Stack swing elements from top to bottom

那年仲夏 提交于 2019-12-19 10:19:10

问题


Consider the following figure:

I need to develop a swing GUI the looks like this. I simply named them jLabel's but there a few images and jLabels in it. The default awt background visible is a JPanel and each red background visible is a serperate JPanel. Now I need them to get stacked as shown above. I tried a number of LayoutManagers and still it doesn't work.

The important point here is that the number of red colored divs are not constant. If there is only one red colored div then it must be displayed at the top, not at the center. As far as i know GridBagLayout should work, but it centers the single red colored jpanel available. All the layout managers are centering them but not stacking them from top to bottom.


回答1:


Even with anchor set to NORTH then the panels will still be centered. You could work around it by adding a dummy panel to fill the remaining space. Personally I'd stay well away from GridBagLayout though.

JFrame frame = new JFrame();
JPanel content = new JPanel();
content.setBorder(BorderFactory.createLineBorder(Color.red));
frame.setContentPane(content);
frame.getContentPane().setLayout(new GridBagLayout());
frame.setSize(400, 300);

for (int i = 0; i < 3; i++) {
    JPanel panel = new JPanel();
    panel.add(new JLabel("label1"));
    panel.add(new JLabel("label2"));
    panel.add(new JLabel("label3"));
    panel.setBorder(BorderFactory.createLineBorder(Color.red));
    GridBagConstraints con = new GridBagConstraints();
    con.gridy = i;
    con.gridx = 0;
    con.anchor = GridBagConstraints.NORTHWEST;
    con.ipady = 10;
    frame.getContentPane().add(panel, con);
}

// dummy panel to use up the space (force others to top)
frame.getContentPane().add(
        new JPanel(),
        new GridBagConstraints(0, 3, 1, 1, 1, 1,
                GridBagConstraints.NORTHWEST,
                GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0,
                0));

frame.setVisible(true);

GroupLayout example (my favourite layout manager).

JFrame frame = new JFrame();
JPanel content = new JPanel();
frame.setContentPane(content);
frame.getContentPane().setLayout(
        new BoxLayout(content, BoxLayout.Y_AXIS));
frame.setSize(400, 300);
GroupLayout gLayout = new GroupLayout(content);
content.setLayout(gLayout);
ParallelGroup hGroup = gLayout.createParallelGroup();
gLayout.setHorizontalGroup(hGroup);
SequentialGroup vGroup = gLayout.createSequentialGroup();
gLayout.setVerticalGroup(vGroup);
for (int i = 0; i < 3; i++) {
    JPanel panel = new JPanel();
    panel.add(new JLabel("label1"));
    panel.add(new JLabel("label2"));
    panel.add(new JLabel("label3"));
    panel.setBorder(BorderFactory.createLineBorder(Color.red));
    hGroup.addComponent(panel);
    vGroup.addComponent(panel, GroupLayout.PREFERRED_SIZE,
            GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE);
    vGroup.addGap(10);
}

frame.setVisible(true);



回答2:


you can use Vertical BoxLayout, for example: http://www.java-tips.org/java-se-tips/javax.swing/how-to-use-swing-boxlayout.html




回答3:


nobody tell us that all JComponents must be visible, for example

from code

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;

public class AddComponentsAtRuntime {

    private JFrame f;
    private JPanel panel;
    private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;

    public AddComponentsAtRuntime() {
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel = new JPanel(new GridLayout(0, 1));
        f.add(panel, "Center");
        f.add(getCheckBoxPanel(), "South");
        f.setLocation(200, 200);
        f.pack();
        f.setVisible(true);
    }

    private JPanel getCheckBoxPanel() {
        checkValidate = new JCheckBox("validate");
        checkValidate.setSelected(false);
        checkReValidate = new JCheckBox("revalidate");
        checkReValidate.setSelected(false);
        checkRepaint = new JCheckBox("repaint");
        checkRepaint.setSelected(false);
        checkPack = new JCheckBox("pack");
        checkPack.setSelected(false);
        JButton addComp = new JButton("Add New One");
        addComp.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JPanel b = new JPanel(new GridLayout(0, 4));
                b.setBackground(Color.red);
                b.setBorder(new LineBorder(Color.black, 2));
                //b.setPreferredSize(new Dimension(600, 20));
                for (int i = 0; i < 4; i++) {
                    JLabel l = new JLabel("label" + i + 1);
                    b.add(l);
                    if (i == 2) {
                        l.setVisible(false);
                    }
                }
                panel.add(b);
                makeChange();
                System.out.println(" Components Count after Adds :" + panel.getComponentCount());
            }
        });
        JButton removeComp = new JButton("Remove One");
        removeComp.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int count = panel.getComponentCount();
                if (count > 0) {
                    panel.remove(0);
                }
                makeChange();
                System.out.println(" Components Count after Removes :" + panel.getComponentCount());
            }
        });
        JPanel panel2 = new JPanel();
        panel2.add(checkValidate);
        panel2.add(checkReValidate);
        panel2.add(checkRepaint);
        panel2.add(checkPack);
        checkPack.setSelected(true);
        panel2.add(addComp);
        panel2.add(removeComp);
        return panel2;
    }

    private void makeChange() {
        if (checkValidate.isSelected()) {
            panel.validate();
        }
        if (checkReValidate.isSelected()) {
            panel.revalidate();
        }
        if (checkRepaint.isSelected()) {
            panel.repaint();
        }
        if (checkPack.isSelected()) {
            f.pack();
        }
    }

    public static void main(String[] args) {
        AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
    }
}



回答4:


You should try the MigLayout it is simple yet powerful. Below I tell miglayout to grow elements, and fill all possible space, then after each element I tell it to go to a new line (wrap). You can find examples and tutorial on MigLayout page http://www.miglayout.com/:

import net.miginfocom.swing.MigLayout;

public class PanelLearning extends JPanel {

public PanelLearning() {
    setLayout(new MigLayout("", "[grow, fill]", ""));

    for (int i = 0; i < 3; i++) {
        JPanel panel = new JPanel();
        panel.add(new JLabel("label1"));
        panel.add(new JLabel("label2"));
        panel.add(new JLabel("label3"));
        panel.setBorder(BorderFactory.createLineBorder(Color.red));
        add(panel, "span, wrap");
    }
}

public static void main(String[] args) {
    JFrame frame = new JFrame("Login");
    frame.setVisible(true);

    frame.setContentPane(new PanelLearning());

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    frame.pack();
}
}



回答5:


Make sure GridBagConstraints.anchor = GridBagConstraints.NORTH when you add components to the panel.



来源:https://stackoverflow.com/questions/9674774/stack-swing-elements-from-top-to-bottom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!