У меня есть JTree, где некоторые данные, которые должны быть показаны, должны отображаться в JTable. Для этого я создал класс renderer (расширение DefaultTreeCellRenderder) для изменения возвращаемого компонента в зависимости от того, что содержит значение объекта, когда оно первоначально передано в рендеринг.Отображение JTable в JTree ведет себя по-разному с различным внешним видом
Если это таблица, которая будет показана, она содержится в JScrollPane (как показано ниже).
Это работает (в том смысле, что JScrollPane, содержащий JTable, отображается целиком) с помощью Cross Platform Look and Feel, но при использовании System Look and Feel JScrollPane, по-видимому, ограничена высотой листового узла. Есть ли способ изменить это, чтобы он выглядел так же, как кросс-платформенный стиль?
JFrame
public class ExampleJTreeWithJTable extends JFrame {
public ExampleJTreeWithJTable() {
setLayout(new BorderLayout(0, 0));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Example");
root.add(new DefaultMutableTreeNode("TABLE:Column A=Cell 1.1,Cell 2.1,Cell 3.1¬Column B=Cell 1.2,Cell 2.2,Cell 3.2"));
JTree tree = new JTree(root);
tree.setCellRenderer(new ExampleRenderer());
add(tree, BorderLayout.CENTER);
pack();
}
public static void main(String... args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // Using getCrossPlatformLookAndFeelClassName works...
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ExampleJTreeWithJTable window = new ExampleJTreeWithJTable();
window.setLocationRelativeTo(null);
window.setVisible(true);
}
});
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
}
Renderer
public class ExampleRenderer extends DefaultTreeCellRenderer {
private Map<String, JScrollPane> tables = new HashMap<String, JScrollPane>();
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (value.toString().startsWith("TABLE:")) {
c = tables.get(value.toString());
if (c == null) {
JTable table = new JTable(createModel(value.toString()));
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane pane = new JScrollPane(table);
tables.put(value.toString(), pane);
c = tables.get(value.toString());
}
}
return c;
}
private TableModel createModel(String tableData) {
tableData = tableData.substring(6, tableData.length());
DefaultTableModel model = new DefaultTableModel();
String[] colData = tableData.split("¬");
for (String data : colData) {
String[] components = data.split("=");
model.addColumn(components[0], components[1].split(","));
}
return model;
}
}
Примеры выхода
Кросплатформенная выглядеть и чувствовать себя
система Смотри и Feel
Я попытался ручная настройка JScrollPane предпочтительного размера JTable при отсутствии эффекта. Я чувствую, что это связано с тем, как System LAF вычисляет высоту компонента против листового узла, но я не уверен в этом.
Я также попробовал просто показать JTable, а не JScrollPane. В Cross Platform LAF это работает. В System LAF отображается первая строка таблицы.