UI在调试模式下按预期更新,但在正常运行时不执行任何操作

时间:2012-03-13 18:00:33

标签: java swing debugging user-interface netbeans

我正在NetBeans中创建一个简单的基于游戏回合的游戏。在GUI初始化之后,它调用函数herosTurn(),等待用户选择,并从单独的类Hero创建该选择的结果。当我在调试模式中单步执行代码时,我得到了正确的结果,但是如果我只是运行代码,则除了在等待输入时等待函数不断附加文本时,不会将任何内容附加到文本区域。我已经看到了类似的其他问题,但它们都涉及多线程,我不相信这就是我在做的事情。任何帮助将不胜感激。

这是主要课程:

package Flow;

import Forms.Battleinterface;


/**
 *
 * @author Steemo
 */
public class battle { 
    public static int hAct;
    public static int gLife = 200;

    public static void herosTurn() {
        hAct = 0;

        Forms.Battleinterface.biText.append("What will you do?");
        while (hAct == 0){
            // adding the line below makes code work but is ugly.
            //Forms.Battleinterface.biText.append(".");
            continue;
        }
        if (hAct == 1){
            Entities.Hero.attack();
        }
    }

    public static void main(String args[]) {
        Battleinterface battleinterface = new Forms.Battleinterface();
        Battleinterface.Start();
        while (gLife > 0) {
            herosTurn();
        }


    }
}

这是Hero()类,它位于一个单独的包中:

package Entities;

import java.util.Random;

/**
 *
 * @author Steemo
 */
public class Hero {
    static Random hGen = new Random(54154454);

    public static void attack() {
        int hAtt = 0;
        hAtt = hGen.nextInt(6) + 15;
        Forms.Battleinterface.biText.append("\nYou swing your axe and do " + hAtt
                + " Damage!!!");
    }

}

我没有附加我用来生成GUI(Battleinterface)的类,因为GUI生成正常,而在那里发生的唯一其他事情是输入hAct的传递。 如果需要,我可以附上它。

4 个答案:

答案 0 :(得分:1)

替换此代码......

while (hAct == 0){
  continue;
}

......改为:

while (hAct == 0){
  try {
    Thread.yield();
  } catch (InterruptedException interruptedEx) {
    // Log the interruption somewhere.
  }
}

假设你在某种程度上使用AWT / Swing?这是一个无限循环,阻止其他线程运行。通过这样做,你永远不会让UI线程实际进行任何更新,这意味着它似乎挂起。您可能没有自己进行任何线程,但AWT / Swing内置了用于执行各种功能的线程,并且需要定期获得CPU时间来完成工作。

这在调试中起作用的原因是因为调试器正在暂停herosTurn方法,因为你正在逐步执行它,允许UI线程进行更新(包括从用户那里获取输入),但是在运行游戏时,herosTurn方法永远不会暂停,并且该方法占用了应用程序可用CPU时间的100%。

最后,正如Mike Clark提到的那样,您通常不应该使用无限循环编写UI。而是定义触发事件的组件。您的代码会收到有关这些事件的通知并做出适当的反应这就是所谓的UI事件模型。如果您正在使用Swing,那么有关在事件模型is covered here中工作的介绍性信息。

我通常也不会将AWT / Swing用于游戏,因为UI编码的复杂性,渲染性能以及与AWT / Swing不是游戏的良好工具的现实相关的其他几个原因。话虽这么说,一个回合制游戏可以这样工作(因为渲染性能要求通常要低得多)如果你愿意深入研究UI代码来完成它,除了一些其他原因我已在a previous answer中列出。

答案 1 :(得分:0)

嗯,将文本缓冲区刷新到文本区域可能存在问题。尝试在每次打印后显式刷新文本缓冲区,看看是否会产生影响。

答案 2 :(得分:0)

在我看来,你的程序停留在方法herosTurn()中的while循环中。只要该函数没有返回,如果你将这个游戏编程为单个线程应用程序,就不会有任何更新。

当您取消注释Forms.Battleinterface.biText.append(".");行cos时,它会起作用,然后每次迭代都会向GUI发送一个信号,导致它更新。

游戏通常有一个主游戏循环,程序的所有元素都可以从中控制。也许改变你的实施策略会有所帮助吗?

答案 3 :(得分:0)

我不是游戏程序员,所以这可能不是最好的方法,但为什么不尝试设置每隔100毫秒运行一次的javax.swing.Timer。在计时器操作内部,您可以编写所有检查和提升游戏状态的代码,并为用户生成输出。

我建议在JTextField中收集用户输入,该JTextField与打印游戏输出的地方分开。如果您想知道用户何时按Enter键发送他们输入的内容,您可以在JTextField上注册ActionListener。

textField.addActionListener(yourListener);