主要问题是我想用几个标签绘制一个图表。我使用以下类进行绘制:
一旦调用
下面是第一次重绘后画布的状态: 下面是第二次重绘后画布的状态: 附加说明: 如果我把标签放在圆盘的右边,它在第一次重绘时就正常渲染出来了。
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()
),它就会显示出来。下面是第一次重绘后画布的状态: 下面是第二次重绘后画布的状态: 附加说明: 如果我把标签放在圆盘的右边,它在第一次重绘时就正常渲染出来了。
g2.drawString("P1", node.getPosition().x+50, node.getPosition().y+30);
代码的位置不会影响行为。如果我注释掉除标签外的所有代码,或者将标签的绘制放在函数的顶部,都不会产生任何影响。
那么,我该如何使这个标签在第一次调用repaint时呈现出来?
编辑:以下是渲染窗口的代码:
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);
}
< p > 画布和其他一些组件是单例的,但我想这不应该成为问题,因为只有一个窗口存在,且上面只有一个画布。 < /p >
Canvas
放置在父容器上。 - alex2410FontMetrics
来确定文本的长度和高度。 - MadProgrammer