Я создаю апплет (j), где пользователь имеет доступ к нескольким различным представлениям, выбираемым из дерева. Апплет имеет основную область, в которой текущее представление отображается внутри прокрутки, заменяя все, что было там раньше. В большинстве случаев это отлично работает, но когда вид, который нужно заменить, имеет более сложный макет, так как в больших (~ 100 компонентов), не вложенных, удаление занимает несколько секунд! Создание большого вида - молниеносное, только удаление происходит медленно. Это заметно только в апплетах, запуск приложения в JFrame все еще так же быстро, как я ожидаю. Я использую GridBagLayout для представления.Удаление контейнера, который использует сложный макет
После нескольких экспериментов я обнаружил, что, если я заменю
contents.remove(view); //contents is the view of the scrollpane.
с
view.removeAll();
contents.remove(view);
тогда весь процесс очень быстро.
Я предполагаю, что причиной такого поведения является макет «магии» Java, и хотя у меня есть решение, оно не кажется правильным и, похоже, указывает, что я не совсем понимаю, что происходит. Поэтому мой вопрос (ы) таков:
Кто-нибудь знает, что на самом деле происходит? Есть ли лучший (более ясный) способ сделать то же самое?
Edit: SSCCE: http://pastebin.com/VC1T7zGv
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class SSCCE extends JApplet {
private boolean state;
public void init() {
super.init();
getContentPane().add(setupSwitchPanel(), BorderLayout.NORTH);
getContentPane().add(setupSimplePanel(), BorderLayout.CENTER);
}
private JPanel setupSwitchPanel() {
JPanel switchPanel = new JPanel();
switchPanel.add(new JButton(new AbstractAction("Switch panels (slow)") {
@Override
public void actionPerformed(ActionEvent arg0) {
switchComponents();
}
}));
switchPanel.add(new JButton(new AbstractAction("Switch panels (fast)") {
@Override
public void actionPerformed(ActionEvent arg0) {
((JPanel)getContentPane().getComponent(1)).removeAll();
switchComponents();
}
}));
return switchPanel;
}
private void switchComponents() {
getContentPane().remove(1);
if (state)
getContentPane().add(setupSimplePanel(), BorderLayout.CENTER);
else
getContentPane().add(setupComplexPanel(), BorderLayout.CENTER);
state = !state;
getContentPane().validate();
}
private JPanel setupComplexPanel() {
JPanel contents = new JPanel();
contents.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
for (int x = 0; x<10; x++) {
c.gridx = x;
for (int y = 0; y<10; y++) {
c.gridy = y;
contents.add(new JLabel(x + ", " + y), c);
}
}
return contents;
}
private JPanel setupSimplePanel() {
JPanel contents = new JPanel();
contents.add(new JLabel("Simple view"));
return contents;
}
}
@AndrewThompson A CardLayout может работать, если я поместил представления в отдельные JScrollPanes, но я бы предпочел не хранить все разные виды в памяти. –
Я решил попробовать, и это может сработать - я действительно ожидал получить такое же поведение. CardLayout вполне может быть самым идиоматическим решением. Я, вероятно, поеду с этим, но мне все еще интересно, почему удаление подкомпонентов ускоряет удаление родительского компонента. –
1) Я ввел комментарии в качестве альтернативной стратегии. 2) Nice SSCCE +1 - я вставлял его в вопрос как редактирование. 3) Интригующее наблюдение, но я бы старался использовать лучший макет и перейти к новой проблеме. Надеюсь, вы получите решение. :) –