2014-01-11 96 views
0

所以我的問題是,有時當我按下我的JFrame中的JButtons,整個框架凍結,只能通過終止它通過Eclipse退出。所有的JButton都有動作監聽器,我不明白爲什麼他們有時會導致JFrame凍結,而在其他時候則不會如何防止我的JFrame凍結?

任何幫助表示讚賞。 這裏是我的代碼:

//objects 
static JFrame frame = new JFrame("Flash cards revision"); 
static JButton beginButton = new JButton(); 
static JButton continueButton = new JButton("CONTINUE"); 
static JButton def1Button; 
static JButton def2Button; 
static JButton def3Button; 
static JLabel keywordLabel = new JLabel(); 
static JLabel title = new JLabel("BIOLOGY FLASH CARDS"); 
static JLabel completionCount = new JLabel("Number of keywords completed - 0/15"); 
static JLabel message = new JLabel(); 

//variables 
static Color backgroundColor = new Color(255, 204, 0); 
static Color labelColor = new Color(44, 103, 0); 
static Color buttonColor = new Color(146, 205, 0); 
static Color highlightedButtonColor = new Color(255, 105, 0); 
static Font textFont = new Font("Myriad Pro", Font.PLAIN, 15); 
static Border border = BorderFactory.createLineBorder(Color.BLACK); 
static String[] keywordsArray = new String[15]; 
static String[] definitionsArray = new String[15]; 
static boolean[] beenUsed = new boolean[15]; 
static int rDefNum; 
static int rButtonNum; 
static int rWDefNum; 
static int numTimesCorrect = 0; 
static int numComplete = 0; 
static int originalY = 0; 
static String keyword; 
static String definition; 
static String wDef1; 
static String wDef2; 

public static void main(String[] args) throws IOException 
{ 
    prepareFrame(); 
    occupyKeywordsArray(); 
    occupyDefinitionsArray(); 
    prepareMenu(); 

    beginButton.addActionListener(new ActionListener() 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      beginButton.removeActionListener(beginButton.getActionListeners()[0]); 
      prepareTest(); 
      getNewKeyword(); 
      getWrongDefinitions(); 
      prepareNewDefinition(); 
      addActionListeners(); 
     } 
    }); 
} 
static void prepareFrame() 
{ 
    frame.setVisible(true); 
    frame.setResizable(false); 
    frame.setLayout(null); 
    frame.setSize(800,600); 
    frame.setLocation(500,200); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().setBackground(backgroundColor); 
    frame.setIconImage(Toolkit.getDefaultToolkit().getImage("biologyIcon.png")); 

} 
static void prepareMenu() 
{ 
    beginButton = new JButton("BEGIN TEST"); 
    frame.add(title); 
    frame.add(beginButton); 

    title.setOpaque(true); 
    title.setSize(650,100); 
    title.setLocation(75,60); 
    title.setHorizontalAlignment(SwingConstants.CENTER); 
    title.setBackground(labelColor); 
    title.setForeground(buttonColor); 
    title.setFont(textFont); 
    title.setFont(title.getFont().deriveFont(60.0f)); 
    title.setBorder(border); 

    beginButton.setBackground(buttonColor); 
    beginButton.setLocation(240,220); 
    beginButton.setForeground(labelColor); 
    beginButton.setFont(textFont); 
    beginButton.setFont(beginButton.getFont().deriveFont(55.0f)); 
    beginButton.setSize(320,100); 
    beginButton.setFocusable(false); 
    beginButton.setBorder(border); 
} 
static void prepareTest() 
{ 
    def1Button = new JButton(); 
    def2Button = new JButton(); 
    def3Button = new JButton(); 
    continueButton = new JButton("CONTINUE"); 

    frame.remove(title); 
    frame.remove(beginButton); 
    frame.add(keywordLabel); 
    frame.add(message); 
    frame.add(completionCount); 
    frame.add(def1Button); 
    frame.add(def2Button); 
    frame.add(def3Button); 
    frame.add(continueButton); 

    frame.repaint(); 
    frame.revalidate(); 

    keywordLabel.setOpaque(true); 
    keywordLabel.setHorizontalAlignment(SwingConstants.CENTER); 
    keywordLabel.setBackground(labelColor); 
    keywordLabel.setForeground(buttonColor); 
    keywordLabel.setFont(textFont); 
    keywordLabel.setFont(keywordLabel.getFont().deriveFont(60.0f)); 
    keywordLabel.setBorder(border); 

    message.setOpaque(true); 
    message.setText("Try to match the keyword to the correct definition"); 
    message.setSize(450,35); 
    message.setLocation(175,370); 
    message.setHorizontalAlignment(SwingConstants.CENTER); 
    message.setBackground(labelColor); 
    message.setForeground(buttonColor); 
    message.setFont(textFont); 
    message.setFont(keywordLabel.getFont().deriveFont(20.0f)); 
    message.setBorder(border); 

    completionCount.setOpaque(true); 
    completionCount.setSize(340,35); 
    completionCount.setLocation(230,20); 
    completionCount.setHorizontalAlignment(SwingConstants.CENTER); 
    completionCount.setBackground(labelColor); 
    completionCount.setForeground(buttonColor); 
    completionCount.setFont(textFont); 
    completionCount.setFont(keywordLabel.getFont().deriveFont(20.0f)); 
    completionCount.setBorder(border); 

    continueButton.setVisible(false); 
    continueButton.setSize(300,100); 
    continueButton.setLocation(250,370); 
    continueButton.setBackground(buttonColor); 
    continueButton.setForeground(labelColor); 
    continueButton.setFont(textFont); 
    continueButton.setFont(def1Button.getFont().deriveFont(50.0f)); 
    continueButton.setFocusable(false); 
    continueButton.setBorder(border); 

    def1Button.setBackground(buttonColor); 
    def1Button.setForeground(labelColor); 
    def1Button.setFont(textFont); 
    def1Button.setFont(def1Button.getFont().deriveFont(20.0f)); 
    def1Button.setFocusable(false); 
    def1Button.setBorder(border); 

    def2Button.setBackground(buttonColor); 
    def2Button.setForeground(labelColor); 
    def2Button.setFont(textFont); 
    def2Button.setFont(def2Button.getFont().deriveFont(20.0f)); 
    def2Button.setFocusable(false); 
    def2Button.setBorder(border); 

    def3Button.setBackground(buttonColor); 
    def3Button.setForeground(labelColor); 
    def3Button.setFont(textFont); 
    def3Button.setFont(def3Button.getFont().deriveFont(20.0f)); 
    def3Button.setFocusable(false); 
    def3Button.setBorder(border); 
} 
static void prepareNewDefinition() 
{ 
    rButtonNum = r.nextInt(3)+1;//Chooses a random number - 1, 2 or 3 

    switch(rButtonNum) 
    { 
    case 1: 
     def1Button.setText(definition); 
     def2Button.setText(wDef1); 
     def3Button.setText(wDef2); 
     break; 
    case 2: 
     def1Button.setText(wDef1); 
     def2Button.setText(definition); 
     def3Button.setText(wDef2); 
     break; 
    case 3: 
     def1Button.setText(wDef1); 
     def2Button.setText(wDef2); 
     def3Button.setText(definition); 
     break; 
    } 

    int b1Width = def1Button.getFontMetrics(def1Button.getFont()).stringWidth(def1Button.getText()) + 45; 
    int b2Width = def2Button.getFontMetrics(def2Button.getFont()).stringWidth(def2Button.getText()) + 45; 
    int b3Width = def3Button.getFontMetrics(def3Button.getFont()).stringWidth(def3Button.getText()) + 45; 

    keywordLabel.setText(keyword); 
    keywordLabel.setSize(keyword.length()*40,100); 
    keywordLabel.setLocation(400-((keyword.length()*40)/2),80); 

    def1Button.setSize(b1Width,30); 
    def1Button.setLocation(400 - def1Button.getWidth()/2,210); 

    def2Button.setSize(b2Width,30); 
    def2Button.setLocation(400 - def2Button.getWidth()/2,260); 

    def3Button.setSize(b3Width,30); 
    def3Button.setLocation(400- def3Button.getWidth()/2,310); 

    optionsListener = new ActionListener() 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      def1Button.removeActionListener(optionsListener); 
      def2Button.removeActionListener(optionsListener); 
      def3Button.removeActionListener(optionsListener); 
      if(e.getActionCommand().equals(definition)) 
      { 
       correct(); 
      } 
      else 
      { 
       incorrect(); 
      } 
     } 
    }; 
} 
static void correct() 
{ 
    numTimesCorrect++; 
    if(numTimesCorrect == 1) 
    { 
     message.setText("Correct! Match this correctly once more to complete this keyword"); 
     message.setSize(550,35); 
     message.setLocation(125,message.getY()); 
    } 
    else 
    { 
     numComplete++; 
     completionCount.setText("Number of keywords completed - "+numComplete+"/15"); 
     message.setText("Correct! Keyword complete!"); 
     message.setSize(250,35); 
     message.setLocation(275,message.getY()); 
    } 
    moveMessageDown(); 
    continueButton.addActionListener(new ActionListener() 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      System.out.println(continueButton.getActionListeners()[0]); 
      continueButton.setVisible(false); 
      continueButton.removeActionListener(continueButton.getActionListeners()[0]); 
      if(numTimesCorrect == 1) 
      { 
       message.setSize(510,35); 
       message.setLocation(145,message.getY()); 
       message.setText("Match this correctly once more to complete this keyword"); 
      } 
      if(numTimesCorrect == 2) 
      { 
       message.setSize(450,35); 
       message.setLocation(175,message.getY()); 
       message.setText("Try to match the keyword to the correct definition"); 
       getNewKeyword(); 
       numTimesCorrect = 0; 
      } 
      getWrongDefinitions(); 
      prepareNewDefinition(); 
      addActionListeners(); 
      moveMessageUp(); 
     } 
    }); 
} 
static void incorrect() 
{ 
    numTimesCorrect = 0; 
    message.setText("Incorrect! The correct definition is now highlighted"); 
    message.setForeground(highlightedButtonColor); 

    if(def1Button.getText().equals(definition)) 
    { 
     def1Button.setBackground(highlightedButtonColor); 
    } 
    if(def2Button.getText().equals(definition)) 
    { 
     def2Button.setBackground(highlightedButtonColor); 
    } 
    if(def3Button.getText().equals(definition)) 
    { 
     def3Button.setBackground(highlightedButtonColor); 
    } 
    message.setSize(450,35); 
    message.setLocation(175,message.getY()); 
    moveMessageDown(); 

    continueButton.addActionListener(new ActionListener() 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      continueButton.setVisible(false); 
      continueButton.removeActionListener(continueButton.getActionListeners()[0]); 
      message.setForeground(buttonColor); 
      getWrongDefinitions(); 
      prepareNewDefinition(); 
      def1Button.setBackground(buttonColor); 
      def2Button.setBackground(buttonColor); 
      def3Button.setBackground(buttonColor); 
      message.setLocation(175,500); 
      message.setText("Try to match the keyword to the correct definition"); 
      addActionListeners(); 
      moveMessageUp(); 
     } 
    }); 
} 
static void getNewKeyword() 
{ 
    boolean validDef = false; 

    while(validDef == false) 
    { 
     rDefNum = r.nextInt(15); 
     if(beenUsed[rDefNum] == false) 
     { 
      validDef = true; 
      beenUsed[rDefNum] = true; 
      keyword = keywordsArray[rDefNum]; 
      definition = definitionsArray[rDefNum]; 
     } 
    } 
} 
static void getWrongDefinitions() 
{ 
    rWDefNum = r.nextInt(15); 
    wDef1 = definitionsArray[rWDefNum]; 
    rWDefNum = r.nextInt(15); 
    wDef2 = definitionsArray[rWDefNum]; 
    while(wDef1.equals(wDef2) || definition.equals(wDef1) || definition.equals(wDef2)) 
    { 
     rWDefNum = r.nextInt(15); 
     wDef1 = definitionsArray[rWDefNum]; 
     wDef2 = definitionsArray[rWDefNum]; 
    } 
} 
static void moveMessageDown() 
{ 
    moveUpThread.stop(); 
    originalY = message.getY(); 
    moveDownThread = new Thread() 
    { 
     public void run() 
     { 
      try 
      { 
       Thread.sleep(200); 
      }catch (InterruptedException e){} 

      for(int loop = 0; loop <= 500-originalY; loop++) 
      { 
       try 
       { 
        Thread.sleep(6); 
       } catch (InterruptedException e){} 

       message.setLocation(message.getX(),originalY+loop); 
      } 
      continueButton.setVisible(true); 
     } 
    }; 
    moveDownThread.start(); 
} 
static void moveMessageUp() 
{ 
    originalY = message.getY(); 
    moveUpThread = new Thread() 
    { 
     public void run() 
     { 

      try 
      { 
       Thread.sleep(200); 
      }catch (InterruptedException e){} 

      for(int loop = 0; loop <= 630 - originalY; loop++) 
      { 
       try 
       { 
        Thread.sleep(6); 
       } catch (InterruptedException e){} 

       message.setLocation(message.getX(),500-loop); 
      } 
     } 
    }; 
    moveUpThread.start(); 
} 
static void addActionListeners() 
{ 
    def1Button.addActionListener(optionsListener); 
    def2Button.addActionListener(optionsListener); 
    def3Button.addActionListener(optionsListener); 
} 
static void occupyKeywordsArray() throws IOException 
{ 
    BufferedReader keywordsReader = new BufferedReader(new FileReader("keywords.txt")); 
    for(int keywordsLoop = 0; keywordsLoop <= 14; keywordsLoop++) 
    { 
     keywordsArray[keywordsLoop] = keywordsReader.readLine(); 
     keywordsReader.readLine(); 
    } 
    keywordsReader.close(); 
} 
static void occupyDefinitionsArray() throws IOException 
{ 
    BufferedReader definitionsReader = new BufferedReader(new FileReader("keywords.txt")); 
    for(int definitionsLoop = 0; definitionsLoop <= 14; definitionsLoop++) 
    { 
     definitionsReader.readLine(); 
     definitionsArray[definitionsLoop] = definitionsReader.readLine(); 
    } 
    definitionsReader.close(); 
} 
} 
+1

不要堵塞EDT(事件指派線程) - 的圖形用戶界面將「凍結」當這種情況發生。而不是調用'Thread.sleep(n)'實現一個Swing'Timer'來重複執行任務,或者一個'SwingWorker'執行長時間運行的任務。有關更多詳細信息,請參見[Swing中的併發](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。順便說一句 - 所有'靜態'的使用都有一個糟糕的代碼味道呢。 –

+0

'frame.setLayout(null);'Java GUI可能需要在多種平臺上工作,使用不同的屏幕分辨率和使用不同的PLAF。因此,它們不利於組件的準確放置。爲了組織強大的圖形用戶界面,請使用佈局管理器或[它們的組合](http://stackoverflow.com/a/5630271/418556)以及[空格]的佈局填充和邊框(http: //stackoverflow.com/q/17874717/418556)。 –

回答

1

你必須創建你聽衆中的一個線程。事情是這樣的:

button.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 

       Thread hilo = new Thread(new Runnable() { 

        @Override 
        public void run() { 

         //here your code 

        } 
       });   
       hilo.start(); 

      } 
     }); 

如果JFrame的不凍結只是因爲執行速度快,它有沒有時間凍結,但如果需要執行比秒鐘JFrame中會凍結。

+0

非常感謝你,我一直在尋找這個非常棒的工作,,,,, –

0

我也一樣@carexcer與invokeLater的電話如下,它爲我工作:

public static void main(String[] args) { 
//  EventQueue.invokeLater(() -> { 
     Toolkit.getDefaultToolkit().setDynamicLayout(false); 
     final JFrame frame = new JFrame(); 
     frame.setUndecorated(true); 
     final JToggleButton backgroundButton = new JToggleButton("Break me!"); 
     backgroundButton.setSelected(true); 
     backgroundButton.addActionListener(e -> { 
      if(!backgroundButton.isSelected()) { 
       EventQueue.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         frame.setBackground(new Color(0, 0, 0, 0)); 
         backgroundButton.setText("Fix me!"); 
        } 
       }); 
      } else { 
       EventQueue.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         frame.setBackground(UIManager.getColor("control")); 
         backgroundButton.setText("Break me!"); 
        } 
       });     
      } 
     }); 
     final JLabel label = new JLabel("Resize Here"); 
     label.setBorder(BorderFactory.createLineBorder(Color.RED)); 
     frame.getContentPane().add(backgroundButton); 
     frame.getContentPane().add(label, BorderLayout.SOUTH); 
     new ComponentResizer(frame); 

     frame.pack(); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
//  }); 
}