Как лениво инициализировать такую панель?
Обратите внимание, что этот вопрос не касается SwingWorker. Для простоты он отсутствует в моем MRE.
Также обратите внимание, что хотя мой MRE включает в себя JTabbedPane (который запускает ChangeEvent, который вы можете прослушивать), вопрос касается JComponent в более широком смысле. Панель, которая должна иметь возможность ленивой инициализации, в любом случае может не знать, что она находится внутри JTabbedPane (или может использоваться в разных контекстах, не обязательно с участием JTabbedPane).
MRE:
Код: Выделить всё
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
public class TabbedPaneDemo {
private static JTable table;
public static void main(String[] args) {
Container mainPanel = createMainPanel();
JFrame frame = new JFrame("Tabbed Pane demo");
frame.setContentPane(mainPanel);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static JComponent createMainPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(createTabbedPane());
return panel;
}
private static JTabbedPane createTabbedPane() {
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Tab A", createPanelA());
tabbedPane.addTab("Tab B", createPanelB());
tabbedPane.setPreferredSize(new Dimension(250, 150));
return tabbedPane;
}
private static Component createPanelA() {
JPanel panel = new JPanel();
return panel;
}
private static Component createPanelB() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(createScroller());
return panel;
}
private static JScrollPane createScroller() {
JScrollPane scroller = new JScrollPane(createTable());
return scroller;
}
private static JTable createTable() {
table = new JTable();
table.setModel(createTableModel());
// ATTEMPT 1. Doesn't work since "showing" is not bound
table.addPropertyChangeListener("showing", e -> loadTableData());
// ATTEMPT 2. Doesn't work since componentShown() actually listens to "visible" which doesn't change
// table.addComponentListener(new ComponentAdapter() {
// @Override
// public void componentShown(ComponentEvent e) {
// loadTableData();
// }
// });
// ATTEMPT 3. Invoked too many times
// table.addComponentListener(new ComponentAdapter() {
// @Override
// public void componentResized(ComponentEvent e) {
// loadTableData();
// }
// });
return table;
}
private static TableModel createTableModel() {
DefaultTableModel model = new DefaultTableModel(new Object[]{"Id", "Name"}, 0);
return model;
}
private static void loadTableData() {
System.out.println("Loading table data..."); // must be called only once on first show
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(new Object[]{"1", "Maria"});
model.addRow(new Object[]{"2", "Patricia"});
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... ent-lazily