我试图根据paint()
或paintComponent()
方法中的一些计算绘制和绘制一些几何形状。但是,我意识到paint()
或paintComponent()
中的打印和其他计算语句执行2次或有时3次。例如,以下代码中的print语句执行两次,并在控制台中打印两次“help”一词:
public class Skeleton extends JPanel {
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.drawOval(50, 50, 100, 100);
System.out.println("help");
}
然后在控制台中打印的部分是这样的:
help
help
这是我的main()
方法
public static void main(String[] args) {
JFrame frame = new JFrame("Java 2D Skeleton");
frame.add(new Skeleton());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(870, 890);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
更糟糕的是,如果我有一个类公共变量,并且我在paint()
方法中将其值增加1。这导致值增加2。
我在本网站的某个地方读过这样的方法paint()
会自动调用其他三种方法,我认为这些方法导致了这个问题。
另外,我在其他网站上尝试了一些建议的解决方案来覆盖方法paintComponent()
而不是方法paint()
。但是我仍然有同样的问题。
请帮我解决。
答案 0 :(得分:2)
您可以覆盖paintComponent而不是paint。我认为这里的问题是paintComponent应该做一件事,画你的组件。任何数量的事情都可能导致调用repaint(),这将调用您的paintComponent,因此它不能确保此方法执行的时间和频率。进行计算和跟踪变量应该是组件可以查看的单独模型类的一部分,以了解要绘制的内容。
答案 1 :(得分:0)
这个问题可能已被遗忘,但我偶然发现了它,并希望帮助其他人。我发现的解决方案是使用JApplet的init()方法。在那里,您可以进行所需的所有计算。然后,如果需要,还可以创建一个计时器,该计时器以指定的时间间隔响应以调用repaint()并执行迭代工作。这样,您可以将除实际绘图代码之外的所有内容都留在绘画之外。它看起来像这样:
public void init()
{
//do calculations here
javax.swing.Timer timer = new javax.swing.Timer(1000 / frameRate, new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
//this is called every so often. Can link to update loops or be an
//update loop itself.
repaint();
}
} );
timer.start();
}
public void paint(Graphics g)
{
//All the actual drawing code for the shapes goes here.
}