2014-01-09 42 views
1

我有以下三類: RNDM:Java的移動JFrames波濤洶涌的運動

import java.util.*; 
public class Rndm { 
    private static Random rn; 
    public static String randInt(int min, int max) 
    { 
     return Integer.toString((min + (int)(Math.random()*(max-min)))); 
    } 
    public static String randInt(int max) 
    { 
     return Integer.toString(((int)(Math.random()*(max)))); 
    } 
    public static int intRandInt(int min, int max) 
    { 
     return (min + (int)(Math.random()*(max-min))); 
    } 
    public static int intRandInt(int max) 
    { 
     return (int)(Math.random()*(max)); 
    } 
    public static String randString(int length) 
    { 
     String randstr=""; 
     for (int i=0; i<=length; i++) 
     { 
      int charset = 1 + (int)(Math.random()*3); 
      if (charset==1) 
      { 
       char randChar = (char) (48 + (int)(Math.random()*(57-48))); 
       randstr += randChar; 
      } 
      else if (charset==2) 
      { 
       char randChar = (char) (65 + (int)(Math.random()*(90-65))); 
       randstr += randChar; 
      } 
      else if (charset==3) 
      { 
       char randChar = (char) (97 + (int)(Math.random()*(122-97))); 
       randstr += randChar; 
      } 
     } 
     return randstr; 
    } 
} 

MovingWindow(移動的JFrame):

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

public class MovingWindow implements Runnable { 
    private JFrame frame; 
    private Point location; 
    private Thread t; 
    private int x; 
    private int y; 
    private int increment = 15; 
    private int delay = 1; 
    public MovingWindow(String tName) { 
     t = new Thread(this, tName); 
     t.start(); 
    } 
    public void run() { 
     drawFrame(); 
    } 
    private void drawFrame() { 
     frame = new JFrame("Moving Window"); 
     x = Rndm.intRandInt(70, 1000); 
     y = Rndm.intRandInt(70, 1000); 
     location = new Point(x, y); 
     frame.setSize(500, 50); 
     frame.setLocation(location); 
     frame.setVisible(true); 
     moveAround(); 
    } 
    public void moveAround() { 
     while(true) { 
      int dir = Rndm.intRandInt(0, 9); 
      switch(dir) { 
       case 1: 
        quad1(); 
        break; 
       case 2: 
        quad2(); 
        break; 
       case 3: 
        quad3(); 
        break; 
       case 4: 
        quad4(); 
        break; 
       case 5: 
        quad5(); 
        break; 
       case 6: 
        quad6(); 
        break; 
       case 7: 
        quad7(); 
        break; 
       case 8: 
        quad8(); 
        break; 
       default: 
      } 
     } 
    } 
    public void quad1() { 
     while (x<1000 && y<1000) { 
      try { Thread.sleep(delay); } catch (java.lang.InterruptedException e) {} 
      setX(x+increment); 
      setY(y+increment); 
     } 
    } 
    public void quad2() { 
     while (x<1000 && y>0) { 
      try { Thread.sleep(delay); } catch (java.lang.InterruptedException e) {} 
      setX(x+increment); 
      setY(y-increment); 
     } 
    } 
    public void quad3() { 
     while (x>0 && y>0) { 
      try { Thread.sleep(delay); } catch (java.lang.InterruptedException e) {} 
      setX(x-increment); 
      setY(y-increment); 
     } 
    } 
    public void quad4() { 
     while (x>0 && y<1000) { 
      try { Thread.sleep(delay); } catch (java.lang.InterruptedException e) {} 
      setX(x-increment); 
      setY(y+increment); 
     } 
    } 
    public void quad5() { 
     while (x>0) { 
      setX(x-increment); 
     } 
    } 
    public void quad6() { 
     while (x<1000) { 
      setX(x+increment); 
     } 
    } 
    public void quad7() { 
     while (y>0) { 
      setY(y-increment); 
     } 
    } 
    public void quad8() { 
     while (y<1000) { 
      setY(y+increment); 
     } 
    } 
    public void setX(int x) { 
     this.x = x; 
     location = new Point(x, y); 
     frame.setLocation(location); 
    } 
    public void setY(int y) { 
     this.y = y; 
     location = new Point(x, y); 
     frame.setLocation(location); 
    } 
} 

和窗口管理器(實例MovingWindow對象):

import java.util.ArrayList; 
public class WindowManager { 
    public static void main(String[] args) { 
     ArrayList<MovingWindow> windows = new ArrayList<MovingWindow>(); 
     for (int i=0; i<Integer.parseInt(args[0]); i++) { 
      windows.add(new MovingWindow(Rndm.randString(10))); 
     } 
    } 
} 

該程序的行爲與預期一致,直到創建多個幀。此時,除一幀或兩幀之外,所有幀都會顯着減速一會兒,恢復正常移動幾秒鐘,然後再次緩慢移動。我有兩個部分的問題: 1:爲什麼會發生這種情況? 2:我該如何解決它? 我在OSX Mavericks上運行java 7。 在此先感謝

+0

我知道,因爲我編寫程序的方式,我的運動永遠不會無縫,但爲什麼不是所有的JFrames都以相同的方式運行? – 735Tesla

+1

而不是每幀有一個單獨的線程,維護一個負責所有幀的移動的單線程...(並且是的,一個Swing'Timer'是最好的) – MadProgrammer

+0

因此,讓'WindowManager'成爲一個靜態類,刪除來自'MovingWindow'的線程代碼,將Thread.sleep()改爲使用'Timer',在'WindowManager'中實現多線程,並用main方法實例化'WindowManager'類。 – 735Tesla

回答

3

您從主線程調用moveAround(),並且從那裏更改GUI。這是一個很大的禁忌。對GUI的所有更改都必須位於事件分派線程或EDT上。

但是,您永遠不應該在EDT上調用Thread.sleep(),因此您當前的方法將無法工作。

我會考慮使用Swing Timer代替。

+0

]我認爲每個新的MovingWindow的run()方法都將在新線程中運行。這是不正確的? – 735Tesla

+1

當然,這就是問題所在。您不應該從非EDT線程更改GUI,否則會出現像您現在遇到的錯誤那樣的奇怪錯誤。 –

+1

@ 735Tesla是的,這是正確的,但Swing不是線程安全的,您不應該從Event Dispatching Thread外部修改任何Swing組件的狀態,請參見[Swing中的併發](http://docs.oracle.com/ javase/tutorial/uiswing/concurrency /)瞭解更多詳情。你還應該看看減少更新線程的數量...... – MadProgrammer

相關問題