Обновить объекты GUI в приложении Java

Первое размещение. Я чувствую, что это должно быть довольно просто, но после поиска и попытки я остался без решения. Я заново создал свою проблему в очень простой программе MVC - она ​​ведет себя одинаково как в этом примере приложения, так и в моем реальном приложении; Я явно делаю одну и ту же ошибку в обоих местах.

В моем настольном Java-приложении у меня есть код GUI в классе «View». Этот класс строго отвечает за внешний вид графического интерфейса, обеспечивая отображение всех видимых объектов на экране / в окне. «Контроллер» обрабатывает весь поток программы и отвечает за прослушивание пользовательских событий, таких как нажатие кнопки, а затем вызывает необходимые методы View для извлечения или передачи данных из / в GUI.

Классы, приведенные ниже, делают это очень простым способом - все, что он делает, это рисует небольшое окно JFrame, содержащее JPanel с 4 объектами, 3 JButton и JTextField. При нажатии любой из 3 кнопок номер этой кнопки, 1, 2 или 3, должен отображаться в текстовом поле. Только поле не обновляется. У меня есть метод в View, который вызывает методы repaint () и revalidate () JFrame, вызываемые из контроллера сразу после обновления текстового поля после нажатия кнопки. У меня есть оператор печати, который записывает текст в консоль, поэтому я знаю, что эта часть работает. Я также считаю, что обновление текстового поля работает, так как у меня в диалоговом окне сообщения отображается его значение. Мое понимание - это JFrame.repaint (); предполагается перекрасить фрейм и все его потомки (объекты внутри), просто нет.

Заранее спасибо за помощь. Вот мой пример кода:

Model.java (в настоящее время пусто)

package com.techbybryan;

public class Model {
}

View.java

package com.techbybryan;

import javax.swing.*;
import java.awt.*;

public class View {

    JButton button1 = new JButton( "One" );
    JButton button2 = new JButton( "Two" );
    JButton button3 = new JButton( "Three" );
    JTextField jTextField = new JTextField();
    JPanel jPanel = new JPanel();
    JFrame jFrame = new JFrame( "Gui Test" );

    public View(){

        jPanel.add( button1 );
        jPanel.add( button2 );
        jPanel.add( button3 );
        jPanel.add( jTextField );
        jFrame.add( jPanel );

        jFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        jFrame.setSize(new Dimension( 500, 100 ) );
        jFrame.setLocationRelativeTo( null );
        jFrame.setResizable( false );
        jFrame.setVisible( true );
    }

    public JButton getButton1() {
        return button1;
    }

    public void setButton1( JButton button1 ) {
        this.button1 = button1;
    }

    public JButton getButton2() {
        return button2;
    }

    public void setButton2( JButton button2 ) {
        this.button2 = button2;
    }

    public JButton getButton3() {
        return button3;
    }

    public void setButton3( JButton button3 ) {
        this.button3 = button3;
    }

    public JTextField getjTextField() {
        return jTextField;
    }

    public void setJTextField( JTextField jTextField ) {
        this.jTextField = jTextField;
    }

    public void repaint(){
        jFrame.revalidate();
        jFrame.repaint();
        JOptionPane.showMessageDialog( null, jTextField );
    }
}

Controller.java

package com.techbybryan;

import javax.swing.*;

public class Controller {
    Model      model;
    View       view;
    Controller controller;

    public Controller( Model model, View view ){
        this.model = model;
        this.view = view;
    }

    public void init(){
        view.getButton1().addActionListener( e -> setOutputText( "One" ) );
        view.getButton2().addActionListener( e -> setOutputText( "Two" ) );
        view.getButton3().addActionListener( e -> setOutputText( "Three" ) );
    }

    public void setOutputText( String textToDisplay ){
        System.out.println( textToDisplay );

        view.setJTextField( new JTextField( textToDisplay ) );
        view.repaint();
    }
}

GuiText.java

package com.techbybryan;

public class GuiTest {

    public static void main(String[] args) {
        Model      model      = new Model();
        View       view       = new View();
        Controller controller = new Controller( model, view );

        controller.init(  );
    }
}

Большое спасибо за любой конструктивный совет, который вы можете иметь; Я ценю ваши отзывы.

Всего 1 ответ


Этот код в вашем контроллере неверен:

view.setJTextField( new JTextField( textToDisplay ) );

Контроллер не должен добавлять компоненты в представление, скорее, этот метод, actionlistener, должен изменять состояние модели, чего вы не можете сделать, так как ваш класс модели необъяснимо пуст.

Короче говоря, вы делаете все задом наперед - сначала вы должны заставить свою модель работать, а затем подключить элемент управления и представление для работы с моделью в первую очередь. Ваша модель должна уведомить представление, когда оно изменяется (PropertyChangeListener будет хорошо работать здесь), и затем представление должно обновить отображение в отображаемом в настоящий момент JTextField ( не добавляя новый JTextField --sorry, чтобы быть тупым, но это безумно сумасшедший), основанный на состоянии модели.

Кроме того, избавьтесь от всех этих перерисовок и повторных проверок, так как этот код не поможет решить вашу основную проблему и не нужен.

Обратите внимание, что я бы избавился от этого кода:

public void setJTextField( JTextField jTextField ) {
    this.jTextField = jTextField;
}

Вместо этого сделайте что-нибудь более похожее

public void setJTextFieldText(String text) {
    this.jTextField.setText(text);
}

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


Есть идеи?

10000