Draw text using Swing

The main problem is that I want to draw a graph with multiple labels. For drawing, I use the following class:

public class Canvas extends JPanel {

    // Lot of other methods

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        // Other code

        g2.setColor(Style.LIGHT_GREY);
        g2.fillOval(node.getPosition().x, node.getPosition().y, Style.SHAPE_SIZE, Style.SHAPE_SIZE);

        g2.setColor(Style.DARK_GREY);
        g2.setStroke(new BasicStroke(1.5f));
        g2.drawOval(node.getPosition().x, node.getPosition().y, Style.SHAPE_SIZE, Style.SHAPE_SIZE);

        //Draw token
        g2.setColor(Style.DARK_GREY);
        g2.setFont(new Font("Monospaced", Font.PLAIN, 12));
        String token = ((Place)node).getTokens().toString();
        g2.drawString(token, 
                (int) (node.getNodeCenterPosition().x - 3.5*token.length()), node.getNodeCenterPosition().y + CHAR_HEIGHT);

        //Draw label
        g2.drawString("P1", node.getPosition().x-8, node.getPosition().y-8);

        // More code
    }

}

Do not pay attention to the coordinates, they are all set and correct. Strange behavior starts with the last drawString here:

//Draw label
g2.drawString("P1", node.getPosition().x-8, node.getPosition().y-8);

All previous code is displayed once when called paintComponent, but this one. Although if I call again paintComponent(from outside, calling canvas.repaint()), it will appear.

Here is the state of the canvas after the first redraw:

No label

And here is the state of the canvas after the second repainting:

With label

Note: if I put a label on the right side of the disk, it will usually appear on the first redraw:

g2.drawString("P1", node.getPosition().x+50, node.getPosition().y+30);

Label on the right side

. , , , .

, , ?

EDIT. , :

public class MainWindow extends JFrame {

    private MainWindow() {
        super();

        setVisible(true);
        setResizable(false);
        setSize(1280, 750);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        this.setJMenuBar(MainMenu.getInstance());       
        add(Canvas.getInstance(), BorderLayout.CENTER);     
        add(ToolBar.getInstance(), BorderLayout.PAGE_START);        
        add(LeftPanel.getInstance(), BorderLayout.LINE_START);
    }

}

Canvas:

private Canvas() {
    super();
    this.setFocusable(true);
    this.setBackground(Style.BACKGROUND);

    this.popupNewNode = new JPopupMenu();
    this.popupNewNode.setFocusable(false);

    this.newPlace = new JMenuItem("New Place");
    this.newTransition = new JMenuItem("New Transition");

    this.popupNewNode.add(newPlace);
    this.popupNewNode.add(newTransition);
}

, , , .

+4
1

, FontMetrics

FontMetrics fm = g.getFontMetrics();
int width = fm.stringWidth("P1");
int height = fm.getHeight();
g.drawString("P1", node.getPosition().x - width, (node.getPosition().y - height) + fm.getAscent());

. API.

, Graphics,

0

Source: https://habr.com/ru/post/1585088/


All Articles