Инициализация неотображаемого JComponent ленивоJAVA

Программисты JAVA общаются здесь
Anonymous
Инициализация неотображаемого JComponent лениво

Сообщение Anonymous »

Предположим, у вас есть JTabbedPane, содержимое вкладок которого заполняется дорого (например, загружается из базы данных).
Как лениво инициализировать такую ​​панель?
Обратите внимание, что этот вопрос не касается 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"});
}
}
Java 8.


Подробнее здесь: https://stackoverflow.com/questions/798 ... ent-lazily

Вернуться в «JAVA»