在 JTree 中显示 JTable 的行为不同,外观和感觉也不同
Showing a JTable in a JTree behaves differently with different look and feels
我有一个 JTree,其中一些要显示的数据应该显示在 JTable 中。因此,为此,我创建了一个渲染器 class(扩展 DefaultTreeCellRenderder)以根据最初传递到渲染器时对象值包含的内容更改返回的渲染组件。
如果要显示的是 table,则它包含在 JScrollPane 中(如以下代码所示)。
这适用于跨平台外观(因为包含 JTable 的 JScrollPane 完整显示),但在使用系统外观时,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();
}
}
}
渲染器
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;
}
}
输出示例
跨平台外观
系统外观
我尝试手动将 JScrollPane 设置为 JTable 的首选大小,但没有任何效果。我觉得这与系统 LAF 如何计算组件相对于叶节点的高度有关,但我不确定。
我也试过只显示 JTable 而不是 JScrollPane。在跨平台 LAF 中,这是有效的。在系统 LAF 中,它显示 table.
的第一行
我从下面算出来的 link:
https://www.daniweb.com/software-development/java/threads/386037/different-height-of-jtree-nodes
本质上,所有需要做的就是将行高设置为 0 以使叶节点高度可变,这取决于正在呈现的组件而不是固定的(我假设)默认值。
因此,代码将如下所示:
JTree tree = new JTree(root);
tree.setRowHeight(0);
tree.setCellRenderer(new ExampleRenderer());
结果是这样的:
我有一个 JTree,其中一些要显示的数据应该显示在 JTable 中。因此,为此,我创建了一个渲染器 class(扩展 DefaultTreeCellRenderder)以根据最初传递到渲染器时对象值包含的内容更改返回的渲染组件。
如果要显示的是 table,则它包含在 JScrollPane 中(如以下代码所示)。
这适用于跨平台外观(因为包含 JTable 的 JScrollPane 完整显示),但在使用系统外观时,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();
}
}
}
渲染器
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;
}
}
输出示例
跨平台外观
系统外观
我尝试手动将 JScrollPane 设置为 JTable 的首选大小,但没有任何效果。我觉得这与系统 LAF 如何计算组件相对于叶节点的高度有关,但我不确定。
我也试过只显示 JTable 而不是 JScrollPane。在跨平台 LAF 中,这是有效的。在系统 LAF 中,它显示 table.
的第一行我从下面算出来的 link:
https://www.daniweb.com/software-development/java/threads/386037/different-height-of-jtree-nodes
本质上,所有需要做的就是将行高设置为 0 以使叶节点高度可变,这取决于正在呈现的组件而不是固定的(我假设)默认值。
因此,代码将如下所示:
JTree tree = new JTree(root);
tree.setRowHeight(0);
tree.setCellRenderer(new ExampleRenderer());
结果是这样的: