Java 为什么我的Swing应用程序冻结了?

Java 为什么我的Swing应用程序冻结了?,java,swing,user-interface,jbutton,infinite-loop,Java,Swing,User Interface,Jbutton,Infinite Loop,基本上,每次我点击我的一个按钮,它就会锁定。我环顾四周,发现这可能是因为一个无限循环,但我在任何地方都看不到 一双新鲜的眼睛会很有用的 无论如何,下面是要声明的JButtons: public static JButton textYes = new JButton("Yes"); public static JButton textNo = new JButton("No"); 下面是我的main()方法: 下面是Start()方法: 下面是带有JButton侦听器的actionPerfor

基本上,每次我点击我的一个按钮,它就会锁定。我环顾四周,发现这可能是因为一个无限循环,但我在任何地方都看不到

一双新鲜的眼睛会很有用的

无论如何,下面是要声明的JButtons:

public static JButton textYes = new JButton("Yes");
public static JButton textNo = new JButton("No");
下面是我的main()方法:

下面是Start()方法:

下面是带有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";
        }
    }
}
我在想它和JButtons有某种联系

如果需要显示更多代码,请告诉我

无论如何,任何和所有的帮助都是感激的

谢谢你的帮助和时间

编辑:很抱歉,我忘记显示附加到JBUttons的侦听器:

textYes.addActionListener(this);
textNo.addActionListener(this);
编辑:还有,这里是Game()方法:

以及rollDice方法:


看起来您从未将任何侦听器附加到按钮,而是尝试从System.in读取。如果这是真的,那么程序将挂起,等待System.in的输入

而不是

Scanner is = new Scanner(System.in);
...
area = "menu";
menu = is.next();
在按钮上使用actionListeners,使用

textYes.addActionListener(/*Your Action Listener*/);
...

编辑-即使附加了ActionListeners,它也会挂在扫描行上,试图读取输入流。删除这些行应该可以解决此问题。

看起来您从未将任何侦听器附加到按钮,而是尝试从System.in读取。如果这是真的,那么程序将挂起,等待System.in的输入

而不是

Scanner is = new Scanner(System.in);
...
area = "menu";
menu = is.next();
在按钮上使用actionListeners,使用

textYes.addActionListener(/*Your Action Listener*/);
...

编辑-即使附加了ActionListeners,它也会挂在扫描行上,试图读取输入流。删除这些行应该可以解决问题。

问题是您的
ActionListener
在不使用新线程的情况下执行所有操作。这意味着您正在冻结UI线程,这基本上会阻止UI刷新

您可以在
actionPerformed
方法中使用
线程

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所说,在这种情况下,最好使用一个线程而不是一个线程。问题是您的
ActionListener
在不使用新线程的情况下执行所有操作。这意味着您正在冻结UI线程,这基本上会阻止UI刷新

您可以在
actionPerformed
方法中使用
线程

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所说,在这种情况下,最好使用一个而不是一个线程

我怀疑
ChoiceRollDice
正在使用一个扫描器从用户那里读取输入,这会阻塞事件调度线程,阻止它被重新绘制

您将CLI范例与GUI范例混合在一起,这再次提出了一个问题:为什么


使用图形界面时,不应使用CLI样式的输入(即
扫描仪
),而应使用可用的图形控件,例如按钮或文本字段

我怀疑
ChoiceRollDice
正在使用扫描仪从用户读取输入,这将阻止事件调度线程,阻止其重新绘制

您将CLI范例与GUI范例混合在一起,这再次提出了一个问题:为什么



使用图形界面时,不应使用CLI样式的输入(即
扫描仪
),而应使用可用的图形控件,例如按钮或文本字段

游戏()的功能是什么?它看起来像是在UI线程中进行处理,这使得UI无法更新。游戏运行几种不同的方法。我可以很快地发布Game()方法。我们还需要所有的rollDice方法。当然,我也会把它们放上去。即使它们所做的只是掷骰子,
Game()
做什么?它看起来像是在UI线程中进行处理,这使得UI无法更新。游戏运行几种不同的方法。我可以很快发布Game()方法。我们还需要所有的rollDice方法。当然,我也会把它们放上去。尽管它们所做的只是掷骰子。很抱歉,我确实有一些听众,我只是没提到。删除哪一行<代码>菜单=is.next()?扫描器is=新扫描器(System.in);“和“菜单=is.next;”行。除非你想让用户输入他们的回复,否则这些都是不需要的。即使去掉那些线,它仍然有同样的问题。此外,每当我尝试使用
textYes.addActionListener()时它告诉我它不是抽象的。对此很抱歉,但我确实附加了一些侦听器,我只是没有提到。删除哪些行<代码>菜单=is.next()?扫描器is=新扫描器(System.in);“和“菜单=is.next;”行。除非你想让用户输入他们的回复,否则这些都是不需要的。即使去掉那些线,它仍然有同样的问题。此外,每当我尝试使用
textYes.addActionListener()时它告诉我它不是抽象的。这不起作用,它只是说“线程不能应用于给定的类型”和“局部变量e是从内部类中访问的;需要声明为final”。还有其他想法吗?非常感谢。@user2506658是的,
Thread
不能使用局部变量,除非它们是
final
。因此,您需要使用
final
变量或。对于无法应用于给定类型的线程,抛出的
异常的完整消息是什么?@user2506658请参见我的编辑,将
public void actionPerformed(ActionEvent e)
更改为
public void actionPerformed(final ActionEvent e)
从内部类访问局部变量e;需要声明最终错误应消失“方法”
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();

}