【问题标题】:Are GridLayout cells really all the same size?GridLayout 单元格的大小真的都一样吗?
【发布时间】:2014-02-11 17:07:15
【问题描述】:

我决定为我的 Java Swing 应用程序使用 GridLayoutLayoutManager,因为网格中的每个单元格都应该具有完全相同的大小。

来自the Java Tutorials

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

甚至在GridLayout类的描述中:

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

但是,我的代码似乎使某个单元格比其他单元格大一倍。我将 3 个JPanels 添加到带有GridLayoutContainer,并为每个JPanel 赋予不同的背景颜色。结果是这样的:

显然,第一个 JPanel(红色背景)是其他 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 时。当只有一个时,它的格式正确。

【问题讨论】:

  • 它们应该并且通常与文档中所说的大小相同。您是否在窗口可见后添加组件?如果是这样,你revalidate() 布局了吗?
  • 你是在用其他方法给mainPane添加组件吗?
  • @JohnGaughan 不,每次我想添加组件时都会运行此方法
  • @kiheru 是的,我是。 revalidate() 有什么作用?我在GridLayout中找不到方法@
  • 是的,GridLayout 中的单元格大小是否相同。重新发布问题 (stackoverflow.com/q/21244363/131872) 不会帮助您获得答案。而是发布一个正确的MVCE 来证明问题。大多数时候,当您尝试创建 MVCE 时,您会解决自己的问题。

标签: java swing layout


【解决方案1】:

基赫鲁是对的。更改容器内容后重新验证/重新绘制。这是一个粗略但可行的示例:

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

}
}

我选择重新验证/重新绘制整个框架,但在重新绘制较小的容器时可能会使其工作。当然,如果没有上面标记的关键行,无论您单击列表元素的频率如何,都不会显示任何新内容。通过这些行,每次单击时,都会添加一个新的聊天框。

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

【讨论】:

  • Have you perhaps accidentally added an extra panel? - 这就是为什么要求 OP 提供MVCE。根据 10 行代码,我们无法判断他做错了什么。问题肯定出在未发布的代码上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 2018-04-13
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多