创建类似Inspector的东西

时间:2016-08-08 23:59:25

标签: java swing jscrollpane gridbaglayout inspector

我正在为我的程序创建类似于检查器面板的东西,因此我可以在运行时轻松更改某些变量。

当您运行下面的代码时,您应该看到如下内容: inspector screenshot

有些事情困扰着我,我仍然无法使它们正常工作。

  1. 项目与中心垂直对齐...我尝试将锚点设置为北方,但它保持不变。在下面的示例代码中,有一行注释掉了可以解决这个问题:inspector.finish()但是解决方案对我来说似乎有些苛刻。它的工作原理是在面板上添加空的JPanel作为最后一项,作为某种垂直胶水来扩展下部区域并向上推动组件。我不喜欢这样,因为通过这个解决方案,我不能再在运行时向检查员添加更多项目。
  2. 如果您向检查员添加更多项目(您可以通过更改 n 变量来填充检查员的某些测试数据),滚动条将不会显示,并且所有较低的项目都是屏幕外即使它全部包裹在JScrollPane中...我已经尝试了几个黑客来解决这个问题,但没有一个能正常工作。其中一个是将JPAnel的preferredSize设置为一些硬编码尺寸,但我不喜欢这样,因为我不知道面板的确切尺寸。
  3. 当您按下某些微调按钮然后单击组合框(标题为"选择我")时,选项隐藏在按钮后面。这看起来像某种z排序问题。也许这就是摇摆中的错误,不知道。
  4. 当您将窗口垂直调整为较小尺寸时,顶部的项目将开始缩小而不是保持相同的大小。是否有任何选项可以始终将它们设置为恒定高度?
  5. 也许我使用错误的布局管理器,但我不知道选择哪一个。我正在考虑简单的网格布局,但这不允许我做一些事情,比如让一些项目包含一个项目而其他项目包含多个项目,这样他们将始终使用整个宽度" capacity"这一行。

    示例代码:

    import java.awt.*;
    import javax.swing.*;
    
    public class Test {
    
        // Setup test scenario
        public Test() {
    
            // Create window
            JFrame f = new JFrame();
            f.setLayout(new BorderLayout());
            f.setSize(800, 600);
            f.setTitle("Inspector");
            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
            // Create panel which will be used for the inspector
            JPanel p = new JPanel();
            p.setPreferredSize(new Dimension(200, 0));
    
            // Encapsulate it to the scroll panel so it can grow vertically
            JScrollPane sp = new JScrollPane();
            sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
            sp.setViewportView(p);
    
            // Create the inspector inside panel p
            Inspector inspector = new Inspector(p);
    
            // Fill the inspector with some test data
            int n = 3;
            for (int i = 0; i < n; ++i) {
                inspector.addTitle("Title");
                inspector.addButton("push me");
                inspector.addCheckBox("check me");
                inspector.addSpinner("Spin me");
                inspector.addTextField("Edit me", "here");
                inspector.addComboBox("Choose one", new String[]{"A", "B", "C"});
                inspector.addSeparator();
            }
            //inspector.finish();
    
            // The inspector will be on the right side of the window
            f.getContentPane().add(sp, BorderLayout.LINE_END);
    
            // Show the window
            f.setVisible(true);
        }
    
        // Main method
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Test();
                }
            });
        }
    
        // Inspector class itself
        private class Inspector {
    
            private final JPanel panel;
            private final GridBagConstraints constraints;
            private int itemsCount = 0;
    
            public Inspector(JPanel p) {
                panel = p;
                panel.setLayout(new GridBagLayout());
    
                constraints = new GridBagConstraints();
                constraints.fill = GridBagConstraints.HORIZONTAL;
                constraints.weightx = 0.5;
            }
    
            // Adds component which will span across whole row
            private void addComponent(Component component) {
                constraints.gridx = 0;
                constraints.gridwidth = 2;
                constraints.gridy = itemsCount;
    
                panel.add(component, constraints);
    
                itemsCount++;
            }
    
            // Adds descriptive label on the left and component on the right side of the row
            private void addNamedComponent(String description, Component component) {
                constraints.gridx = 0;
                constraints.gridy = itemsCount;
                constraints.gridwidth = 1;
                panel.add(new JLabel(description), constraints);
    
                constraints.gridx = 1;
                constraints.gridy = itemsCount;
                constraints.gridwidth = 1;
                panel.add(component, constraints);
    
                itemsCount++;
            }
    
            public void addSeparator() {
                // (little hacky)
                addComponent(new JPanel());
            }
    
            public void addTitle(String title) {
                addComponent(new JLabel(title));
            }
    
            public void addButton(String actionName) {
                addComponent(new Button(actionName));
            }
    
            public void addCheckBox(String description) {
                addNamedComponent(description, new JCheckBox());
            }
    
            public void addSpinner(String description) {
                addNamedComponent(description, new JSpinner());
            }
    
            public void addTextField(String description, String text) {
                addNamedComponent(description, new JTextField(text));
            }
    
            public void addComboBox(String description, String[] options) {
                JComboBox<String> comboBox = new JComboBox<>();
                ComboBoxModel<String> model = new DefaultComboBoxModel<>(options);
                comboBox.setModel(model);
    
                addNamedComponent(description, comboBox);
            }
    
            public void finish() {
                constraints.gridx = 0;
                constraints.gridy = itemsCount;
                constraints.gridwidth = 2;
                constraints.weighty = 1.0;
    
                panel.add(new JPanel(), constraints);
            }
        }
    }
    

1 个答案:

答案 0 :(得分:1)

您无法向上或向下滚动的原因是因为您将首选大小sp设置为200x0。你需要删除这一行。

p.setPreferredSize(new Dimension(200, 0));

关于一切都在中心而不是在顶部的问题。我希望将p保留为默认FlowLayout,并为每个&#34;部分&#34;它自己的面板,以及面板a GridBagLayout的制作。通过这样做,您可能不再需要addSeparator()

public class Test {

    // Setup test scenario
    public Test() {

        // Create window
        JFrame f = new JFrame();
        f.setLayout(new BorderLayout());
        f.setSize(800, 600);
        f.setTitle("Inspector");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        // Create panel which will be used for the inspector
        JPanel p = new JPanel();

        // Encapsulate it to the scroll panel so it can grow vertically
        JScrollPane sp = new JScrollPane();
        sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        sp.setViewportView(p);

        // Create the inspector inside panel p
        Inspector inspector = new Inspector(p);

        // Fill the inspector with some test data
        int n = 2;
        for (int i = 0; i < n; ++i) {
            inspector.addTitle("Title");
            inspector.addButton("push me");
            inspector.addCheckBox("check me");
            inspector.addSpinner("Spin me");
            inspector.addTextField("Edit me", "here");
            inspector.addComboBox("Choose one", new String[]{"A", "B", "C"});
        }

        // The inspector will be on the right side of the window
        f.getContentPane().add(sp, BorderLayout.LINE_END);

        // Show the window
        f.setVisible(true);
    }

    // Main method
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    // Inspector class itself
    private class Inspector {

        private final JPanel panel;
        private final GridBagConstraints constraints;
        private int itemsCount = 0;

        public Inspector(JPanel p) {
            panel = new JPanel();
            p.add(panel);
            panel.setLayout(new GridBagLayout());

            constraints = new GridBagConstraints();
            constraints.fill = GridBagConstraints.HORIZONTAL;
            constraints.weightx = 1.0;
        }

        // Adds component which will span across whole row
        private void addComponent(Component component) {
            constraints.gridx = 0;
            constraints.gridwidth = 2;
            constraints.gridy = itemsCount;

            panel.add(component, constraints);

            itemsCount++;
        }

        // Adds descriptive label on the left and component on the right side of the row
        private void addNamedComponent(String description, Component component) {
            constraints.gridx = 0;
            constraints.gridy = itemsCount;
            constraints.gridwidth = 1;
            panel.add(new JLabel(description), constraints);

            constraints.gridx = 1;
            constraints.gridy = itemsCount;
            constraints.gridwidth = 1;
            panel.add(component, constraints);

            itemsCount++;
        }

        public void addSeparator() {
            // (little hacky)
            addComponent(new JPanel());
        }

        public void addTitle(String title) {
            addComponent(new JLabel(title));
        }

        public void addButton(String actionName) {
            addComponent(new Button(actionName));
        }

        public void addCheckBox(String description) {
            addNamedComponent(description, new JCheckBox());
        }

        public void addSpinner(String description) {
            addNamedComponent(description, new JSpinner());
        }

        public void addTextField(String description, String text) {
            addNamedComponent(description, new JTextField(text));
        }

        public void addComboBox(String description, String[] options) {
            JComboBox<String> comboBox = new JComboBox<>();
            ComboBoxModel<String> model = new DefaultComboBoxModel<>(options);
            comboBox.setModel(model);

            addNamedComponent(description, comboBox);
        }

        public void finish() {
            constraints.gridx = 0;
            constraints.gridy = itemsCount;
            constraints.gridwidth = 2;
            constraints.weighty = 1.0;

            panel.add(new JPanel(), constraints);
        }
    }
}