1

我正在编写一个允许多个用户共享屏幕截图的程序。每次用户连接时,参与“房间”的每个人(一群能够从彼此接收屏幕截图的用户)都可以看到用户拍摄的屏幕截图。为了能够看到屏幕截图,框架需要自行拆分,以便为该用户的屏幕截图提供专用空间。

我决定使用 GridLayout ,因为它将组件拆分为大小相同的矩形,这正是我要寻找的。布局完全符合我的需要,除了有一个问题。如果我的 GridLayout 配置为有两行和两列,即使只有一个组件,最底部的行仍将拆分为两列。这是预期的行为,但是否有走动,最好不使用不同的布局?我真的很喜欢 GridLayout 的简单性。我曾考虑使用 BorderLayout,但它是有限的,因为有一定数量的空间可以放置项目。

不支持图片的格式,所以我无法将它们嵌入到这个问题中。这是框架看起来已满的样子。我用实际的屏幕截图代替了按钮,因为我只是在测试。

http://cl.ly/0N311g3w061P1B0W1T3s/Screen%20shot%202012-05-13%20at%204.23.25%20PM.png

现在这是我从最底行删除按钮时的外观:http: //cl.ly/2j3Z0V1r3w1S3F160j05/Screen%20shot%202012-05-13%20at%204.23.41%20PM.png

这是我希望最底行的外观: http ://cl.ly/0J2R2y2L06151F0k0Y0i/Screen%20shot%202012-05-13%20at%204.24.11%20PM.png

我怎样才能使最底部的行看起来像那样?请记住,我仍然希望其他行有两列,但我只希望最底部的行有一列。

谢谢!

4

3 回答 3

2

据我所知,你不能。GridLayout 就是这样完成的。

但是 GridBagLayout 将为您的程序做得很好。

看看这个按行和列排列按钮的小演示。(单击按钮将其删除)。

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Test4 {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();

                final JPanel root = new JPanel(new GridBagLayout());
                frame.add(root);
                frame.setSize(600, 600);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                Timer t = new Timer(2000, new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        final JButton b = new JButton("Hello" + root.getComponentCount());
                        b.addActionListener(new ActionListener() {

                            @Override
                            public void actionPerformed(ActionEvent e) {
                                root.remove(b);
                                updateConstraints(root);
                            }
                        });
                        root.add(b);
                        updateConstraints(root);
                    }
                });
                t.start();
            }
        });
    }

    protected static void updateConstraints(JPanel root) {
        if (!(root.getLayout() instanceof GridBagLayout)) {
            System.err.println("No a gridbaglayout");
            return;
        }
        GridBagLayout layout = (GridBagLayout) root.getLayout();
        int count = root.getComponentCount();
        int col = (int) Math.round(Math.sqrt(count));
        int row = (int) Math.ceil((double) count / col);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        int index = 0;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                gbc.gridx = j;
                gbc.gridy = i;
                boolean last = index + 1 == count;
                if (last) {
                    gbc.gridwidth = col - j;
                }
                Component c = root.getComponent(index);
                layout.setConstraints(c, gbc);
                if (last) {
                    break;
                }
                index++;
            }
        }
        root.doLayout();
    }
}
于 2012-05-13T22:04:02.440 回答
1

我决定采用稍微不同的方法。由于在屏幕数量为偶数时使用 GridLayout 可以很好地布置单独的屏幕,因此我决定在屏幕数量为奇数的情况下简单地将屏幕拆分为页面。

于 2012-05-14T03:31:49.777 回答
0

我认为您想使用GridBagLayout- 查看布局的视觉指南

特别是,使用 a GridBagLayout,您可以添加带有 a 的组件GridBagConstraints。这允许您指定每个组件的放置位置,以及每个组件应该具有的权重 - 例如,请参阅GridBagLayout 教程

于 2012-05-13T21:57:47.433 回答