Java 使用Swing绘制文本

Java 使用Swing绘制文本,java,swing,jframe,jpanel,sizing,Java,Swing,Jframe,Jpanel,Sizing,主要的问题是我想画一个带有几个标签的图。对于绘图,我使用以下类别: public class Canvas extends JPanel { // Lot of other methods @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; // Other

主要的问题是我想画一个带有几个标签的图。对于绘图,我使用以下类别:

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
    }

}
不管坐标是什么,它们都已设置并正确无误。奇怪的行为从这里的最后一根绳子开始:

//Draw label
g2.drawString("P1", node.getPosition().x-8, node.getPosition().y-8);
调用
paintComponent
后,将渲染前面的所有代码,但此代码除外。虽然如果我再次触发
paintComponent
(从外部调用
canvas.repaint()
),它会显示出来

以下是第一次重新绘制后画布的状态:

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

下面是第二次重新绘制后画布的状态:

附加说明:如果我将标签放在光盘的右侧,则在第一次重新绘制时会正常渲染:

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

代码的位置对行为没有影响。如果我注释掉了所有的代码,但没有注释标签,或者我将标签图形放在函数的顶部,这没有什么区别

那么,如何在第一次调用“重新绘制”时渲染此标签

编辑:以下是呈现窗口的代码:

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);
    }

}
画布的构造函数中的代码:

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);
}

画布和一些其他组件是单例的,但我认为这不应该是一个问题,因为只有一个窗口上有一个画布。

如果没有一个完全可运行的示例,就很难知道,但是,您不应该假设文本的大小,而应该使用
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());
请仔细查看以了解更多详细信息


另一个问题可能是,如果您以前翻译过
图形
上下文,而没有先复制它或反转翻译

显示您如何将
画布
放置在父容器上。使用
FontMetrics
确定文本的长度和高度您是否有什么东西可以使?设置可见(true); 必须是最后一行代码==您的主要问题要更快地获得更好的帮助,请发布(最小完整可验证示例)或(简短、自包含、正确的示例)。