【问题标题】:Why do statements get executed more than once in paint or paintComponent methods?为什么在paint或paintComponent方法中语句会多次执行?
【发布时间】:2013-05-30 03:53:48
【问题描述】:

我正在尝试根据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()。但是我仍然有同样的问题。 请帮我解决它。

【问题讨论】:

    标签: java swing awt paint paintcomponent


    【解决方案1】:

    你是正确的覆盖paintComponent 而不是paint。我认为这里的问题是paintComponent 应该做一件事,绘制你的组件。任何数量的事情都可能导致调用 repaint() 来调用您的paintComponent,因此不能真正保证该方法何时以及多久执行一次。进行计算和跟踪变量可能应该是单独模型类的一部分,您的组件可以查看该模型类以了解要绘制的内容。

    【讨论】:

    • 感谢您的回复,但我需要它根据某些变量的值和计算来绘制形状。此外,我需要根据形状位置调用其他方法来做其他工作人员。如果适用,也许一个可能的解决方案是用不同的方法进行计算,但在这个新方法中,我调用 paintComponent 方法来进行绘画。这可能吗?
    • 你不应该直接调用paintComponent()。如果您更改了导致绘画更改的类的属性,则调用 repaint(),然后 Swing 将确定何时重新绘制组件。
    【解决方案2】:

    这个问题可能已经被遗忘了,但我偶然发现了它,并想帮助其他也这样做的人。我找到的解决方案是使用 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.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-07
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      • 2010-12-13
      • 1970-01-01
      • 1970-01-01
      • 2011-07-22
      相关资源
      最近更新 更多