java可扩展JDialog

java可扩展JDialog,java,swing,jdialog,Java,Swing,Jdialog,对于我的应用程序,我有一个JDialog,其中包含一个JPanel,带有一些基本的JTextFields和JButtons。这个想法是有一个按钮,可以展开JDialog,显示第二个JPanel,其中包含一些“高级”设置 我通过调用setPreferredSize()和pack()实现了这一点,但这并不十分优雅。一个“优雅”的解决方案是将第二个面板设置为null,因此当切换状态为“收回”时,pack()会忽略它 很抱歉,我不能向您提供代码(这大约是700个谎言),但它就像我说的,基本上是JDial

对于我的应用程序,我有一个
JDialog
,其中包含一个
JPanel
,带有一些基本的
JTextFields
JButtons
。这个想法是有一个按钮,可以展开
JDialog
,显示第二个
JPanel
,其中包含一些“高级”设置

我通过调用
setPreferredSize()
pack()
实现了这一点,但这并不十分优雅。一个“优雅”的解决方案是将第二个面板设置为null,因此当切换状态为“收回”时,pack()会忽略它

很抱歉,我不能向您提供代码(这大约是700个谎言),但它就像我说的,基本上是JDialog中的两个jpanel

以下是一些图片:


问题:有没有一个技巧可以让这个扩展过程继续进行,而不必为扩展/正常状态设置固定的尺寸。

可能有几种方法可以做到这一点,例如,您可以根据需要简单地添加和删除底部面板。如果可以,我希望避免这种情况,因为这会使管理布局更加困难

另一个解决方案是简单地使组件可见/不可见,但您需要找到一个布局管理器,它将实际处理不可见组件,就像它不存在一样(
0x0
)-是的,我在进行测试时遇到了一些问题

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class FlipDialog {

    public static void main(String[] args) {
        new FlipDialog();
    }

    public FlipDialog() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JButton flip;
        private JPanel bottom;

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(8, 8, 8, 8);
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            JPanel top = new JPanel();
            flip = new JButton("+");
            top.add(flip);
            add(top, gbc);

            bottom = new JPanel();
            bottom.add(new JLabel("Boo"));
            bottom.setVisible(false);

            add(bottom, gbc);

            flip.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    bottom.setVisible(!bottom.isVisible());
                    if (bottom.isVisible()) {
                        flip.setText("-");
                    } else {
                        flip.setText("+");
                    }
                    revalidate();
                    Window window = SwingUtilities.windowForComponent(bottom);
                    window.pack();
                }
            });
        }

    }

}

需要注意的是,调用
revalidate
可能与打包窗口无关

使用布局示例更新

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractSpinnerModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test100 {

    public static void main(String[] args) {
        new Test100();
    }

    public Test100() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new SearchPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class SearchPane extends JPanel {

        private ObjectsPane objectsPane;
        private AdvanceSettingsPane advanceSettingsPane;

        public SearchPane() {
            setBorder(new EmptyBorder(8, 8, 8, 8));
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;

            objectsPane = new ObjectsPane();
            add(objectsPane, gbc);

            gbc.gridy++;
            gbc.weighty = 0;

            advanceSettingsPane = new AdvanceSettingsPane();
            advanceSettingsPane.setVisible(false);
            add(advanceSettingsPane, gbc);

            objectsPane.addExpandCollapseListener(new ChangeListener() {

                @Override
                public void stateChanged(ChangeEvent e) {
                    System.out.println(objectsPane.isExpanded());
                    advanceSettingsPane.setVisible(objectsPane.isExpanded());
                    Window window = SwingUtilities.windowForComponent(SearchPane.this);
                    window.pack();
                }
            });
        }

        public class ObjectsPane extends JPanel {

            private JSpinner findField;
            private JTextField replaceField;

            private JButton expandButton;
            private JButton replaceButton;
            private JButton replaceAllButton;

            private boolean expanded = false;

            public ObjectsPane() {
                setLayout(new GridBagLayout());

                findField = new JSpinner(new AbstractSpinnerModel() {

                    @Override
                    public Object getValue() {
                        return "";
                    }

                    @Override
                    public void setValue(Object value) {
                    }

                    @Override
                    public Object getNextValue() {
                        return "";
                    }

                    @Override
                    public Object getPreviousValue() {
                        return "";
                    }
                });
                replaceField = new JTextField(10);

                replaceButton = new JButton("Replace");
                replaceAllButton = new JButton("Replace All");
                expandButton = new JButton("+");

                GridBagConstraints gbc = new GridBagConstraints();
                gbc.insets = new Insets(4, 4, 4, 4);
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                gbc.weightx = 1;
                gbc.anchor = GridBagConstraints.WEST;
                add(new JLabel("Objects found:"), gbc);

                gbc.gridx = 0;
                gbc.gridy = 1;
                gbc.gridwidth = 1;
                gbc.weightx = 0;
                add(new JLabel("Find:"), gbc);

                gbc.gridy = 2;
                add(new JLabel("Replace:"), gbc);

                gbc.gridx = 1;
                gbc.gridy = 1;
                gbc.weightx = 1;
                gbc.fill = GridBagConstraints.HORIZONTAL;
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                add(findField, gbc);

                gbc.gridy = 2;
                add(replaceField, gbc);

                gbc.anchor = GridBagConstraints.WEST;
                gbc.gridwidth = 1;
                gbc.weightx = 0;
                gbc.gridx = 0;
                gbc.gridy = 3;
                gbc.fill = GridBagConstraints.NONE;
                add(expandButton, gbc);

                JPanel pnlButtons = new JPanel(new GridLayout(1, 2));
                pnlButtons.add(replaceButton);
                pnlButtons.add(replaceAllButton);

                gbc.gridx = 1;
                gbc.gridy = 3;
                gbc.fill = GridBagConstraints.HORIZONTAL;
                gbc.weightx = 1;
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                add(pnlButtons, gbc);

                expandButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        expanded = !expanded;
                        if (expanded) {
                            expandButton.setText("-");
                        } else {
                            expandButton.setText("+");
                        }
                        fireStateChanged();
                    }
                });
            }

            public boolean isExpanded() {
                return expanded;
            }

            public void addExpandCollapseListener(ChangeListener listener) {
                listenerList.add(ChangeListener.class, listener);
            }

            public void removeExpandCollapseListener(ChangeListener listener) {
                listenerList.remove(ChangeListener.class, listener);
            }

            protected void fireStateChanged() {
                ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
                if (listeners.length > 0) {

                    ChangeEvent evt = new ChangeEvent(this);
                    for (ChangeListener listener : listeners) {
                        listener.stateChanged(evt);
                    }

                }
            }

        }

        public class AdvanceSettingsPane extends JPanel {

            public AdvanceSettingsPane() {
                setBorder(new TitledBorder("Advance Settings"));
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
//              gbc.gridy = 0;
                gbc.weightx = 1;
                gbc.anchor = GridBagConstraints.WEST;
                gbc.gridwidth = GridBagConstraints.REMAINDER;

                add(new JCheckBox("Live Update"), gbc);
                add(new JCheckBox("Word search"), gbc);
                add(new JCheckBox("Ignore Case"), gbc);
            }

        }

    }

}


您可以使用
CardLayout
(用于扩展状态)并调用
pack
,或者您可以添加/删除设置面板并调用
pack
…程序员!很高兴再次见到你xD你能给我一些关于布局的基本信息吗。我读了关于oracle的教程,但我仍然不是100%了解我实际在做什么。出于某种原因,pack()会忽略这两个面板。这是什么原因造成的?以及哪种布局最适合这种情况(只有两个面板相互下方)。-是的,
CardLayout
希望将容器大小调整为最大的子组件,而不管可见的是什么:P-我猜您必须手动执行“删除”是一个很好的调用!这太棒了!现在还有两个问题:1。除非我在两个面板上都设置了setPreferredSize,否则pack()将忽略它们。2.我在面板周围没有空白,所以感觉非常密集。添加一个空订单似乎没有帮助。是因为我使用了BorderLayout吗?组件的大小应由布局管理器确定,因此不需要调用
setPreferredSize
。如果不知道布局管理器涉及到什么,很难诊断“集群”问题,但我要说的是,问题在于调用
setPreferredSize
——请参阅更新的答案,没有
setPreferredSize
调用,它工作得很好……这看起来很有希望。一旦我在代码中实现了这一点,我就会对其进行标记。非常感谢你!好啊这管用!非常感谢。pack()的问题是我的面板的布局为空。现在我把一切都搞定了。只是我的布局完全被破坏了。您认为哪种布局管理器最适合/最容易重新创建我的空布局?我怀疑一个布局管理器可以完成全部工作,但我会使用一系列容器,可能使用
GridBagLayout
,但这只是我;)使用GridBagLayout,我的代码长度增加了一倍,看起来像垃圾:(我真的在考虑切换回null布局..我知道,我知道,好的编程习惯和东西..但它不应该让代码变得更简单更好..你可以切换回null布局,但你失去了api提供的所有好处(如打包和自动调整大小)。您可以编写自己的代码,但实际情况是,您只能复制已有的代码。您还将失去跨平台支持,因为布局考虑了不同平台使用的渲染技术的差异,这会改变组件的首选大小。。。