在JTree中显示JTable的行为与外观不同 [英] Showing a JTable in a JTree behaves differently with different look and feels

查看:95
本文介绍了在JTree中显示JTable的行为与外观不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JTree where some of the data to be shown should be shown in a JTable. So to do this, I created a renderer class (extending DefaultTreeCellRenderder) to change the rendered component returned depending on what the object value contains when initially passed into the renderer.

如果要显示的表,则包含在JScrollPane中(如下面的代码所示).

If it is a table to be shown, it is contained within a JScrollPane (as the below code shows).

这与跨平台外观一起工作(因为完整显示了包含JTable的JScrollPane),但是在使用系统外观时,JScrollPane似乎受限于叶节点的高度.有没有办法改变它,使其表现得像跨平台外观?

This works (in that the JScrollPane containing the JTable is shown in its entirety) with the Cross Platform Look and Feel but when using the System Look and Feel, the JScrollPane seems to be constrained to the height of the leaf node. Is there a way of changing this so it acts like the Cross Platform look and feel?

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如何计算组件相对于叶节点的高度有关,但是我不确定在这里.

I've tried manually setting the JScrollPane to the preferred size of the JTable with no effect. I have a feeling it is to do with how the System LAF calculates the height of the component against the leaf node but I am not certain here.

我也尝试过简单地显示JTable而不是JScrollPane.在跨平台LAF中,这有效.在系统LAF中,它显示表的第一行.

I have also tried simply showing the JTable rather than the JScrollPane. In the Cross Platform LAF, this works. In the System LAF, it shows the first row of the table.

推荐答案

我从以下链接中得出了答案:

I figured this out from the below link:

https://www .daniweb.com/software-development/java/threads/386037/different-height-of-jtree-nodes

本质上,所需要做的就是将行高设置为0,以使叶节点高度可变,这取决于要渲染的组件,而不是固定的(我认为)默认值.

In essence, all that is needed to do is set the row height to 0 to make the leaf node height variable, depending on the component being rendered as opposed to a fixed (I presume) default value.

因此,代码如下所示:

JTree tree = new JTree(root);
tree.setRowHeight(0);
tree.setCellRenderer(new ExampleRenderer());

结果是这样的:

这篇关于在JTree中显示JTable的行为与外观不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆