0

im currently trying to create a program that dynamically changes the text on JTextArea's and JButtons when they are pressed, or display a JOptionPane. At the moment nothing is happening when i press the buttons, they are not getting updated nor are they making a dialogue box appear.

Help is appreciated private MillionaireGui view; private Millionaire model; private String question; private int gameState; private boolean 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();
}

GUI:

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);
}

MAIN:

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();
  }
}
user2542424
  • 11
  • 1
  • 4
  • 2
    I honestly think you mis-understanding how UI's work and seem to be think in a linear process. UI's are event driven, that is, something happens and you respond to it. You whole "update" loop just screams "wrong" at me – MadProgrammer May 14 '15 at 14:05
  • 1
    Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses – MadProgrammer May 14 '15 at 14:10
  • Can you show us what your controller is doing? – nullByteMe May 14 '15 at 14:25
  • sure, it has been changed above – user2542424 May 14 '15 at 21:45

2 Answers2

1

The code within the update() method seems to be running with a thread. What I think is happening is that you have 2 threads, one of which is doing some background task which causes the update. The background thread is not the EDT, thus any UI updates will not be visible.

Trying the approach below would fix the problem (most likely at least)

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));
    }
});

The above should place your button settings events on the EDT, which should trigger the change.

npinti
  • 51,780
  • 5
  • 72
  • 96
  • thanks for the response will try it out! EDIT: just tried that out and its still not responding. I think i will have to try a swingworker? – user2542424 May 14 '15 at 14:14
  • 1
    @user2542424 If something like `SwingUtilities` didn't solve your problem, it's unlikely that `SwingWorker` will. You probably need to change your design/approach to fit within the event driven nature of the framework, instead of trying to "force" monitoring and state changes – MadProgrammer May 14 '15 at 14:21
  • @user2542424: Please take the advice given by *MadProgrammer*. I think that this will boil down to a design problem. In Java UI events are event driven, having a loop which polls sort of breaks that. – npinti May 14 '15 at 14:23
  • I have taken out the while loop now, so that all it is doing is constantly running checks. Any more advice is appreciated – user2542424 May 14 '15 at 22:37
  • @user2542424: What would happen if you where to wrap your GUI methods within a `SwingWorker`? – npinti May 15 '15 at 06:12
1

Looks like maybe you just need to revalidate the container.

After you set all the button text fields, call gui.revalidate() to mark everything as invalid & validate. Here's more on the differences between those 3 methods

Also (as mentioned by @npinti) - I'm not sure exactly what you're doing with the extra thread, but be aware that modifying GUI components outside of the AWT thread is NOT a good idea

Community
  • 1
  • 1
blazetopher
  • 1,050
  • 9
  • 13