Java网格布局自动构造

Java网格布局自动构造,java,swing,user-interface,layout,gridbaglayout,Java,Swing,User Interface,Layout,Gridbaglayout,我使用GridBagLayout和GridBagConstraints设计了一个GUI。它包含数量可变的行,每个行具有几个可能的列布局中的一个。为了测试代码,我用不同颜色的面板组成了GUI,这些面板演示了每行和每列中所有单元格的位置和大小调整行为。这个测试GUI工作得很好,但是现在我需要自动化它的构建。具体来说,我需要行是三种不同类型中的一种。如果运行下面的代码并查看生成的GUI,可以看到行1是一种类型,行2、6和7是另一种类型,行3、4和5是第三种类型。我需要将这三种类型的行分别封装在自己的类

我使用GridBagLayout和GridBagConstraints设计了一个GUI。它包含数量可变的行,每个行具有几个可能的列布局中的一个。为了测试代码,我用不同颜色的面板组成了GUI,这些面板演示了每行和每列中所有单元格的位置和大小调整行为。这个测试GUI工作得很好,但是现在我需要自动化它的构建。具体来说,我需要行是三种不同类型中的一种。如果运行下面的代码并查看生成的GUI,可以看到行1是一种类型,行2、6和7是另一种类型,行3、4和5是第三种类型。我需要将这三种类型的行分别封装在自己的类中。更重要的是,我需要我的代码能够创建第三种类型的可变行数(如示例中的第3、4和5行所示)。(这适用于数据分析软件。面板将加载数据视图和用于操作数据视图的工具。)

当我试图将行封装到它们自己的类中时,GUI看起来就不再像它应该的样子了。下面的测试代码生成一个GUI布局。有人能告诉我如何修改这个代码,使其具有上面第一段中描述的功能吗

您可以将我下面的测试代码粘贴到IDE中,让它立即工作。测试代码位于两个单独的文件中,如下所示:

GridBagLayoutDemo.java的代码是:

import java.awt.*;
import javax.swing.JFrame;

public class GridBagLayoutDemo {
    final static boolean RIGHT_TO_LEFT = false;

    public static void addComponentsToPane(Container pane) {
        if (RIGHT_TO_LEFT) {pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);}
        pane.setLayout(new GridBagLayout());

// top row (fill, gridx, gridy, gridwidth 1, weightx 0, weighty 0, ipady 0)
        TestPanel panelr1c1 = new TestPanel(Color.black);
        GridBagConstraints constraint_r1c1 = getGridBagConstraints(GridBagConstraints.NONE,0,0,1,0,0,0);
        pane.add(panelr1c1,constraint_r1c1);

        TestPanel panelr1c2 = new TestPanel(Color.blue);
        GridBagConstraints constraint_r1c2 = getGridBagConstraints(GridBagConstraints.HORIZONTAL,1,0,1,0.8,0,0);
        pane.add(panelr1c2,constraint_r1c2);

        TestPanel panelr1c2a = new TestPanel(Color.green);
        GridBagConstraints constraint_r1c2a = getGridBagConstraints(GridBagConstraints.HORIZONTAL,2,0,1,0.8,0,0);
        pane.add(panelr1c2a,constraint_r1c2a);

        TestPanel panelr1c3 = new TestPanel(Color.red);
        GridBagConstraints constraint_r1c3 = getGridBagConstraints(GridBagConstraints.NONE,3,0,1,0,0,0);
        pane.add(panelr1c3,constraint_r1c3);

        TestPanel panelr1c4 = new TestPanel(Color.blue);
        GridBagConstraints constraint_r1c4 = getGridBagConstraints(GridBagConstraints.NONE,4,0,1,0,0,0);
        pane.add(panelr1c4,constraint_r1c4);

// second row (fill, gridx, gridy, gridwidth 1, weightx 0, weighty 0, ipady 0)
        TestPanel panelr2c1 = new TestPanel(Color.magenta);
        GridBagConstraints constraint_r2c1 = getGridBagConstraints(GridBagConstraints.NONE,0,1,1,0,0,0);
        pane.add(panelr2c1,constraint_r2c1);

        TestPanel panelr2c2 = new TestPanel(Color.pink);
        GridBagConstraints constraint_r2c2 = getGridBagConstraints(GridBagConstraints.HORIZONTAL,1,1,2,1.0,0,0);
        pane.add(panelr2c2,constraint_r2c2);

        TestPanel panelr2c3 = new TestPanel(Color.black);
        GridBagConstraints constraint_r2c3 = getGridBagConstraints(GridBagConstraints.NONE,3,1,1,0,0,0);
        pane.add(panelr2c3,constraint_r2c3);

        TestPanel panelr2c4 = new TestPanel(Color.pink);
        GridBagConstraints constraint_r2c4 = getGridBagConstraints(GridBagConstraints.NONE,4,1,1,0,0,0);
        pane.add(panelr2c4,constraint_r2c4);

// third row (fill, gridx, gridy, gridwidth 1, weightx 0, weighty 0, ipady 0)
        TestPanel panelr3c1 = new TestPanel(Color.gray);
        GridBagConstraints constraint_r3c1 = getGridBagConstraints(GridBagConstraints.VERTICAL,0,2,1,0,0.5,40);
        pane.add(panelr3c1,constraint_r3c1);

        TestPanel panelr3c2 = new TestPanel(Color.orange);
        GridBagConstraints constraint_r3c2 = getGridBagConstraints(GridBagConstraints.BOTH,1,2,2,1.0,0.5,40);
        pane.add(panelr3c2,constraint_r3c2);

        TestPanel panelr3c3 = new TestPanel(Color.red);
        GridBagConstraints constraint_r3c3 = getGridBagConstraints(GridBagConstraints.VERTICAL,3,2,1,0,0.5,40);
        pane.add(panelr3c3,constraint_r3c3);

        TestPanel panelr3c4 = new TestPanel(Color.orange);
        GridBagConstraints constraint_r3c4 = getGridBagConstraints(GridBagConstraints.VERTICAL,4,2,1,0,0.5,40);
        pane.add(panelr3c4,constraint_r3c4);

// fourth row (fill, gridx, gridy, gridwidth 1, weightx 0, weighty 0, ipady 0)
        TestPanel panelr4c1 = new TestPanel(Color.black);
        GridBagConstraints constraint_r4c1 = getGridBagConstraints(GridBagConstraints.VERTICAL,0,3,1,0,0.5,40);
        pane.add(panelr4c1,constraint_r4c1);

        TestPanel panelr4c2 = new TestPanel(Color.white);
        GridBagConstraints constraint_r4c2 = getGridBagConstraints(GridBagConstraints.BOTH,1,3,2,1.0,0.5,40);
        pane.add(panelr4c2,constraint_r4c2);

        TestPanel panelr4c3 = new TestPanel(Color.green);
        GridBagConstraints constraint_r4c3 = getGridBagConstraints(GridBagConstraints.VERTICAL,3,3,1,0,0.5,40);
        pane.add(panelr4c3,constraint_r4c3);

        TestPanel panelr4c4 = new TestPanel(Color.blue);
        GridBagConstraints constraint_r4c4 = getGridBagConstraints(GridBagConstraints.VERTICAL,4,3,1,0,0.5,40);
        pane.add(panelr4c4,constraint_r4c4);

// fifth row (fill, gridx, gridy, gridwidth 1, weightx 0, weighty 0, ipady 0)
        TestPanel panelr5c1 = new TestPanel(Color.darkGray);
        GridBagConstraints constraint_r5c1 = getGridBagConstraints(GridBagConstraints.VERTICAL,0,4,1,0,0.5,40);
        pane.add(panelr5c1,constraint_r5c1);

        TestPanel panelr5c2 = new TestPanel(Color.yellow);
        GridBagConstraints constraint_r5c2 = getGridBagConstraints(GridBagConstraints.BOTH,1,4,2,1.0,0.5,40);
        pane.add(panelr5c2,constraint_r5c2);

        TestPanel panelr5c3 = new TestPanel(Color.white);
        GridBagConstraints constraint_r5c3 = getGridBagConstraints(GridBagConstraints.VERTICAL,3,4,1,0,0.5,40);
        pane.add(panelr5c3,constraint_r5c3);

        TestPanel panelr5c4 = new TestPanel(Color.orange);
        GridBagConstraints constraint_r5c4 = getGridBagConstraints(GridBagConstraints.VERTICAL,4,4,1,0,0.5,40);
        pane.add(panelr5c4,constraint_r5c4);

// sixth row (fill, gridx, gridy, gridwidth 1, weightx 0, weighty 0, ipady 0)
        TestPanel panelr6c1 = new TestPanel(Color.green);
        GridBagConstraints constraint_r6c1 = getGridBagConstraints(GridBagConstraints.NONE,0,5,1,0,0,0);
        pane.add(panelr6c1,constraint_r6c1);

        TestPanel panelr6c2 = new TestPanel(Color.blue);
        GridBagConstraints constraint_r6c2 = getGridBagConstraints(GridBagConstraints.HORIZONTAL,1,5,2,1.0,0,0);
        pane.add(panelr6c2,constraint_r6c2);

        TestPanel panelr6c3 = new TestPanel(Color.red);
        GridBagConstraints constraint_r6c3 = getGridBagConstraints(GridBagConstraints.NONE,3,5,1,0,0,0);
        pane.add(panelr6c3,constraint_r6c3);

        TestPanel panelr6c4 = new TestPanel(Color.black);
        GridBagConstraints constraint_r6c4 = getGridBagConstraints(GridBagConstraints.NONE,4,5,1,0,0,0);
        pane.add(panelr6c4,constraint_r6c4);

// seventh row (fill, gridx, gridy, gridwidth 1, weightx 0, weighty 0, ipady 0)
        TestPanel panelr7c1 = new TestPanel(Color.darkGray);
        GridBagConstraints constraint_r7c1 = getGridBagConstraints(GridBagConstraints.NONE,0,6,1,0,0,0);
        pane.add(panelr7c1,constraint_r7c1);

        TestPanel panelr7c2 = new TestPanel(Color.white);
        GridBagConstraints constraint_r7c2 = getGridBagConstraints(GridBagConstraints.HORIZONTAL,1,6,2,1.0,0,0);
        pane.add(panelr7c2,constraint_r7c2);

        TestPanel panelr7c3 = new TestPanel(Color.yellow);
        GridBagConstraints constraint_r7c3 = getGridBagConstraints(GridBagConstraints.NONE,3,6,1,0,0,0);
        pane.add(panelr7c3,constraint_r7c3);

        TestPanel panelr7c4 = new TestPanel(Color.green);
        GridBagConstraints constraint_r7c4 = getGridBagConstraints(GridBagConstraints.NONE,4,6,1,0,0,0);
        pane.add(panelr7c4,constraint_r7c4);
    }

    // Create the GUI and show it.  For thread safety, this method should be invoked from the event-dispatching thread.
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("GridBagConstraint Practice");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Set up the content pane.
        addComponentsToPane(frame.getContentPane());
        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread: creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {public void run() {createAndShowGUI();}});
    }
    private static GridBagConstraints getGridBagConstraints(int fill, int gridx, int gridy, int gridwidth, double weightx, double weighty, int ipady){
        GridBagConstraints myGridBagConstraints = new GridBagConstraints();
          myGridBagConstraints.fill=fill;
        myGridBagConstraints.gridx=gridx;
        myGridBagConstraints.gridy=gridy;
        myGridBagConstraints.gridwidth=gridwidth;
        myGridBagConstraints.weightx=weightx;
        myGridBagConstraints.weighty=weighty;
        myGridBagConstraints.ipady=ipady;
        return myGridBagConstraints;
    }
}
TestPanel.java的代码是:

import java.awt.Color;
import javax.swing.JPanel;

public class TestPanel extends JPanel {
    public TestPanel (Color myColor){this.setBackground(myColor);}
}

Swing布局的第1条规则:无论您做什么,都不要使用GridBagLayout。1998年的情况很好。它的设计是有问题的,它是有车的,而且它还没有进化。代码极其冗长、难以编写、难以理解和维护

我推荐,这是我见过的最通用、最直观的布局管理器。看看MigLayout网站上的快速入门指南,它比GridBagLayout简单得多,功能更强大。以下是您在MigLayout中的示例,我已经向您展示了如何重构行类型:

import net.miginfocom.swing.MigLayout;
import java.awt.*;
import javax.swing.*;

public class GridBagLayoutDemo {
    final static boolean RIGHT_TO_LEFT = false;

    public static void addComponentsToPane(Container pane) {
        if (RIGHT_TO_LEFT) {
            pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        }
        pane.setLayout(new MigLayout("insets 0, gap 0, wrap", "[][fill, grow][fill, grow][][]", "[fill]"));

        addType1(pane, Color.BLACK, Color.BLUE, Color.GREEN, Color.RED, Color.BLUE);
        addType2(pane, Color.MAGENTA, Color.PINK, Color.BLACK, Color.PINK);
        addType3(pane, Color.GRAY, Color.ORANGE, Color.RED, Color.ORANGE);
        addType3(pane, Color.BLACK, Color.WHITE, Color.GREEN, Color.BLUE);
        addType3(pane, Color.DARK_GRAY, Color.YELLOW, Color.WHITE, Color.ORANGE);
        addType2(pane, Color.GREEN, Color.BLUE, Color.RED, Color.BLACK);
        addType2(pane, Color.DARK_GRAY, Color.WHITE, Color.YELLOW, Color.GREEN);
    }

    private static void addType1(Container pane, Color c1, Color c2, Color c3, Color c4, Color c5) {
        pane.add(new TestPanel(c1));
        pane.add(new TestPanel(c2));
        pane.add(new TestPanel(c3));
        pane.add(new TestPanel(c4));
        pane.add(new TestPanel(c5));
    }

    private static void addType2(Container pane, Color c1, Color c2, Color c3, Color c4) {
        pane.add(new TestPanel(c1));
        pane.add(new TestPanel(c2), "spanx 2");
        pane.add(new TestPanel(c3));
        pane.add(new TestPanel(c4));
    }

    private static void addType3(Container pane, Color c1, Color c2, Color c3, Color c4) {
        pane.add(new TestPanel(c1));
        pane.add(new TestPanel(c2), "spanx 2, pushy, hmin pref+40");
        pane.add(new TestPanel(c3));
        pane.add(new TestPanel(c4));
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("MigLayout Practice");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addComponentsToPane(frame.getContentPane());
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

class TestPanel extends JPanel {
    public TestPanel(Color myColor) {
        this.setBackground(myColor);
    }
}
这将产生与您的示例完全相同的布局。可能您想要的是
hmin 40
而不是
hmin pref+40
,后者产生的结果与在GridBagConstraints中设置ipady=40相同

请在颜色类中使用大写常量,小写常量应该被弃用

对于任何想知道此布局是什么样子的人,请看以下内容:


你有一个好问题要问,但你问的不是正确的问题。您应该询问有关您试图将代码重构为类的问题,因为毕竟,重构毫无疑问是您在未来将不得不做无数次的事情。这对您来说是一个很好的实践机会,因此我建议您再尝试一次,并提出关于您的设计的具体问题。@安定您能提出一种您认为可行的重构方法吗?我可以看到明确设置某些组件的最大尺寸的方法,这样,剩余的组件将填充所有可用空间,包括完成大小调整时。但我的印象是,不建议使用明确的尺寸说明,我希望有人能给我展示一些使用更动态的方法的东西,比如GridBagLayout或其他类似的东西。非常感谢您花时间来做这件事。但是我注意到,您使用miglayet为代码添加了另一个依赖项。您知道一种不向代码添加额外依赖项的方法吗?仅使用Java附带的工具?JRE中还有其他布局管理器,但没有一个可以与MigLayout相比。MigLayout JAR文件只有76 kB。当然,您也可以用类似的方式重构GBL代码。谢谢。我最终重构了我的GBL代码,只需90行代码就可以完成我在发帖之初要求的所有工作。这样,我就不必在代码中添加另一个依赖项。然而,我将你的答案标记为答案,并投票给你+1,这样你就可以得到更多的分数。我想感谢你花这么多时间来帮助我。