简体   繁体   English

Java:JTree 和 BasicTreeUI 参考不显示滚动条

[英]Java : JTree and BasicTreeUI reference doesn't show scrollbars

Working with the JTreeWithScrollbar example, but scaled it back significantly to focus on the issue.使用 JTreeWithScrollbar 示例,但将其显着缩小以专注于该问题。

The original code would have the vertical scrollbars appear as needed.原始代码将根据需要显示垂直滚动条。

Here, there is plenty of space and no scrollbars are needed.这里有足够的空间,不需要滚动条。

在此处输入图像描述

If the panel is moved enough, the scrollbar will appear.如果面板移动得足够多,就会出现滚动条。

在此处输入图像描述

Once the following line of code was added, the scrollbars stopped appearing.一旦添加了以下代码行,滚动条就会停止出现。

        tree.setUI(new MyTreeUI());

Notice no scrollbar.注意没有滚动条。

在此处输入图像描述

If the above line of code is commented out, the vertical scrollbar appears.如果上面这行代码被注释掉,就会出现垂直滚动条。

Checking the documentation for BasicTreeUI and there isn't anything related to showing/hiding scrollbars.检查 BasicTreeUI 的文档,没有任何与显示/隐藏滚动条相关的内容。

2 Questions 2 个问题

1 - When utilizing the BasicTreeUI object, what is required to ensure the scrollbars still function? 1 - 使用 BasicTreeUI 对象时,需要什么来确保滚动条仍然起作用?

2 - Why is it the Horizontal scrollbar never appears even if the line of code is commented out? 2 - 为什么即使注释掉代码行,水平滚动条也不会出现?

import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.Dimension;

public class JTreeWithScrollbar extends JPanel { 
    private JEditorPane htmlPane;
    private JTree tree;

    public JTreeWithScrollbar() 
    {
        //Create the nodes. 
        DefaultMutableTreeNode top =  new DefaultMutableTreeNode("The Java Series");
        DefaultMutableTreeNode book1Node = new DefaultMutableTreeNode("Book 1");
        DefaultMutableTreeNode book2Node = new DefaultMutableTreeNode("Book 2");
        top.add(book1Node);
        top.add(book2Node);     

        tree = new JTree(top);
        tree.setUI(new MyTreeUI());  ///Comment out this line of code and the vertical scrollbar appears.

        JScrollPane treeView = new JScrollPane(tree);

        JScrollPane htmlView = new JScrollPane(htmlPane);

        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane.setTopComponent(treeView);
        splitPane.setBottomComponent(htmlView);

        Dimension minimumSize = new Dimension(100, 50);
        htmlView.setMinimumSize(minimumSize);
        splitPane.setDividerLocation(100); 
        splitPane.setPreferredSize(new Dimension(500, 300));
        add(splitPane);
    }
    
    public static void main(String[] args) 
    {
        //Create and set up the window.
        JFrame frame = new JFrame("TreeDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel jp = new JPanel();
        jp.add(new JTreeWithScrollbar());
        frame.add(jp);


        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }
    
    
    private static class MyTreeUI extends BasicTreeUI 
    {
        public MyTreeUI() 
        {
            super();
        }

        @Override
        protected void updateCachedPreferredSize() {
            treeState.invalidateSizes();
            tree.treeDidChange();
        }
        
    }
}
  1. When utilizing the BasicTreeUI object, what is required to ensure the scrollbars still function?在使用BasicTreeUI对象时,需要什么来确保滚动条仍然有效?

As shown in the minimal example below, BasicTreeUI correctly shows each scroll bar when needed;如下面的最小示例所示, BasicTreeUI在需要时正确显示每个滚动条; resize the frame to see the effect.调整框架大小以查看效果。

  1. Why does the horizontal scrollbar never appear even if the line of code is commented out?为什么即使注释掉了这行代码,水平滚动条也永远不会出现?

After pack() the frame has been resized to adopt the preferred size of it content.pack()之后,框架已调整大小以采用其内容的首选大小。 Making the frame slightly smaller illustrates the effect.使框架稍小一点可以说明效果。 Your example adds the tree to a JPanel having a default FlowLayout which ignores preferred sizes;您的示例将树添加到具有忽略首选大小的默认FlowLayoutJPanel the example below adds the tree to the center of the frame's default BorderLayout which responds to preferred sizes.下面的示例将树添加到框架的默认BorderLayout的中心,它响应首选尺寸。

  1. I am assuming the updateCachedPreferredSize() must be doing other stuff behind the scenes…我假设updateCachedPreferredSize()必须在幕后做其他事情......

Exactly.确切地。 Each invocation of updateCachedPreferredSize() updates the component's preferred size to reflect any change in state (resize, expand, etc. );每次调用updateCachedPreferredSize()都会更新组件的首选大小以反映状态的任何变化(调整大小、展开); when the preferred size exceeds the viewport size, the scroll bars appear.当首选大小超过视口大小时,会出现滚动条。 As you observed , invoking super.updateCachedPreferredSize() allows normal operation, and any further customization must preserve that functionality.正如您所观察到的,调用super.updateCachedPreferredSize()允许正常操作,并且任何进一步的自定义都必须保留该功能。

In addition,此外,

  • Expand rows as need like this .这样根据需要展开行。

  • Construct and manipulate Swing GUI objects only on the event dispatch thread .仅在事件调度线程上构造和操作 Swing GUI 对象。

  • Don't use setSize() when you really mean to override getPreferredSize() or illustrates a resize effect;当你真的想覆盖getPreferredSize()或说明调整大小的效果时,不要使用setSize() more here .更多在这里

树

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.plaf.basic.BasicTreeUI;

public class JTreeWithScrollbar {

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            //Create and set up the window.
            JFrame frame = new JFrame("TreeDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            JTree tree = new JTree(); //default model
            for (int i = 0; i < tree.getRowCount(); i++) {
                tree.expandRow(i);
            }
            tree.setUI(new MyTreeUI());
            frame.add(new JScrollPane(tree));

            //Display the window.
            frame.pack();
            frame.setSize(frame.getWidth() - 10, frame.getHeight() - 100);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

    private static class MyTreeUI extends BasicTreeUI {
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM