【问题标题】:java expandable JDialogjava可扩展JDialog
【发布时间】:2014-11-11 23:56:06
【问题描述】:

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

我通过调用setPreferredSize()pack() 实现了这一点,但这不是很优雅。一个“优雅”的解决方案是将第二个面板设置为以某种方式为空,因此当切换状态处于“收回”时被 pack() 忽略。

很抱歉,我无法为您提供代码(那东西大约有 700 个谎言),但这就像我在 JDialog 中所说的基本上两个 JPanel。

这里有一些图片:

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

【问题讨论】:

  • 您可以使用CardLayout(用于展开状态)并调用pack,或者您可以添加/删除设置面板并调用pack...
  • 你的疯狂程序员!很高兴再次见到你 xD 你能给我一些关于布局的基本信息吗?我阅读了有关 oracle 的教程,但我仍然不是 100% 我实际在做什么。由于某种原因 pack() 忽略了两个面板 atm。什么可能导致这种情况?以及哪种布局最适合这种情况(彼此下方只有两个面板)。
  • - 是的,CardLayout 想要将容器的大小调整为最大的子组件,无论可见什么:P - 猜你必须手动完成
  • "remove" 是个不错的电话!这很好用!现在还有两个问题: 1. 除非我在两个面板上都设置了 setPreferredSize,否则 pack() 会忽略它们。 2. 我的面板周围没有边距,所以感觉非常聚集。添加一个 emptyBorder 似乎没有帮助。是因为我使用了 BorderLayout 吗?
  • 组件的大小应该由布局管理器决定,所以不需要调用setPreferredSize。在不知道涉及哪些布局管理器的情况下,很难诊断“集群”问题,但我会说问题出在电话 setPreferredSize - 请参阅更新的答案,那里没有 setPreferredSize 电话,它工作得很好......跨度>

标签: java swing jdialog


【解决方案1】:

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

另一种解决方案是让组件可见/不可见,但您需要找到一个布局管理器,它实际上会将不可见的组件视为不存在 (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);
            }

        }

    }

}

【讨论】:

  • 这看起来很有希望。一旦我设法将它实现到我的代码中,我将立即标记它。非常感谢!
  • 好的。这行得通!谢谢你。 pack() 的问题是我的面板有一个空布局。现在我删除了一切正常。除了我的布局完全坏了。您认为哪个 LayoutManager 最好/最容易重新创建我的 null 布局?
  • 我怀疑一个布局管理器会完成整个工作,但我会使用一系列容器,可能使用 GridBagLayout,但这只是我 ;)
  • 使用 GridBagLayout 我的代码长度增加了一倍,看起来像废话 :( 我真的在考虑切换回空布局.. 我知道,我知道,良好的编程习惯和东西.. 但是难道不应该让代码更简单更好..?
  • 您可以切换回空布局,但您会失去 api 提供的所有好处(如打包和自动调整大小)。您可以编写自己的辞职代码,但实际情况是,您只会复制已经存在的内容。您还将失去跨平台支持,因为布局考虑了不同平台使用的渲染技术的差异,这会改变组件的首选大小...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
相关资源
最近更新 更多