2016-02-03 45 views
-2

我有两个类用于绘制JFrame(见下文)。更新JFrame

我试图刷新内容,因此它给出随机“移动”点的印象。 (即:足够快的重新绘制)

理想情况下,我想通过一些参数来指定点应出现在哪个坐标。但是,我得到的只是一张静态图片。

有什么建议吗?

package uk.me.dariosdesk.dirtydemo; 

import javax.swing.*; 
import java.awt.*; 
import java.util.Random; 

class DrawPanel extends JPanel { 
    private void doDrawing(Graphics g) { 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setColor(Color.blue); 

     for (int i = 0; i <= 1000; i++) { 
      Dimension size = getSize(); 
      Insets insets = getInsets(); 

      int w = size.width - insets.left - insets.right; 
      int h = size.height - insets.top - insets.bottom; 

      Random r = new Random(); 
      int x = Math.abs(r.nextInt()) % w; 
      int y = Math.abs(r.nextInt()) % h; 
      g2d.drawLine(x, y, x, y); 
     } 
     g2d.fillRect(200, 250, 200, 250); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     doDrawing(g); 
    } 
} 

而且

package uk.me.dariosdesk.dirtydemo; 

import javax.swing.*; 

public class PointsExample extends JFrame { 
    public PointsExample() { 
     initUI(); 
    } 

    public final void initUI() { 
     DrawPanel dpnl = new DrawPanel(); 
     add(dpnl); 
     setSize(500, 500); 
     setTitle("Points"); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       PointsExample ex = new PointsExample(); 
       ex.setVisible(true); 
       for(int i = 0; i < 10; i++) { 
        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
        ex.repaint(); 
       } 
      } 
     }); 
    } 
} 
+1

您是否在IDE调试器中运行此代码并遍历代码以查看发生了什么?那是开始的地方。 StackOverflow中关于类型的问题“这里是我所有的代码,告诉我什么是错误的”。 –

+1

用Swing'Timer'替换'PointsExample' for-loop,因为我认为'Thread.sleep()'阻塞了你的整个应用程序。实际上,我也将计时器放置在'DrawPanel'类中,并对所有的计算进行下一个点的计算,否则如果例如调整帧大小(即每次帧重绘),点也将移动。 –

+0

您正在调用'getSize()','getInsets()'和'new Random()'1000次。为什么? – user1803551

回答

3

“我得到的是一个静态图像”是对细节很轻。但我认为LuxxMiner是正确的,您的Event Dispatch Thread上的Thread.Sleep是一个坏主意。更重要的是,Runnable从不退出1000秒。所以你阻止了EDT 1000秒。

什么重绘Component.repaint做(重点煤矿):

如果此组件是轻量级组件,这种方法尽快导致这个组件的paint方法的调用。否则,此方法会尽快致电此组件的更新方法

这已经表明此方法将邮件发送到调度线程,该线程使用Thread.Sleep进行阻止。你可以做的反而是使用Swing Timer,要求重新绘制每一秒:

一般情况下,我们推荐使用Swing的计时器,而不是通用定时器用于GUI相关的任务,因为摇摆定时器都有着相同的,预先存在的计时器线程和与GUI相关的任务将自动在事件分派线程上执行。