[英]Why is my Swing application freezing?
基本上,每次我單擊一個JButton時,它都會鎖定。 我一直在環顧四周,發現可能是由於無限循環所致,但我看不到任何地方。
一雙新鮮的眼睛將非常方便!
無論如何,這是要聲明的JButton:
public static JButton textYes = new JButton("Yes");
public static JButton textNo = new JButton("No");
這是我的main()方法:
public static void main(String[] args) throws IOException {
Greed gui = new Greed();
gui.launchFrame();
redirectSystemStreams();
Container contentPane = f.getContentPane();
contentPane.add(new Greed());
Scanner is = new Scanner(System.in);
System.out.println("Welcome to Greed...");
//do {
System.out.println("Would you like to play? (yes/no)");
area = "menu";
menu = is.next();
}
這是Start()方法:
public static void start(String menu) {
switch (menu) {
case "yes":
jTextArea1.setText(null);
diceOne = 0;
diceTwo = 0;
diceThree = 0;
diceFour = 0;
diceFive = 0;
System.out.println("Rolling...");
Game();
break;
case "no":
System.out.println("Goodbye...");
System.exit(0);
break;
default:
invalidInput();
break;
}
}
這是帶有JButton偵聽器的actionPerformed()方法:
public void actionPerformed(ActionEvent e) {
//jTextArea1.setText(null);
if (box1.isSelected()) {
System.out.println("1 is selected");
willRerollDiceOne = true;
}
else {
//System.out.println("1 not selected");
willRerollDiceOne = false;
}
if (box2.isSelected()) {
System.out.println("2 is selected");
willRerollDiceTwo = true;
}
else {
//System.out.println("2 not selected");
willRerollDiceTwo = false;
}
if (box3.isSelected()) {
System.out.println("3 is selected");
willRerollDiceThree = true;
}
else {
//System.out.println("3 not selected");
willRerollDiceThree = false;
}
if (box4.isSelected()) {
System.out.println("4 is selected");
willRerollDiceFour = true;
}
else {
//System.out.println("4 not selected");
willRerollDiceFour = false;
}
if (box5.isSelected()) {
System.out.println("5 is selected");
willRerollDiceFive = true;
}
else {
//System.out.println("5 not selected");
willRerollDiceFive = false;
}
if ("menu".equals(area)) {
if(e.getSource() == textYes){
start("yes");
}
if(e.getSource() == textNo){
start("no");
}
}
if ("choiceReroll".equals(area)) {
if(e.getSource() == textYes){
choiceReroll = "yes";
}
if(e.getSource() == textNo){
choiceReroll = "no";
}
}
}
我認為它以某種方式連接到JButton。
讓我知道是否需要顯示更多代碼。
無論如何,我們將不勝感激!
感謝您的幫助和時間!
編輯:對不起,我忘了告訴聽眾被附加到JBUttons:
textYes.addActionListener(this);
textNo.addActionListener(this);
編輯:此外,這是Game()方法:
public static void Game() {
rollDiceOne();
rollDiceTwo();
rollDiceThree();
rollDiceFour();
rollDiceFive();
displayDiceValues();
f.validate();
f.repaint();
choiceRerollDice();
}
而rollDice#方法:
public static void rollDiceOne() {
diceOne = 1 + (int)(Math.random()*6);
}
public static void rollDiceTwo() {
diceTwo = 1 + (int)(Math.random()*6);
}
public static void rollDiceThree() {
diceThree = 1 + (int)(Math.random()*6);
}
public static void rollDiceFour() {
diceFour = 1 + (int)(Math.random()*6);
}
public static void rollDiceFive() {
diceFive = 1 + (int)(Math.random()*6);
}
問題是您的ActionListener
無需使用新線程即可執行所有操作。 這意味着您將凍結UI線程,這基本上會阻止UI刷新。
您可以做的是在actionPerformed
方法中使用Thread
。
public void actionPerformed(final ActionEvent e) {
Thread t = new Thread() {
public void run() {
//jTextArea1.setText(null);
if (box1.isSelected()) {
System.out.println("1 is selected");
willRerollDiceOne = true;
}
else {
//System.out.println("1 not selected");
willRerollDiceOne = false;
}
if (box2.isSelected()) {
System.out.println("2 is selected");
willRerollDiceTwo = true;
}
else {
//System.out.println("2 not selected");
willRerollDiceTwo = false;
}
if (box3.isSelected()) {
System.out.println("3 is selected");
willRerollDiceThree = true;
}
else {
//System.out.println("3 not selected");
willRerollDiceThree = false;
}
if (box4.isSelected()) {
System.out.println("4 is selected");
willRerollDiceFour = true;
}
else {
//System.out.println("4 not selected");
willRerollDiceFour = false;
}
if (box5.isSelected()) {
System.out.println("5 is selected");
willRerollDiceFive = true;
}
else {
//System.out.println("5 not selected");
willRerollDiceFive = false;
}
if ("menu".equals(area)) {
if(e.getSource() == textYes){
start("yes");
}
if(e.getSource() == textNo){
start("no");
}
}
if ("choiceReroll".equals(area)) {
if(e.getSource() == textYes){
choiceReroll = "yes";
}
if(e.getSource() == textNo){
choiceReroll = "no";
}
}
}
};
t.start();
}
使用線程將防止UI凍結
更新
正如MadProgrammer所說,在這種情況下,最好使用SwingWorker而不是Thread
我懷疑choiceRerollDice
正在使用掃描儀從用戶讀取輸入,這阻止了事件調度線程,從而阻止了其重新繪制。
您正在將CLI范例與GUI范例混合在一起,這又引發了一個問題,為什么?
使用圖形界面時,不應使用CLI樣式輸入(即Scanner
),而應使用可用的圖形控件,例如按鈕或文本字段。
看起來您從未在按鈕上附加任何偵聽器,而是嘗試從System.in中讀取。 如果是這樣,則程序將掛起,等待來自System.in的輸入。
而不是
Scanner is = new Scanner(System.in);
...
area = "menu";
menu = is.next();
在按鈕上使用actionListeners,
textYes.addActionListener(/*Your Action Listener*/);
...
編輯-即使附加了ActionListener,它也會掛在Scanner行上,嘗試從輸入流中讀取。 刪除這些行應該修復它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.