Java Swing布局

5
我很难确定应该使用哪种布局。有什么建议吗?

在这里输入图片描述

JPanel mainpanel = new JPanel();

public void addPanel(JPanel panel){
    mainpanel.add(panel);
}

addPanel(A);
addPanel(B);
addPanel(C);
addPanel(D);
addPanel(E);
....

面板A、B、C、D……的大小不是固定的。如何实现这一点?
5个回答

5
似乎通过使用GridBagLayout,您可以实现这一点。希望您可以根据自己的喜好更改JPanel的颜色为MAGENTA :-)
以下是输出:

GRIDBAG LAYOUT TEST

这里是代码:

 import java.awt.*;
 import javax.swing.*; //swing package

 public class GridBagLayoutTest
 {


    //defining the constructor
    public GridBagLayoutTest() 
    {

        JFrame maFrame = new JFrame("The main screen"); //creating main Jframe
        maFrame.setLocationByPlatform(true); //centering frame

        JPanel headPanel = new JPanel(); //creating the header panel

        Container container = maFrame.getContentPane();
        container.setLayout(new GridBagLayout()); //setting layout of main frame
        GridBagConstraints cns = new GridBagConstraints(); //creating constraint
        cns.gridx = 0;
        cns.gridy = 0;
        //cns.gridwidth = 3;
        //cns.gridheight = 4;
        cns.weightx = 0.5;
        cns.weighty = 0.2;
        cns.anchor = GridBagConstraints.FIRST_LINE_START;
        cns.fill = GridBagConstraints.BOTH;        
        headPanel.setBackground(Color.BLUE);
        container.add(headPanel, cns);

        JPanel panel = new JPanel();
        panel.setBackground(Color.CYAN);
        cns = new GridBagConstraints();
        cns.gridx = 1;
        cns.gridy = 0;
        //cns.gridwidth = 7;
        //cns.gridheight = 4;
        cns.weightx = 0.5;
        cns.weighty = 0.2;
        cns.anchor = GridBagConstraints.FIRST_LINE_END;
        cns.fill = GridBagConstraints.BOTH;
        container.add(panel, cns);

        JPanel panel1 = new JPanel();
        panel1.setBackground(Color.RED);
        cns = new GridBagConstraints();
        cns.gridx = 0;
        cns.gridy = 1;
        //cns.gridwidth = 2;
        cns.gridheight = 2;
        cns.weightx = 0.5;
        cns.weighty = 0.3;
        cns.anchor = GridBagConstraints.LINE_START;
        cns.fill = GridBagConstraints.BOTH;
        container.add(panel1, cns);     

        JPanel panel2 = new JPanel();
        panel2.setBackground(Color.PINK);
        cns = new GridBagConstraints();
        cns.gridx = 1;
        cns.gridy = 1;
        //cns.gridwidth = 2;
        //cns.gridheight = 2;
        cns.weightx = 0.5;
        cns.weighty = 0.2;
        cns.anchor = GridBagConstraints.LINE_END;
        cns.fill = GridBagConstraints.BOTH;
        container.add(panel2, cns);                 

        JPanel panel4 = new JPanel();
        panel4.setBackground(Color.ORANGE);
        cns = new GridBagConstraints();
        cns.gridx = 1;
        cns.gridy = 2;
        //cns.gridwidth = 2;
        //cns.gridheight = 2;
        cns.weightx = 0.5;
        cns.weighty = 0.2;
        cns.anchor = GridBagConstraints.LINE_END;
        cns.fill = GridBagConstraints.BOTH;
        container.add(panel4, cns); 

        JPanel mainPanel = new JPanel();
        mainPanel.setBackground(Color.WHITE);
        mainPanel.setLayout(new GridBagLayout());
        cns = new GridBagConstraints();
        cns.gridx = 0;
        cns.gridy = 4;
        cns.gridwidth = 2;
        cns.gridheight = 2;
        cns.weightx = 1.0;
        cns.weighty = 0.3;
        cns.anchor = GridBagConstraints.LAST_LINE_START;
        cns.fill = GridBagConstraints.BOTH;
        container.add(mainPanel, cns); 

        JPanel panel3 = new JPanel();
        panel3.setBackground(Color.MAGENTA);
        cns = new GridBagConstraints();
        cns.gridx = 0;
        cns.gridy = 0;
        //cns.gridwidth = 2;
        //cns.gridheight = 2;
        cns.weightx = 0.5;
        cns.weighty = 0.2;
        cns.anchor = GridBagConstraints.FIRST_LINE_START;
        cns.fill = GridBagConstraints.BOTH;
        mainPanel.add(panel3, cns); 

        JPanel bottomPanel = new JPanel();
        bottomPanel.setBackground(Color.WHITE);
        cns = new GridBagConstraints();
        cns.gridx = 0;
        cns.gridy = 1;
        //cns.gridwidth = 2;
        //cns.gridheight = 2;
        cns.weightx = 1.0;
        cns.weighty = 0.2;
        cns.anchor = GridBagConstraints.LAST_LINE_START;
        cns.fill = GridBagConstraints.BOTH;
        mainPanel.add(bottomPanel, cns); 

        //JButton button = new JButton("BUTTON");
        //headPanel.add(button);

        maFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //setting the default close operation of JFrame
        maFrame.pack();
        maFrame.setVisible(true); //making the frame visible
    }

    //defining the main method
    public static void main(String[] args) 
    {
        Runnable runnable = new Runnable()
        {
            public void run()
            {
                new GridBagLayoutTest(); //instantiating the class
            }
        };
        SwingUtilities.invokeLater(runnable);       
    }
}

3
考虑使用 JGoodies Forms 布局,它非常灵活且易于使用。任何类型的 widget 布局都是可能的,例如垂直堆叠、水平堆叠等。 http://www.jgoodies.com/freeware/forms/index.html enter image description here
                   /* B1   Space  B2    Space B3    Space  B4 */
     String col1 = "10dlu, 3dlu, 10dlu, 3dlu 10dlu, 3dlu, 10ldu";
                   /*Width of button */ 
     String row1 = "5dlu";

     FormLayout layout = new FormLayout( col1, row1);

     JPanel panel = new JPanel(layout); 

     panel.setBorder(Borders.DIALOG_BORDER);

     CellConstraints cc = new CellConstraints();

     /* X - stands for column position :: Y - stand for row */  
     panel.add(new JButton("B1"), cc.xy(1, 1));

     panel.add(new JButton("B2"), cc.xy(2, 1));
     .
     .
     . 
     there is one more cc.xyh(1,1,2) where 'h' stands for vertical span or width.   

是的,你可以去JGoodies网站了解更多关于表单布局的信息,“DLU”意味着对话框单位,而不是我来解释所有这些。请下载该库和文档。相信我,这个布局管理器在可用性、可维护性和可读性方面都要好得多。


2

网格布局可以适应这种形状。只需查看Java Swing文档


2

我认为,首先创建一个临时的面板来处理ACF,然后再创建一个来处理BDE,接着再创建一个面板将ACF和BDE组合起来,最后将这个临时面板和你的主要面板添加到边界布局的NORTH和SOUTH上。


1

取决于窗口调整大小时的行为。但是你无法避免使用JPanels构建树形结构。

顶部组件可以具有BorderLayout,其中North区域有一个面板,中心区域有一个主面板。
North面板将具有X轴BoxLayout,并包含两个面板。
这两个面板都应该具有Y轴BoxLayout,第一个面板将包含A、C、F,第二个面板将包含B、D、E。

您还应该为A、B、C、D、E和F设置首选大小,以便它们以适当的大小呈现。

编辑:
这里,我创建了一个示例:

public class GladysPanel extends JPanel
{
    public GladysPanel(JComponent A, JComponent B, JComponent C, JComponent D, JComponent E, JComponent F, JComponent main){
        super(new BorderLayout());
            JPanel abcdef = new JPanel(new BorderLayout());
                Box ab = new Box(BoxLayout.X_AXIS);
                ab.add(A);
                ab.add(B);
            abcdef.add(ab, BorderLayout.NORTH);
                Box cdef = new Box(BoxLayout.X_AXIS);
                    Box cf = new Box(BoxLayout.Y_AXIS);
                    cf.add(C);
                    cf.add(F);
                    cf.add(Box.createVerticalGlue());
                    Box de = new Box(BoxLayout.Y_AXIS);
                    de.add(D);
                    de.add(E);
                    de.add(Box.createVerticalGlue());
                cdef.add(cf, BorderLayout.WEST);
                cdef.add(de, BorderLayout.EAST);
            abcdef.add(cdef);
        add(abcdef, BorderLayout.NORTH);
        add(main);
    }

    public static void main(String[] args){
        JPanel A = new JPanel();
        A.setOpaque(true);
        A.setBackground(Color.BLUE);
        A.add(new JLabel("A"));
        JPanel B = new JPanel();
        B.setOpaque(true);
        B.setBackground(Color.LIGHT_GRAY);
        B.add(new JLabel("B"));
        JPanel C = new JPanel();
        C.setPreferredSize(new Dimension(0, 100));
        C.setOpaque(true);
        C.setBackground(Color.RED);
        C.add(new JLabel("C"));
        JPanel D = new JPanel();
        D.setOpaque(true);
        D.setBackground(Color.PINK);
        D.add(new JLabel("D"));
        JPanel E = new JPanel();
        E.setOpaque(true);
        E.setBackground(Color.YELLOW);
        E.add(new JLabel("E"));
        E.setPreferredSize(new Dimension(0, 60));
        JPanel F = new JPanel();
        F.setOpaque(true);
        F.setBackground(Color.MAGENTA);
        F.add(new JLabel("F"));
        JPanel main = new JPanel();
        main.setOpaque(true);
        main.setBackground(Color.WHITE);
        main.add(new JLabel("main"));

        GladysPanel panel = new GladysPanel(A, B, C, D, E, F, main);
        JFrame example = new JFrame("Gladys example");
        example.setContentPane(panel);
        example.setSize(300, 300);
        example.setVisible(true);
    }
}

你可以省略setPreferredSize(),我只是添加它来演示行为。你也可以尝试调整窗口大小。使用这段代码比使用GridBagLayout要短得多。


不要使用 setPreferredSize();在 pack() 后让内容决定大小。 - trashgod
如果_won't avoid building a tree_被翻译成“嵌套面板”(根据您的描述):那就是错误的 - 即使在核心中也有LayoutManagers可以实现几乎所有目标。请注意,这里只提供文本翻译,不进行解释。 - kleopatra
当然,你甚至可以使用空布局。但有些布局比其他布局更容易和更清晰。我的意思是,看看 Gagandeep 的代码。 - Jakub Zaverka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接