GridLayout单元格的大小是否真的相同?

时间:2014-01-21 21:25:23

标签: java swing layout

我决定在我的Java Swing应用程序中使用GridLayout LayoutManager,因为网格中的每个单元格应该完全相同。

来自the Java Tutorials

  

GridLayout对象将组件放置在单元格网格中。每个组件占用其单元格中的所有可用空间,每个单元格的大小完全相同

甚至在GridLayout类的描述中:

  

GridLayout类是一个布局管理器,它在矩形网格中布置容器的组件。容器分为大小相等的矩形,每个矩形中放置一个组件。

然而,我的代码似乎使某个单元格比其他单元格大两倍。我使用JPanelsContainer添加了3 GridLayout,并为每个JPanel提供了不同的背景颜色。这就是结果:

enter image description here

显然,第一个JPanel(红色背景)是其他(绿色和黄色)的两倍。产生这个的代码如下:

public void updateListFrameContentPane(Container mainPane) {
    mainPane.setLayout(new GridLayout(1,0));
    JPanel listPanel = new JPanel();
    listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS));
    listPanel.add(friendsLabel);        
    listPanel.add(listScrollPane);
    listPanel.setBackground(Color.RED);
    mainPane.add(listPanel);
    for(JPanel chatPanel : chatPanels) {
        chatPanel.setBackground((Math.random()>0.5 ? Color.YELLOW : Color.GREEN));
        mainPane.add(chatPanel);
    }
}

我所做的就是将Container's布局设置为GridLayout,其中包含1行和任意数量的列,然后为其添加3 JPanels。那么为什么第一个JPanel要大得多呢?奇怪的是,只有在添加两个或更多chatPanels时才会发生这种情况。当只有一个时,它格式正确。

1 个答案:

答案 0 :(得分:1)

Kiheru是对的。更改容器的内容后重新验证/重新绘制。这是一个粗略但有效的例子:

public class GridLayoutExample {

private JFrame frame;
private Map<String,JPanel> chatBoxes = new HashMap<String,JPanel>();
private String lastKey = "0";

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                GridLayoutExample window = new GridLayoutExample();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public GridLayoutExample() {
    initialize();
}

private void addChatBox() {
    /*
     * JPanel (border layout)
     * - JPanel (Border South, Border layout)
     * - - JTextField ( Border center )
     * - - JButton ( Border east )
     * - JLabel (Border North )
     * - JTextArea (Border Center);
     */
    int lk = Integer.valueOf(lastKey)+1;
    lastKey = Integer.toString(lk);
    JPanel np = new JPanel();
    np.setLayout(new BorderLayout(0,0));
    np.setBackground((lk%2 == 0) ? Color.GREEN : Color.YELLOW);

    JPanel south = new JPanel();
    south.setLayout(new BorderLayout(0,0));
    np.add(south,BorderLayout.SOUTH);

    JButton b = new JButton("New Button");
    south.add(b,BorderLayout.EAST);

    JTextField field = new JTextField();
    south.add(field,BorderLayout.CENTER);

    JLabel label = new JLabel(lastKey);
    label.setHorizontalAlignment(SwingConstants.CENTER);
    np.add(label,BorderLayout.NORTH);

    JTextArea text = new JTextArea();
    np.add(text,BorderLayout.CENTER);

    chatBoxes.put(lastKey, np);
    frame.getContentPane().add(np);
    frame.revalidate();                 // CRITICAL MISSING LINES
    frame.repaint();                    // CRITICAL MISSING LINES
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 923, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(new GridLayout(1, 0, 0, 0));

    JPanel panel = new JPanel();
    panel.setBackground(Color.RED);
    frame.getContentPane().add(panel);
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

    JLabel lblNewLabel = new JLabel("Online Users");
    panel.add(lblNewLabel);

    JList list = new JList();
    list.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            addChatBox();
        }
    });
    list.setModel(new AbstractListModel() {
        String[] values = new String[] {"Alpha", "Beta", "Gamma", "Delta", "Epsilon"};
        public int getSize() {
            return values.length;
        }
        public Object getElementAt(int index) {
            return values[index];
        }
    });
    panel.add(list);

}
}

我选择重新验证/重新绘制整个框架,但是可以在重新绘制较小的容器时使其工作。当然,如果没有上面标出的关键线,那么点击列表元素的频率并不重要,不会显示任何新内容。使用这些行,每次单击时,都会添加一个新的聊天框。

嗯......刚才注意到这一点。如果红色区域被认为是两个单独的面板,那么它们的大小完全正确。您是否意外添加了额外的面板?