2013-08-18 67 views
0

我對Java很新,我剛開始編寫這個愚蠢的小程序作爲GUI測試。它應該做的是有12個按鈕,將它們全部設置爲白色,連續將3個隨機按鈕設置爲黑色,將所有按鈕再次設置爲白色,等待一秒鐘然後重複。問題是,我似乎無法重複它。每當我嘗試在隨機按鈕變黑的代碼段放一段時間或循環時,它都不會運行。它不會給出任何錯誤,並且該進程本身也會運行,但不會出現窗口。這是類的代碼(減去進口語句):GUI中的循環問題(java)

public class testingness extends JFrame { 

JButton one, two, three, four, five, six, seven, eight, nine, ten, eleven, 
     twelve; 
JPanel panel; 

testingness(String title) { 

    super(title); 
    this.init(); 
    this.setSize(800, 800); 
    this.setLocationRelativeTo(null); 
    this.setVisible(true); 
} 

void init() { 
    panel = new JPanel(); 
    panel.setLayout(new GridLayout(3, 4)); 
    one = new JButton(); 
    one.setBackground(Color.white); 
    two = new JButton(); 
    two.setBackground(Color.white); 
    three = new JButton(); 
    three.setBackground(Color.white); 
    four = new JButton(); 
    four.setBackground(Color.white); 
    five = new JButton(); 
    five.setBackground(Color.white); 
    six = new JButton(); 
    six.setBackground(Color.white); 
    seven = new JButton(); 
    seven.setBackground(Color.white); 
    eight = new JButton(); 
    eight.setBackground(Color.white); 
    nine = new JButton(); 
    nine.setBackground(Color.white); 
    ten = new JButton(); 
    ten.setBackground(Color.white); 
    eleven = new JButton(); 
    eleven.setBackground(Color.white); 
    twelve = new JButton(); 
    twelve.setBackground(Color.white); 

    panel.add(one); 
    panel.add(two); 
    panel.add(three); 
    panel.add(four); 
    panel.add(five); 
    panel.add(six); 
    panel.add(seven); 
    panel.add(eight); 
    panel.add(nine); 
    panel.add(ten); 
    panel.add(eleven); 
    panel.add(twelve); 

    this.add(panel); 
    while (true) { 
     randomness(); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

public void randomness() { 

    for (int timesdone = 0; timesdone < 4; timesdone++) { 
     panel.update(panel.getGraphics()); 
     Random r = new Random(); 
     int rand = r.nextInt(12); 

     if (rand == 0) { 
      one.setBackground(Color.black); 
     } else if (rand == 1) { 
      two.setBackground(Color.black); 
     } else if (rand == 2) { 
      three.setBackground(Color.black); 
     } else if (rand == 3) { 
      four.setBackground(Color.black); 
     } else if (rand == 4) { 
      five.setBackground(Color.black); 
     } else if (rand == 5) { 
      six.setBackground(Color.black); 
     } else if (rand == 6) { 
      seven.setBackground(Color.black); 
     } else if (rand == 7) { 
      eight.setBackground(Color.black); 
     } else if (rand == 8) { 
      nine.setBackground(Color.black); 
     } else if (rand == 9) { 
      ten.setBackground(Color.black); 
     } else if (rand == 10) { 
      eleven.setBackground(Color.black); 
     } else if (rand == 11) { 
      twelve.setBackground(Color.black); 
     } 
     one.setBackground(Color.white); 
     two.setBackground(Color.white); 
     three.setBackground(Color.white); 
     four.setBackground(Color.white); 
     five.setBackground(Color.white); 
     six.setBackground(Color.white); 
     seven.setBackground(Color.white); 
     eight.setBackground(Color.white); 
     nine.setBackground(Color.white); 
     ten.setBackground(Color.white); 
     eleven.setBackground(Color.white); 
     twelve.setBackground(Color.white); 

    } 
    } 

} 

我在做什麼錯在這裏?

+0

把一些斷點和監控你的行爲節目。它是否嘗試呼叫,正在呼叫您的所有setbackground呼叫,也許它只是不刷新顯示。我會首先確認邏輯。 – mwjohnson

+0

試着看看[這個例子](http://stackoverflow.com/questions/18266087/change-jlabel-background-on-mouserelease-event/18293834#18293834) – MadProgrammer

+0

你永遠不應該調用'update'或'paint '這個'panel.update(panel.getGraphics());'是非常糟糕的 – MadProgrammer

回答

2

由於GERMANN阿靈頓指出,在GUI線程永遠不會被允許運行,因爲你的構造函數永遠不會返回。但是,在GUI線程(您需要更改GUI組件的屬性)上定期執行某些操作的更好方法是使用定時器(http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html)。例如:

int delay = 1000; //milliseconds 
ActionListener taskPerformer = new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
     randomness(); 
    } 
}; 
new Timer(delay, taskPerformer).start(); 
+1

雖然這是一個更好的答案,但OP仍然會遇到'randomness'方法的問題... – MadProgrammer

2

在randomness()函數結束時,您將所有按鈕設置爲白色。你應該把所有的if-elses,而不是之後。

0

主要的問題是,你的代碼運行,但因爲它是永無止境的循環,你永遠不會得到畫的組成部分 - 試圖喚起重繪()方法中的循環內您的方法結束。

另外一點:如果你有多個按鈕,你會好起來的(編程),只將它們添加到容器中,並遍歷這個容器的內容。

4

Swing是一個單線程環境。要求在事件分派線程的上下文中執行對UI的所有交互和修改。

的EDT負責,除其他外,過程重新繪製請求和傳入事件

的任何行動或操作,這些操作阻斷EDT會阻止它處理這些事件和更新屏幕。

在你的代碼正在做這個...

while (true) { 
    randomness(); 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

這可能是阻止EDT,防止它從不斷更新屏幕。

同樣,你也正在做這...

for (int timesdone = 0; timesdone < 4; timesdone++) { 
    /*...*/ 
} 

這將一視同仁,阻止EDT,防止它從不斷更新屏幕...

此外,這panel.update(panel.getGraphics());是一個非常餿主意。在Swing中,您不控制塗料工藝,這取決於RepaintManager。您可以提出更新/重新繪製的請求,但是要決定什麼時間以及什麼時候決定什麼時候取決於RepaintManager。這些請求然後發佈到美國東部時間......如果被阻止,什麼都不會做。

getGraphics也可以返回null,這是從來沒有很...

解決你的問題,你需要關閉加載「等待」時間的某種後臺進程,這在準備好時,需要告訴UI改變它的相應狀態......

你可以使用一個Thread,但這意味着你要負責重新同步所有的電話回到EDT,這是凌亂的,並提供了頭頂小增益。

你可以使用一個SwingWorker,但它不是真的適合你手頭的任務

一個更好的解決辦法是使用javax.swing.Timer,這將在指定的延遲後,多次觸發actionPerformed事件,如在EDT的背景下執行。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Random; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Flashy01 { 

    public static void main(String[] args) { 
     new Flashy01(); 
    } 

    public Flashy01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new FlashPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class FlashPane extends JPanel { 

     private final BigButton one, two, three, four, five, six, seven, eight, nine, ten, eleven, 
       twelve; 
     private final JPanel panel; 
     private final Random random; 
     private int timesDone; 

     public FlashPane() { 
      panel = new JPanel(); 
      panel.setLayout(new GridLayout(3, 4)); 
      one = new BigButton(); 
      one.setBackground(Color.white); 
      two = new BigButton(); 
      two.setBackground(Color.white); 
      three = new BigButton(); 
      three.setBackground(Color.white); 
      four = new BigButton(); 
      four.setBackground(Color.white); 
      five = new BigButton(); 
      five.setBackground(Color.white); 
      six = new BigButton(); 
      six.setBackground(Color.white); 
      seven = new BigButton(); 
      seven.setBackground(Color.white); 
      eight = new BigButton(); 
      eight.setBackground(Color.white); 
      nine = new BigButton(); 
      nine.setBackground(Color.white); 
      ten = new BigButton(); 
      ten.setBackground(Color.white); 
      eleven = new BigButton(); 
      eleven.setBackground(Color.white); 
      twelve = new BigButton(); 
      twelve.setBackground(Color.white); 

      panel.add(one); 
      panel.add(two); 
      panel.add(three); 
      panel.add(four); 
      panel.add(five); 
      panel.add(six); 
      panel.add(seven); 
      panel.add(eight); 
      panel.add(nine); 
      panel.add(ten); 
      panel.add(eleven); 
      panel.add(twelve); 

      this.add(panel); 
      random = new Random(); 

      Timer timer = new Timer(1000, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        randomness(); 
       } 
      }); 
      timer.start(); 
     } 

     public void randomness() { 

      int rand = random.nextInt(12); 
      timesDone++; 

      if (timesDone % 5 != 0) { 

       if (rand == 0) { 
        one.setBackground(Color.black); 
       } else if (rand == 1) { 
        two.setBackground(Color.black); 
       } else if (rand == 2) { 
        three.setBackground(Color.black); 
       } else if (rand == 3) { 
        four.setBackground(Color.black); 
       } else if (rand == 4) { 
        five.setBackground(Color.black); 
       } else if (rand == 5) { 
        six.setBackground(Color.black); 
       } else if (rand == 6) { 
        seven.setBackground(Color.black); 
       } else if (rand == 7) { 
        eight.setBackground(Color.black); 
       } else if (rand == 8) { 
        nine.setBackground(Color.black); 
       } else if (rand == 9) { 
        ten.setBackground(Color.black); 
       } else if (rand == 10) { 
        eleven.setBackground(Color.black); 
       } else if (rand == 11) { 
        twelve.setBackground(Color.black); 
       } 

      } else { 

       one.setBackground(Color.white); 
       two.setBackground(Color.white); 
       three.setBackground(Color.white); 
       four.setBackground(Color.white); 
       five.setBackground(Color.white); 
       six.setBackground(Color.white); 
       seven.setBackground(Color.white); 
       eight.setBackground(Color.white); 
       nine.setBackground(Color.white); 
       ten.setBackground(Color.white); 
       eleven.setBackground(Color.white); 
       twelve.setBackground(Color.white); 
      } 
     } 
    } 

    public class BigButton extends JButton { 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(20, 20); 
     } 

    } 
} 

看一看......

有關詳細信息...

+0

哇,我沒有不知道這一切關於鞦韆。感謝分享,我一定會研究你提到的那些話題。 – EyedJellyfish