所以我的問題是,有時當我按下我的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();
}
}
不要堵塞EDT(事件指派線程) - 的圖形用戶界面將「凍結」當這種情況發生。而不是調用'Thread.sleep(n)'實現一個Swing'Timer'來重複執行任務,或者一個'SwingWorker'執行長時間運行的任務。有關更多詳細信息,請參見[Swing中的併發](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。順便說一句 - 所有'靜態'的使用都有一個糟糕的代碼味道呢。 –
'frame.setLayout(null);'Java GUI可能需要在多種平臺上工作,使用不同的屏幕分辨率和使用不同的PLAF。因此,它們不利於組件的準確放置。爲了組織強大的圖形用戶界面,請使用佈局管理器或[它們的組合](http://stackoverflow.com/a/5630271/418556)以及[空格]的佈局填充和邊框(http: //stackoverflow.com/q/17874717/418556)。 –