Редактирование текста JLabel из другого класса - PullRequest
3 голосов
/ 30 марта 2012

Итак, я пытаюсь отредактировать текст моего JLabel из другого класса. Я делаю это с label.setText ("бла бла"); но это не влияет на мою JLabel.

Мой код в классе GUI выглядит примерно так:

public class GUI {

    JFrame f1 = new JFrame("GUI");
    JLabel l1 = new JLabel("Output");
    JTextField tf1 = new JTextField("");

    public run(){  // main calls this method.

    Listener listener = new Listener();

    f1.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    f1.setBounds(450, 170, 400, 400);
    f1.setVisible(true);
    f1.setResizable(false);
    f1.setLayout(null);

    l1.setBounds(8, 8, 200, 30);
    listener.listen(tf1);

    f1.add(l1);
    }
}

и затем у меня есть этот класс слушателя, который должен вносить изменения в JLabel в зависимости от ввода пользователя. Вот код:

public class Listener {

    GUI gui = new GUI();

    public void listen(final JTextField textfield) {

        textfield.getDocument().addDocumentListener(new DocumentListener() {

            public void changedUpdate(DocumentEvent e) {
                test();
            }

            public void removeUpdate(DocumentEvent e) {
                test();
            }

            public void insertUpdate(DocumentEvent e) {
                test();
            }

            public void test() {
                if (gui.everythingOK()) { // everythingOK is just a boolean that test if input is valid number and returns true if it is.
                    gui.l1.setText("No errors."); // this code is supposed to change JLabels text.
                } else {
                    gui.l1.setText("Error."); // this code is supposed to change JLabels text.
                }
            }
        });
    }
}

Метод allOK работает отлично, ты просто должен доверять мне в этом. Это работает, если я определяю JLabel как статический, но это работает только в первый раз. После первого изменения в JLabel больше не появляются изменения, поэтому определение статического не помогает. Я надеюсь, что есть кто-то, кто знает, что не так с этим кодом. И не против, если есть явные ошибки, потому что я взял только самые важные части очень очень длинного кода.

Заранее спасибо.

Вот мой код ОК:

public boolean everythingOK() {
        if (hasInt(tf1) && isValid(tf1)) {
            return true;
        } else {
            return false;
        }
    }

    public boolean hasInt(JTextField textfield) {
        try {
            Integer.parseInt(textfield.getText());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public boolean isValid(JTextField textfield) {
        if (hasInt(textfield)) {
            if (Integer.parseInt(textfield.getText()) >= minValue && Integer.parseInt(textfield.getText()) <= maxValue) {
                return true;
            } else {
                return false;
            }

        } else {
            return false;
        }

    }

1 Ответ

3 голосов
/ 30 марта 2012

Ваш класс Listener создает еще один экземпляр Gui.

GUI gui = new GUI();

Код в Listener.test () изменяет метку l1 в его экземпляре Gui, а не в отображаемом Gui.

Вы должны дать Слушателю ссылку на настоящий объект Gui.

Возможно, вам также придется обернуть код, который устанавливает новую метку в SwingUtilities.invokeLater, чтобы он выполнялся из потока диспетчеризации событий.

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      <guiInstance>.l1.setText("Query: " + queryNo);
    }
  });

UPDATE: Вот пример кода, который делает то, что вы хотите. Вы можете взять его как есть и поиграть с ним. Посмотрите, как класс GUI дает свой собственный экземпляр Listener при его создании (новый Listener (this). Если текстовое поле содержит текст, то на этикетке печатается «Нет ошибок», в противном случае печатается «Ошибка».

В этом случае часть SwingUtilities.invokeLater на самом деле не нужна. Но если вы продолжаете развивать свою программу и начинаете добавлять фоновые потоки, которые хотят обновить пользовательский интерфейс, то вам нужно сделать это следующим образом. Просто предупреждение на потом ...; -)

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;

public class GUI {

    JFrame f1 = new JFrame("GUI");
    JLabel l1 = new JLabel("Output");
    JTextField tf1 = new JTextField("");

    public void run(){  // main calls this method.
        f1.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        f1.setBounds(450, 170, 400, 400);
        f1.setVisible(true);
        f1.setResizable(false);
        f1.setLayout(new GridLayout(2,1));

        f1.add(l1);
        f1.add(tf1);

        f1.pack();

        Listener listener = new Listener(this);
        listener.listen(tf1);
    }

    public static void main(String[] args) {
        new GUI().run();
    }

    public boolean everythingOK() {
        return tf1.getText().length() > 0;
    }

    class Listener {
        private GUI gui;

        public Listener(GUI gui) {
            this.gui = gui;
        }

        public void listen(final JTextField textfield) {

            textfield.getDocument().addDocumentListener(new DocumentListener() {

                public void changedUpdate(DocumentEvent e) { test(); }
                public void removeUpdate(DocumentEvent e) { test(); }
                public void insertUpdate(DocumentEvent e) { test(); }

                public void test() {
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            if (gui.everythingOK()) { // everythingOK is just a boolean that test if input is valid number and returns true if it is.
                                gui.l1.setText("No errors."); // this code is supposed to change JLabels text.
                            } else {
                                gui.l1.setText("Error."); // this code is supposed to change JLabels text.
                            }
                        }
                    });
                }
            });
        }
    }
}
...