【问题标题】:Showing a JTable in a JTree behaves differently with different look and feels在 JTree 中显示 JTable 具有不同的外观和感觉
【发布时间】:2015-04-24 20:22:34
【问题描述】:

我有一个 JTree,其中一些要显示的数据应该显示在 JTable 中。为此,我创建了一个渲染器类(扩展 DefaultTreeCellRenderder)来根据最初传递给渲染器时对象值包含的内容来更改返回的渲染组件。

如果是要显示的表格,则它包含在 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 中,它显示表格的第一行。

【问题讨论】:

    标签: java swing jtable jtree


    【解决方案1】:

    我从下面的链接中发现了这一点:

    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());
    

    结果是这样的:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多