Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用JToggleButtons、jpanel和JScrollPanes解决这些大小调整问题?_Java_Swing_Jpanel_Jscrollpane_Preferredsize - Fatal编程技术网

Java 如何使用JToggleButtons、jpanel和JScrollPanes解决这些大小调整问题?

Java 如何使用JToggleButtons、jpanel和JScrollPanes解决这些大小调整问题?,java,swing,jpanel,jscrollpane,preferredsize,Java,Swing,Jpanel,Jscrollpane,Preferredsize,我正在尝试开发一种手风琴菜单。有少量(2-12)选项可切换开/关。当切换到on时,将出现一个带有附加设置的JPanel。禁用时,附加设置将不可见 我创建了一个SelectableExpandablePanel类,该类扩展了JPanel,并实现了ActionListener和ComponentListener。该面板包含两件东西-一个JToggleButton和一个子组件(通常是一个JPanel,但我不想限制自己在BoxLayout中执行一个列。选择“切换”按钮后,子对象将可见。取消选择切换时,子

我正在尝试开发一种手风琴菜单。有少量(2-12)选项可切换开/关。当切换到on时,将出现一个带有附加设置的
JPanel
。禁用时,附加设置将不可见

我创建了一个
SelectableExpandablePanel
类,该类扩展了
JPanel
,并实现了
ActionListener
ComponentListener
。该面板包含两件东西-一个
JToggleButton
和一个子
组件
(通常是一个JPanel,但我不想限制自己在
BoxLayout
中执行一个列。选择“切换”按钮后,子对象将可见。取消选择切换时,子对象将隐藏

当我使用这个组件时,我打算将它放在
JScrollPane
内部的
JPanel上,如示例main方法中所示

似乎有两个问题我很难克服:

  • 如果我不指定一个
    JFrame
    大小,它只够每个子对象的宽度,够三个按钮的高度。当我单击按钮时,我希望
    JScrollPane
    能够完成它的工作并生成一个垂直滚动条。这不会发生

  • 我希望切换按钮是包含它们的JPanel的全宽。我认为我在构造函数中所做的加上
    组件侦听器
    可以处理这个问题,但事实并非如此

  • 下面提供的内容编译并具有主方法。如果编译并执行,它将驱动我正在构建的组件,以提供一个测试框架和重现我所说问题的能力

    import javax.swing.BoxLayout;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JToggleButton;
    
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ComponentEvent;
    import java.awt.event.ComponentListener;
    
    public class SelectableExpandablePanel extends JPanel implements
            ActionListener, ComponentListener {
        private JToggleButton titleButton;
        private JComponent childComponent;
    
        public SelectableExpandablePanel(JComponent child) {
            this(child, null, null);
        }
    
        public SelectableExpandablePanel(JComponent child, String title) {
            this(child, title, null);
        }
    
        public SelectableExpandablePanel(JComponent child, String title,
                String tooltip) {
            super();
    
            if (child == null) {
                throw new IllegalArgumentException("Child component cannot be null");
            }
    
            childComponent = child;
    
            titleButton = new JToggleButton();
            titleButton.setText(title);
            titleButton.addActionListener(this);
            titleButton.setPreferredSize(new Dimension(getSize().width, titleButton
                    .getPreferredSize().height));
            titleButton.setToolTipText(tooltip);
    
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            setPreferredSize(new Dimension(childComponent.getPreferredSize().width,
                    titleButton.getPreferredSize().height));
            setSize(new Dimension(childComponent.getPreferredSize().width,
                    titleButton.getPreferredSize().height));
    
            add(titleButton);
    
            this.addComponentListener(this);
        }
    
        public void actionPerformed(ActionEvent e) {
            if (titleButton.isSelected()) {
                add(childComponent);
                setSize(new Dimension(childComponent.getPreferredSize().width,
                        titleButton.getPreferredSize().height
                                + childComponent.getPreferredSize().height));
    
            } else {
                remove(childComponent);
                setSize(new Dimension(childComponent.getPreferredSize().width,
                        titleButton.getPreferredSize().height));
            }
    
            invalidate();
            revalidate();
        }
    
        public void componentHidden(ComponentEvent arg0) {
            // Do nothing
        }
    
        public void componentMoved(ComponentEvent arg0) {
            // Do nothing
        }
    
        public void componentResized(ComponentEvent arg0) {
            titleButton.setSize(this.getWidth(),
                    titleButton.getPreferredSize().height);
        }
    
        public void componentShown(ComponentEvent arg0) {
            // Do nothing
        }
    
        public static void main(String[] args) {
            JScrollPane scrollPane = new JScrollPane();
    
            // These panels simulates a complex, multi-line configuration panel.
            JPanel testPanel = new JPanel();
            testPanel.setLayout(new BoxLayout(testPanel, BoxLayout.Y_AXIS));
            testPanel.add(new JLabel("Test JLabel"));
            testPanel.add(new JLabel("Test JLabel 2"));
            testPanel.add(new JLabel("Test JLabel 3"));
    
            JPanel testPanel2 = new JPanel();
            testPanel2.setLayout(new BoxLayout(testPanel2, BoxLayout.Y_AXIS));
            testPanel2.add(new JLabel("Test JLabel"));
            testPanel2.add(new JLabel("Test JLabel 2"));
            testPanel2.add(new JLabel("Test JLabel 3"));
    
            JPanel testPanel3 = new JPanel();
            testPanel3.setLayout(new BoxLayout(testPanel3, BoxLayout.Y_AXIS));
            testPanel3.add(new JLabel("Test JLabel"));
            testPanel3.add(new JLabel("Test JLabel 2"));
            testPanel3.add(new JLabel("Test JLabel 3"));
    
            // This panel simulates the panel that will contain each of the
            // SelectableExpandablePanels.
            JPanel testHolder = new JPanel();
            testHolder.setLayout(new BoxLayout(testHolder, BoxLayout.Y_AXIS));
            testHolder.add(new SelectableExpandablePanel(testPanel, "Test"));
            testHolder.add(new SelectableExpandablePanel(testPanel2, "Test 2"));
            testHolder.add(new SelectableExpandablePanel(testPanel3, "Test 3"));
    
            // We add the test holder to the scroll pane. The intention is that if
            // the expansion is too big to fit, the holding JFrame won't expand, but
            // the scroll pane will get scroll bars to let the user scroll up and
            // down through the toggle buttons and any enabled items.
            scrollPane.setViewportView(testHolder);
    
            JFrame testFrame = new JFrame("Expandable Panel Test");
            testFrame.getContentPane().add(scrollPane);
            testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            testFrame.pack();
            testFrame.setVisible(true);
        }
    }
    

    不要试图自己管理尺寸:

    //titleButton.setPreferredSize(new Dimension(getSize().width, titleButton.getPreferredSize().height));
     titleButton.setToolTipText(tooltip);
    
     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    //setPreferredSize(new Dimension(childComponent.getPreferredSize().width, titleButton.getPreferredSize().height));
    //setSize(new Dimension(childComponent.getPreferredSize().width, titleButton.getPreferredSize().height));
    
    另外,去掉ActionListener中的
    setSize()
    代码。这将被忽略,因为布局管理器将确定大小

    当面板的首选大小大于滚动窗格的大小时,将显示滚动条。如果硬编码首选尺寸,则默认布局管理器的用途,并且在添加/删除零部件时首选尺寸不会更改


    注:对于类似的内容,我通常使用边界布局。将按钮放在页面开始处,另一个面板放在中间。组件将自动填满可用空间。

    不要试图自己管理尺寸:

    //titleButton.setPreferredSize(new Dimension(getSize().width, titleButton.getPreferredSize().height));
     titleButton.setToolTipText(tooltip);
    
     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    //setPreferredSize(new Dimension(childComponent.getPreferredSize().width, titleButton.getPreferredSize().height));
    //setSize(new Dimension(childComponent.getPreferredSize().width, titleButton.getPreferredSize().height));
    
    另外,去掉ActionListener中的
    setSize()
    代码。这将被忽略,因为布局管理器将确定大小

    当面板的首选大小大于滚动窗格的大小时,将显示滚动条。如果硬编码首选尺寸,则默认布局管理器的用途,并且在添加/删除零部件时首选尺寸不会更改

    注:对于类似的内容,我通常使用边界布局。将按钮放在页面开始处,另一个面板放在中间。组件将自动填充可用空间

  • 删除所有setSize/setPreferredSize调用,让LayoutManager完成它的工作
  • 要允许JButtons填充面板的宽度,可以使用BorderLayout(例如,将按钮添加到中心,将子容器添加到南部,并删除所有这些setSize值,以让LayoutManager处理它)
  • 删除所有setSize/setPreferredSize调用,让LayoutManager完成它的工作
  • 要允许JButtons填充面板的宽度,可以使用BorderLayout(例如,将按钮添加到中心,将子容器添加到南部,并删除所有这些setSize值,以让LayoutManager处理它)
    或者,一切都取决于孩子们是什么、如何、何时(如果是或不是)resizable@mKorbel让我看看那些。快速看,使用setVisible而不是添加或删除可能是更好的选择。我需要深入挖掘滚动窗格问题和宽度问题。使用setVisible而不是添加或删除可能会更好--->在JScrollPane内部无所谓,我的问题是you@mKorbel我不知道你在问什么。子面板可以调整大小,是的。一切取决于JFrames childs(如果是或不是)可以调整大小的内容、方式、时间(您期望什么),然后答案更简单,或者一切取决于JFrames childs(如果是或不是)可以调整大小的内容、方式、时间resizable@mKorbel让我看看那些。快速看,使用setVisible而不是添加或删除可能是更好的选择。我需要深入挖掘滚动窗格问题和宽度问题。使用setVisible而不是添加或删除可能会更好--->在JScrollPane内部无所谓,我的问题是you@mKorbel我不知道你在问什么。子面板可以调整大小,是的。一切都取决于什么、如何、何时(您期望什么)JFrames子面板(如果是或不是)可以调整大小,然后答案是更容易这是完美的。我想。我需要进行更多测试,但这看起来像我需要的功能。不要使用setPreferredSize(),这是布局管理器的工作。唯一的问题是,如果我删除setSize/setPreferredSize,SelectableExpandablePanel的大小只是按钮的宽度。宽度必须是最宽的子组件的宽度,因为我想防止水平滚动。除此之外,一切正常。同意关于setPreferredSize()的通知,但另一种情况是JScrollpane(在他的回答中未提及)这是完美的。我想。我需要进行更多测试,但这看起来像我需要的功能。不要使用setPreferredSize(),这是布局管理器的工作。唯一的问题是,如果我删除setSize/setPreferredSize,SelectableExpandablePanel的大小为o