java - 使用 Swing 绘制文本

标签 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 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
    }

}

别介意坐标,它们都是正确的。奇怪的行为从这里的最后一个 drawString 开始:

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

一旦 paintComponent 被调用,之前的所有代码都会被渲染,但是这一个。尽管如果我再次触发 paintComponent(从外部调用 canvas.repaint())它会显示出来。

这是第一次重绘后 Canvas 的状态:

No label

这是第二次重绘后 Canvas 的状态:

With label

补充说明:如果我把标签放在光盘的右侧,第一次重绘时它会正常渲染:

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

Label on the right side

代码的位置对行为没有影响。如果我注释掉除标签之外的所有代码,或者我将标签绘图放在函数的顶部,这没有任何区别。

那么,我怎样才能让这个标签在我第一次调用重绘时呈现?

编辑:这是呈现窗口的代码:

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

Canvas 和其他一些组件是单例的,但我想这应该不是问题,因为只有一个窗口存在,上面有一个 Canvas 。

最佳答案

没有完全可运行的示例很难知道,但是,您不应该对文本的大小做出假设,而应该使用 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());

仔细看看Working with Text APIs了解更多详情。

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

关于java - 使用 Swing 绘制文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29916284/

相关文章:

java - 如何将字节数组从 Android 设备发送到 servlet

java - GridLayout 以及行数和列数

java - 在 JFrame 和 JPanel 之间添加空间

java - JFrame后台错误: Unwanted Transparency

java - 如何查看 Graphics2D 中的某些内容是否超出框架

java - 我如何更改代码,以便垃圾收集器将由于程序而删除此实例?

java - 在计算器应用程序上 toast 时出错

java - Graphics2D 在定义的四边形内部绘制图像

java - actionPerformed 时出现 NullPointerException。不知道为什么

java - 为什么我的标签和按钮没有显示在 JFrame 中?