简体   繁体   English

GridLayout单元格真的都一样大小吗?

[英]Are GridLayout cells really all the same size?

I decided to use a GridLayout LayoutManager for my Java Swing app because each cell within the grid is supposed to be exactly the same size. 我决定为我的Java Swing应用程序使用GridLayout LayoutManager ,因为网格中的每个单元格都应该具有完全相同的大小。

From the Java Tutorials : Java教程

A GridLayout object places components in a grid of cells. GridLayout对象将组件放置在单元格的网格中。 Each component takes all the available space within its cell, and each cell is exactly the same size . 每个组件占用其单元中的所有可用空间,并且每个单元的大小完全相同

And even in the description of the GridLayout class: 甚至在GridLayout类的描述中:

The GridLayout class is a layout manager that lays out a container's components in a rectangular grid. GridLayout类是一个布局管理器,用于将容器的组件布置在矩形网格中。 The container is divided into equal-sized rectangles , and one component is placed in each rectangle. 容器分为大小相等的矩形 ,每个矩形中放置一个组件。

However, my code seems to make a certain cell twice as large as the others. 但是,我的代码似乎使某个单元格的大小是其他单元格的两倍。 I added 3 JPanels to a Container with GridLayout , and gave each JPanel a different background color. 我使用GridLayout将3个JPanels添加到了一个Container ,并为每个JPanel了不同的背景色。 This was the result: 结果是:

在此处输入图片说明

Clearly, the first JPanel (red background) is twice as big as the others (green and yellow). 显然,第一个JPanel(红色背景)的大小是其他JPanel(绿色和黄色)的两倍。 The code that produced this is the following: 产生此代码的代码如下:

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);
    }
}

All I do is set the Container's layout to GridLayout with 1 row and any number of columns, and then add 3 JPanels to that. 我要做的就是将Container's布局设置为GridLayout其中包含1行和任意数量的列,然后向其中添加3个JPanels So why is the first JPanel so much larger? 那么,为什么第一个JPanel这么大? Strangely this only happens when two or more chatPanels are added. 奇怪的是,只有在添加两个或更多chatPanels时,才会发生这种情况。 When there is only one, it formats correctly. 如果只有一个,则格式正确。

Kiheru is right. Kiheru是对的。 revalidate/repaint after changing the contents of a container. 更改容器的内容后重新验证/重新绘制。 Here's a rough but working example: 这是一个粗略但可行的示例:

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

}
}

I chose to revalidate/repaint the entire frame, but it may be possible to have it work while repainting a lesser container. 我选择重新验证/重新绘制整个框架,但是在重新绘制较小的容器时可能会使其工作。 Certainly without the critical lines marked above, it doesn't matter how often you click on the list elements, nothing new will show up. 当然,没有上面标记的关键行,无论单击列表元素的频率如何,都不会显示任何新内容。 With those lines, every time you click, a new chatbox is added. 使用这些行,每次单击时,都会添加一个新的聊天框。

Huh... just noticed this. 嗯...刚注意到这一点。 If the red area is considered two separate panels, then they're all the exactly correct size. 如果红色区域被认为是两个单独的面板,则它们的大小完全正确。 Have you perhaps accidentally added an extra panel? 您是否可能不小心添加了额外的面板?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM