在GridBagLayout中设置任意宽度

时间:2014-12-07 22:34:46

标签: java swing layout-manager gridbaglayout

我正在尝试制作键盘布局,可以指定按钮的宽度。因此,我尝试GridBagLayout,但没有成功。 为了说明我的问题,我做了一个简单的例子,我期望得到它(Button2,Button4,Button5,Button6):

但我获得了双倍宽度的Button4和Button6。

代码是:

package views;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

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

public class TestLayout  extends JFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestLayout().setVisible(true);
            }
        });
    }

    public TestLayout() {
        JButton btn;
        setBounds(0, 0, 444, 111);
        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;

        gbc.gridy = 1;//ROW 1
        btn = new JButton("Button 1");gbc.gridx = 0;gbc.gridwidth = 1;add(btn, gbc);
        btn = new JButton("Button 2");gbc.gridx = 1;gbc.gridwidth = 2;add(btn, gbc);
        btn = new JButton("Button 3");gbc.gridx = 3;gbc.gridwidth = 1;add(btn, gbc);
        btn = new JButton("Button 4");gbc.gridx = 4;gbc.gridwidth = 2;add(btn, gbc);

        gbc.gridy = 2;//ROW 2
        btn = new JButton("Button 5");gbc.gridx = 0;gbc.gridwidth = 2;add(btn, gbc);
        btn = new JButton("Button 6");gbc.gridx = 2;gbc.gridwidth = 2;add(btn, gbc);
        btn = new JButton("Button 7");gbc.gridx = 4;gbc.gridwidth = 1;add(btn, gbc);
        btn = new JButton("Button 8");gbc.gridx = 5;gbc.gridwidth = 1;add(btn, gbc);
    }  
}

此外,我的目标是定义类似这样的键盘,行之间没有相关性,这是我用这个布局管理器无法实现的:

1 个答案:

答案 0 :(得分:3)

我把这件事交给了Why does this GridBagLayout not appear as planned?& camickr使用一排虚拟的元件解决了它,每个元件宽1 gridwidth

enter image description here

这两张图片显示:

  1. 在底部,'极简主义'使用1px高透明图像的代码版本。
  2. 在顶部,使用高度为5像素的纯黑色图像的更明显的版本。

  3. import java.awt.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    import javax.swing.border.*;
    
    public class KeyBoardLayout {
    
        private JComponent ui = null;
    
        KeyBoardLayout(boolean lowImpact) {
            initUI(lowImpact);
        }
    
        public void initUI(boolean lowImpact) {
            if (ui != null) {
                return;
            }
    
            ui = new JPanel(new GridBagLayout());
            ui.setBorder(new EmptyBorder(4, 4, 4, 4));
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.weightx = .5;
            gbc.weighty = .5;
            gbc.fill = GridBagConstraints.BOTH;
    
            /* This code adds a dummy (invisible) row of components, 1 per 
             single gridwidth column.  It has the effect of forcing the GBL width 
             to the size we would expect, proportional to each gridwidth assigned.
             The problem with this (simple) approach is that the perfect 
             width will change according to PLAF and the content/preferred 
             size of the visible components. */
            // TODO! improve on use of 'magic numbers'
            int w = 30; // adjust width per requirement
            int h = lowImpact ? 1 : 5; // 1 for small height/border, 5 for large
            // TYPE_INT_RGB for black
            // TYPE_INT_ARGB for invisible
            int t = lowImpact ? 
                    BufferedImage.TYPE_INT_ARGB : 
                    BufferedImage.TYPE_INT_RGB;
            // an icon for the dummy row
            ImageIcon ii = new ImageIcon(new BufferedImage(w, h, t));
            ui.setBorder(new CompoundBorder(
                    ui.getBorder(), new EmptyBorder(0, 0, h, 0)));
            // put a 'padding cell' in each column of the top row
            // to force the layout to respect each individual column
            for (int i = 0; i < 22; i++) {
                gbc.gridx = i;
                gbc.gridy = 4;
                ui.add(new JLabel(ii));
            }
    
            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.gridwidth = 3;
            ui.add(new JButton("1,1 (3)"), gbc);
    
            gbc.gridx = 3;
            gbc.gridwidth = 2;
            ui.add(new JButton("2,1 (2)"), gbc);
    
            gbc.gridx = 5;
            ui.add(new JButton("3,1 (2)"), gbc);
    
            gbc.gridx = 7;
            ui.add(new JButton("4,1 (2)"), gbc);
    
            gbc.gridx = 9;
            ui.add(new JButton("5,1 (2)"), gbc);
    
            gbc.gridx = 11;
            ui.add(new JButton("6,1 (2)"), gbc);
    
            gbc.gridx = 13;
            ui.add(new JButton("7,1 (2)"), gbc);
    
            gbc.gridx = 15;
            gbc.gridwidth = 3;
            ui.add(new JButton("8,1 (3)"), gbc);
    
            gbc.gridx = 18;
            gbc.gridwidth = 4;
            ui.add(new JButton("9,1 (4)"), gbc);
    
            gbc.gridx = 0;
            gbc.gridy = 2;
            ui.add(new JButton("1,2 (4)"), gbc);
    
            gbc.gridx = 4;
            gbc.gridwidth = 2;
            ui.add(new JButton("2,2 (2)"), gbc);
    
            gbc.gridx = 6;
            ui.add(new JButton("3,2 (2)"), gbc);
    
            gbc.gridx = 8;
            ui.add(new JButton("4,2 (2)"), gbc);
    
            gbc.gridx = 10;
            ui.add(new JButton("5,2 (2)"), gbc);
    
            gbc.gridx = 12;
            ui.add(new JButton("6,2 (2)"), gbc);
    
            gbc.gridx = 14;
            ui.add(new JButton("7,2 (2)"), gbc);
    
            gbc.gridx = 16;
            ui.add(new JButton("8,2 (2)"), gbc);
    
            gbc.gridx = 18;
            gbc.gridwidth = 4;
            ui.add(new JButton("9,2 (4)"), gbc);
    
            gbc.gridx = 0;
            gbc.gridy = 3;
            gbc.gridwidth = 5;
            ui.add(new JButton("1,3 (5)"), gbc);
    
            gbc.gridx = 5;
            gbc.gridwidth = 2;
            ui.add(new JButton("2,3 (2)"), gbc);
    
            gbc.gridx = 7;
            ui.add(new JButton("3,3 (2)"), gbc);
    
            gbc.gridx = 9;
            ui.add(new JButton("4,3 (2)"), gbc);
    
            gbc.gridx = 11;
            ui.add(new JButton("5,3 (2)"), gbc);
    
            gbc.gridx = 13;
            ui.add(new JButton("6,3 (2)"), gbc);
    
            gbc.gridx = 15;
            ui.add(new JButton("7,3 (2)"), gbc);
    
            gbc.gridx = 17;
            ui.add(new JButton("8,3 (2)"), gbc);
    
            gbc.gridx = 19;
            gbc.gridwidth = 3;
            ui.add(new JButton("9,3 (3)"), gbc);
    
            gbc.gridx = 0;
            gbc.gridy = 4;
            gbc.gridwidth = 3;
            ui.add(new JButton("1,4 (3)"), gbc);
    
            gbc.gridx = 3;
            ui.add(new JButton("2,4 (3)"), gbc);
    
            gbc.gridx = 6;
            gbc.gridwidth = 10;
            ui.add(new JButton("3,4 (10)"), gbc);
    
            gbc.gridx = 16;
            gbc.gridwidth = 3;
            ui.add(new JButton("4,4 (3)"), gbc);
    
            gbc.gridx = 19;
            ui.add(new JButton("5,4 (3)"), gbc);
    
            gbc.gridx = 0;
            gbc.gridy = 4;
            gbc.gridwidth = 1;
        }
    
        public JComponent getUI() {
            return ui;
        }
    
        public static void main(String[] args) {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(
                                UIManager.getSystemLookAndFeelClassName());
                    } catch (Exception useDefault) {
                    }
                    for (int ii = 0; ii < 2; ii++) {
                        KeyBoardLayout o = new KeyBoardLayout(ii==0);
    
                        JFrame f = new JFrame("Keyboard Layout");
                        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                        f.setLocationByPlatform(true);
    
                        f.setContentPane(o.getUI());
                        f.pack();
                        f.setMinimumSize(f.getSize());
    
                        f.setVisible(true);
                    }
                }
            };
            SwingUtilities.invokeLater(r);
        }
    }