удалитьВсе не удаляются при следующей проверке? - PullRequest
5 голосов
/ 28 апреля 2011

Может кто-нибудь объяснить, почему следующее не работает так, как я ожидаю?

Нажатие кнопки «должно» приведет к отображению только с (пустым) JScrollPane, то есть поле ввода и кнопка должны исчезнуть.Однако они остаются, пока размер компонента не изменится ...

public static void main(String[] args)
{
    JFrame frame = new JFrame("test");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    final JPanel panel = new JPanel();

    Container cp = frame.getContentPane();
    cp.setLayout(new FlowLayout());
    cp.add(new JScrollPane(panel));

    Component textField = new JTextField("i am input");
    JButton button = new JButton(new AbstractAction("i am pressy")
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            // this is already on the EDT
            panel.removeAll();
            panel.revalidate();
        }
    });

    panel.setLayout(new FlowLayout());
    panel.add(textField);
    panel.add(button);

    frame.pack();
    frame.setVisible(true);
}

Спасибо за вашу помощь.р.

Ответы [ 3 ]

19 голосов
/ 28 апреля 2011

При обновлении видимого графического интерфейса код должен быть:

panel.revalidate();
panel.repaint(); // sometimes needed, this appears to be one of them
9 голосов
/ 28 апреля 2011

Метод revalidate() помечает компоненты как подлежащие планировке, но пока что-то не сработает repaint(), вы не увидите никаких изменений.Изменение размера родительского окна является одним из таких триггеров;переключение приложений это другое.В этой предыдущей версии обратите внимание, как setSize() на панели устраняет необходимость в repaint().Аналогично, этот пример изменяет макет в resetGame().

В статье Рисование в AWT и Swing более подробно.

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

/** @see https://stackoverflow.com/questions/5812002 */
public class RevalidateTest {

    private static JPanel panel = new JPanel(); // default FlowLayout
    private static JTextField text = new JTextField("Text field");
    private static JButton clear = new JButton(new AbstractAction("Clear") {

        @Override
        public void actionPerformed(ActionEvent e) {
            panel.removeAll();
            panel.add(reset);
            panel.revalidate();
            panel.repaint();
        }
    });
    private static JButton reset = new JButton(new AbstractAction("Reset") {

        @Override
        public void actionPerformed(ActionEvent e) {
            panel.removeAll();
            panel.add(text);
            panel.add(clear);
            panel.revalidate();
            panel.repaint();
        }
    });

    static void createAndShowGUI() {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        panel.add(text);
        panel.add(clear);
        frame.add(panel); // default BorderLayout center
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
2 голосов
/ 28 апреля 2011

Вы можете выполнить panel.repaint(), как указано в комментарии @Jeremy, однако пользовательский интерфейс все равно изменится при изменении размера окна.Причина в том, что удаление элементов из JPanel приведет к изменению размера панели.Операция перерисовки не приведет к изменению размера панели до тех пор, пока JFrame не перепроверит свой макет (как это происходит при изменении размера окна).

Чтобы убедиться, что макет правильно выложен при изменении, вы можете позвонить frame.validate().Эта операция приведет к повторной проверке JFrame себя и всех дочерних компонентов, что является той же самой операцией, которая происходит во время события изменения размера окна.Чтобы выполнить этот метод в своем коде, вам нужно изменить JFrame frame на final, то есть

final JFrame frame = new JFrame("test");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...