【问题标题】:GUI not updating dynamicallyGUI 没有动态更新
【发布时间】:2015-07-26 04:15:29
【问题描述】:

我目前正在尝试创建一个程序,该程序可以在 JTextArea 和 JButton 被按下时动态更改它们的文本,或者显示一个 JOptionPane。目前,当我按下按钮时什么都没有发生,它们没有得到更新,也没有出现对话框。

感谢您的帮助 私人 MillionaireGui 视图; 私人百万富翁模型; 私人字符串问题; 私人 int 游戏状态; 私有布尔 isRunning;

public MillionaireController(MillionaireGui view, Millionaire model) {
    this.view = view;
    this.model = model;
    this.question = null;
    this.gameState = 0;
    this.isRunning = true;
}

public void setModel(Millionaire model) {
    this.model = model;
}

public void setView(MillionaireGui gui) {
    this.view = gui;
}

public void getQuestion() {
    question = model.getDeck().generateQuestion();
    view.setQuestion(question);
}
public void update(){
 while(isRunning){

 if(gameState == 0){

    getQuestion();

    ArrayList<String> ans = model.getDeck().getAnswers();
    view.setButtonA(ans.get(0));
    view.setButtonB(ans.get(1));
    view.setButtonC(ans.get(2));
    view.setButtonD(ans.get(3));
    gameState = 1;

}

if(gameState == 1){

    if(view.getAnswer() != 0){
        if(model.getDeck().isCorrect(view.getAnswer())){
            view.dispCorrectAnswer();
            view.setAnswer(0);
                gameState = 0;
        }
        else {
            gameState = 3;
        }
    }

  }
  if(gameState == 3){
      isRunning = false;
      view.displayErrorMsg();
    }
}
}
@Override
public void run() {
  update();
}

图形界面:

public void setButtonB(String str){
    buttonB.setText(str);
}

public void setButtonC(String str){
    buttonC.setText(str);
}

public void setButtonD(String str){
    buttonD.setText(str);
}

public void setAnswer(int num){
    answer = num;
}

public String getQuestion(){
   return question;

}

public void setQuestion(String str){
   question = str;
   questionField.setText(str);
}

主要:

public class Millionaire_main {

public Millionaire_main(){

}

public static void main(String[] args) {
    MillionaireGui gui = new MillionaireGui();
    QuestionDeck deck = new QuestionDeck();
    Millionaire model = new Millionaire(deck);
    MillionaireController control = new MillionaireController(gui, model);   
    gui.setVisible(true);

    Thread thread = new Thread(control);
    thread.start();
  }
}

【问题讨论】:

  • 老实说,我认为您误解了 UI 的工作方式,并且似乎是在线性过程中思考的。 UI 是事件驱动的,也就是说,有些事情发生了,你会做出响应。你整个“更新”循环只是对我尖叫“错误”
  • 考虑提供一个runnable example 来证明您的问题。这不是代码转储,而是您正在做的事情的一个例子,它突出了您遇到的问题。这将减少混乱并获得更好的响应
  • 你能告诉我们你的控制器在做什么吗?
  • 没错,上面已经改了

标签: java swing user-interface


【解决方案1】:

update() 方法中的代码似乎正在使用线程运行。我认为正在发生的是您有 2 个线程,其中一个正在执行一些导致更新的后台任务。后台线程不是 EDT,因此任何 UI 更新都将不可见。

尝试以下方法可以解决问题(至少很可能)

SwingUtilities.invokeLater(new Runnable() 
{
    @Override
    public void run() {
        view.setButtonA(ans.get(0));
        view.setButtonB(ans.get(1));
        view.setButtonC(ans.get(2));
        view.setButtonD(ans.get(3));
    }
});

上面应该将您的按钮设置事件放在 EDT 上,这应该会触发更改。

【讨论】:

  • 感谢您的回复将尝试一下!编辑:刚刚尝试过,它仍然没有响应。我想我得试试摇工?
  • @user2542424 如果像SwingUtilities 这样的东西不能解决你的问题,那么SwingWorker 不太可能会。您可能需要更改设计/方法以适应框架的事件驱动性质,而不是尝试“强制”监控和状态更改
  • @user2542424:请采纳MadProgrammer的建议。我认为这将归结为设计问题。在 Java UI 中,事件是事件驱动的,有一个循环来轮询中断。
  • 我现在已经去掉了while循环,所以它所做的就是不断地运行检查。任何更多的建议表示赞赏
  • @user2542424:如果您将 GUI 方法包装在 SwingWorker 中会发生什么?
【解决方案2】:

看起来您可能只需要revalidate 容器。

设置所有按钮文本字段后,调用gui.revalidate() 将所有内容标记为invalidvalidateHere's more on the differences between those 3 methods

另外(如@npinti 所述)- 我不确定您在使用额外线程做什么,但请注意,在 AWT 线程之外修改 GUI 组件是NOT a good idea

【讨论】:

  • setText 是绑定字段,即调用时会自动使自己失效并安排重绘
  • 确实,不错的选择 - 也许这只是多线程的问题?
猜你喜欢
  • 2013-10-06
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-17
  • 2016-01-12
相关资源
最近更新 更多