Как я могу удалить JPanel из JFrame? - PullRequest
9 голосов
/ 23 марта 2010

Недавно я спросил здесь , как добавить новую JPanel в JFrame . Ответ помог мне получить рабочий код. Но не у меня есть связанный вопрос: «Как я могу удалить старую JPanel». Мне это нужно из-за следующей проблемы.

Когда я захочу, появится новая JPanel (либо превышено ограничение по времени, либо пользователь нажмет кнопку «Отправить»). Но через несколько секунд какой-то элемент старой JPanel появляется вместе с компонентом новой JPanel. Я не понимаю, почему это происходит.

Я думал, что это связано с тем, что я обновляю окно. Но в первом потоке просто добавьте старую панель один раз (значит, она должна быть закончена). И во втором потоке у меня есть цикл, который нарушен (так что это также должно быть закончено).

Вот мой код:

private Thread controller = new Thread() {
    public void run() {
        // First we set the initial pane (for the selection of partner).
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.getContentPane().add(generatePartnerSelectionPanel());
                frame.invalidate();
                frame.validate();
            }
        });
        // Update the pane for the selection of the parnter.
        for (int i=40; i>0; i=i-1) {
            final int sec = i;
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    timeLeftLabel.setText(sec + " seconds left.");
                }
            });
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) { }

            if (partnerSubmitted) {
                break;
            }
        }
        // For the given user the selection phase is finished (either the time is over or form was submitted).
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.getContentPane().add(generateWaitForGamePanel());
                frame.invalidate();
                frame.validate();
            }
        });

    }
};

Ответы [ 5 ]

8 голосов
/ 23 марта 2010

То же самое, если вы добавляете или удаляете компонент в видимом графическом интерфейсе:

panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint();
7 голосов
/ 23 марта 2010

Самый простой способ удалить компонент (панель) из контейнера (фрейма) - сохранить ссылку на него, а затем вызвать Container.remove(Component), то есть:

private Thread controller = new Thread() {
public void run() {

        final Component panel1 = generatePartnerSelectionPanel();

        // First we set the initial pane (for the selection of partner).
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.getContentPane().add(panel1);
                frame.invalidate();
                frame.validate();
        }
        });
        // Update the pane for the selection of the parnter.
        for (int i=40; i>0; i=i-1) {
            final int sec = i;
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    timeLeftLabel.setText(sec + " seconds left.");
                }
            });
            try {Thread.sleep(1000);} catch (InterruptedException e) {}
            if (partnerSubmitted) {break;}
        }
        // For the given user the selection phase is finished (either the time is over or form was submitted).
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.getContentPane().remove(panel1);
                frame.getContentPane().add(generateWaitForGamePanel());
                frame.invalidate();
                frame.validate();
        }
        });

}
};

Я не тестировал этот код, но он должен работать.

1 голос
/ 31 января 2018

У меня тоже были проблемы с requestFocusInWindow на TextField. Хитрость заключается в том, чтобы не создавать компоненты в конструкторе JPanel. Но создайте метод сборки и выполните следующий код после того, как он был добавлен во фрейм.

Это сработало для меня:

frame.getContentPane().removeAll(); //or .remove(previousPanel);
frame.getContentPane().add(newPanel);
panel.buildPanel(); // panel needs a builder method
frame.revalidate(); // in- and validate in one !! 
frame.pack(); // 

Если вы хотите изменить размер, вам нужно preferredSize(); на панели или использовать repaint(), если вам не нужно изменять размер фрейма.

0 голосов
/ 02 апреля 2017
    panel.invalidate();
    panel.setVisible(false);
    panel.removeAll();
    frame.getContentPane().remove(panel);
    panel = null;
0 голосов
/ 23 марта 2010

Роман, проблему можно решить так:

  1. Сделайте это в начале вашего run метода:

final JPanel partnerSelectionPanel = generatePartnerSelectionPanel();

  1. Тогда сделайте это

frame.getContentPane().add(partnerSelectionPanel);

  1. Прежде чем добавить новую панель, сделайте следующее:

partnerSelectionPanel.setVisible(false);

Работает. Я не знаю, является ли это безопасным и / или элегантным решением, но оно работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...