2016-02-03 46 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相關的任務將自動在事件分派線程上執行。