2012-03-12 96 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(); 
} 
}