2012-03-12 93 views
2

考虑以下图:堆栈摇摆元素底部

Required Design

我需要开发一个Swing GUI的外观上来看是这样的。我只是简单地将它们命名为jLabel's,但其中包含一些图像和jLabel。可见的默认awt背景是JPanel,每个可见的红色背景是一个serperate JPanel。现在我需要他们像上面显示的那样堆叠起来。我尝试了一些布局管理器,但仍然无法使用。

这里重要的一点是红色的div的数量不是恒定的。如果只有一个红色的彩色格,那么它必须显示在顶部,而不是中心。据我所知GridBagLayout应该工作,但它集中了可用的单红色jpanel。所有的布局管理员都将它们集中在一起,但不是从上到下进行堆叠。

+0

我挺没得到你meant.The什么JPanel的内容是真正动态。什么是适当的布局管理器,这样做?并将其从最外层的jpanel(带有awt背景的jpanel)中添加到“JScrollPane”。所以'FlowLayout'不工作 – sasidhar 2012-03-12 21:16:47

回答

3

即使锚集合向北则面板仍将居中。你可以通过添加一个虚拟面板来填补余下的空间。就个人而言,我会尽可能远离GridBagLayout。

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示例(我最喜欢的布局管理器)。

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); 
+0

组布局是为了手动编码吗?我一辈子都远离它... 而我不明白你在哪里插入这个假面板? – sasidhar 2012-03-12 21:34:20

+1

@sasidhar是GroupLayout可以“手工”使用 - 说了很多人觉得很难理解。虚拟面板是在3个示例面板后添加的面板 - 我在代码中添加了一条评论来指出它。 – Adam 2012-03-12 21:53:39

0

将组件添加到面板时请确保GridBagConstraints.anchor = GridBagConstraints.NORTH

+0

尝试'GridBagConstraints.NORTH','GridBagConstraints.FIRST_LINE_START'和'GridBagConstraints.PAGE_START'似乎没有任何工作 – sasidhar 2012-03-12 21:26:34

+0

@sasidhar是的我试过NORTH但它没有工作,我不得不添加一个虚拟面板填补剩下的空间,以强制东西顶部。看我的解决方案。 – Adam 2012-03-12 21:30:08

2
+1

尝试过,这确实得到了预期位置的第一个元素,但是当只有两个元素时,下一个元素被展开占据整个重新渲染的位置 – sasidhar 2012-03-12 21:27:33

+0

尝试将框布局面板添加到具有边框布局的面板的北侧。 – 2012-03-13 10:54:34

+0

有相同的问题,使用Axis = y使用BoxLayout解决。感谢Wajdy – 2012-06-07 05:25:13

2

没有人告诉我们,所有JComponent上必须是可见的,例如

enter image description here

enter image description here

enter image description here

从代码

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(); 
    } 
} 
+0

我觉得你错过了这里的一个点,我给你的图像清楚地表明背景JPanel的高度是固定的,当它增加到超过该点时,它附加的JScrollPane将创建滚动条。使用this.pack创建一个仅适用于组件的JPanel是一个不适合我的场景的简单解决方案。 – sasidhar 2012-03-13 04:11:19

+0

@sasidhar所有的东西都是简单的,你在想什么, – mKorbel 2012-03-13 07:45:11

1

你应该尝试MigLayout,它很简单但功能强大。下面我告诉miglayout增长元素,并填充所有可能的空间,然后在每个元素之后,我告诉它去一个新行(换行)。你可以找到MigLayout 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(); 
} 
}