2015-05-14 5 views
0

im в настоящее время пытается создать программу, которая динамически меняет текст в JTextArea и JButtons при нажатии или отображает JOptionPane. На данный момент ничего не происходит, когда я нажимаю кнопки, они не обновляются и не появляются диалоговое окно.GUI не обновляется динамически

справка приветствуется частное лицо MillionaireGui; частная модель миллионера; частный вопрос строкой; 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); 
} 

ОСНОВНОЙ:

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(); 
    } 
} 
+2

Я честно думаю вы неправильно понимаете, как работает пользовательский интерфейс и, кажется, думают в линейном процессе. UI управляются событиями, то есть что-то происходит, и вы отвечаете на него. Вы весь цикл «обновления» просто кричат ​​«неправильно» на мне – MadProgrammer

+1

Рассмотрите возможность предоставления [runnable example] (https://stackoverflow.com/help/mcve), который демонстрирует вашу проблему. Это не дамп кода, а пример того, что вы делаете, что подчеркивает проблему, с которой вы сталкиваетесь. Это приведет к меньшему путанице и лучшим ответам – MadProgrammer

+0

Можете ли вы показать нам, что делает ваш контроллер? –

ответ

1

Код в методе update(), кажется, работает с нитью. Что я знаю думаю происходит, что у вас есть 2 потока, один из которых выполняет некоторую фоновую задачу, которая вызывает обновление. Фоновый поток не является EDT, поэтому любые обновления пользовательского интерфейса не будут видны.

Стараясь подход ниже будет решить эту проблему (скорее всего, по крайней мере)

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, которое должно вызвать изменение.

+0

спасибо, что ответ попробует! РЕДАКТИРОВАТЬ: просто попробовал это и все еще не ответил. Думаю, мне придется попробовать swingworker? – user2542424

+1

@ user2542424 Если что-то вроде 'SwingUtilities' не решило вашу проблему, маловероятно, что' SwingWorker' будет. Вероятно, вам нужно изменить свой дизайн/подход, чтобы он соответствовал природе, основанной на событии, вместо того, чтобы пытаться «принудительно» отслеживать и изменять состояние. – MadProgrammer

+0

@ user2542424: Пожалуйста, дайте совет, заданный * MadProgrammer *. Я думаю, что это сводится к проблеме дизайна. В Java UI события управляются событиями, имея цикл, который опробовывает разрывы, которые. – npinti

1

Похоже, что вам нужно всего лишь revalidate контейнер.

После установки всех кнопок текстовых полей, вызовите gui.revalidate() пометить все как invalid & validate. Here's more on the differences between those 3 methods

Кроме того (как было упомянуто @npinti) - Я не уверен, что именно то, что вы делаете с дополнительной нитью, но следует помнить, что изменение компонентов GUI вне AWT нити NOT a good idea

+0

'setText' - это связанное поле, то есть при вызове оно автоматически делает недействительными себя и назначает переписывание – MadProgrammer

+0

действительно, хороший вызов - возможно, это просто проблема с многопотоковой обработкой? – blazetopher

+0

Да, я уверен, проблема в многопоточности – user2542424