制作 Java SplitButton

Making a Java SplitButton

下面的代码似乎应该用两个关联的 JButton 均匀地填充给定的 space,但它却用一个按钮填充了 FlowLayout 的整个顶行——忽略按钮的最大尺寸——并将新行上的其他按钮,仅部分可见。如何让按钮并排均匀填充 JPanel?

import java.awt.*;
import javax.swing.*;

public class SplitButton extends JPanel {

    // The other half.
    private JButton button2;
    private JButton button3;

    public SplitButton(String left, String right, int width, int height) {
        super();
        //setBackground(Color.GREEN);
        //setBorder(BorderFactory.createLineBorder(Color.BLUE));
        setMinimumSize(new Dimension(width, height));
        FlowLayout flow = new FlowLayout();
        flow.setAlignment(FlowLayout.LEFT);
        flow.setHgap(0);
        flow.setVgap(0);

        setLayout(flow);

        button2 = new JButton(right);
        button2.setMinimumSize(new Dimension(width / 2, height));
        button2.setMaximumSize(new Dimension(width / 2, height));
        button2.setPreferredSize(new Dimension(width / 2, height));
        add(button2);

        button3 = new JButton(right);
        button3.setMinimumSize(new Dimension(width / 2, height));
        button2.setMaximumSize(new Dimension(width / 2, height));
        button2.setPreferredSize(new Dimension(width / 2, height));
        add(button3);
    }
}

经过一段时间的挣扎,我尝试了一个 GridLayout--它使 Swing 中的 SplitButtons 成为一个非常合理的 UI 元素。

import java.awt.Font;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;

public class SplitButton extends JPanel {

    // The buttons.
    private JButton[] buttons;

    // Self-explanatory.
    public Color prim, trim;
    public Font font;

    public SplitButton(String[] labels, Color prim, Color trim, Font font) {
        super();

        this.prim = prim;
        this.trim = trim;
        this.font = font;

        // Evenly lays out buttons evenly in a row.
        GridLayout grid = new GridLayout(1, labels.length);
        grid.setHgap(0);
        grid.setVgap(0);
        setLayout(grid);

        setOpaque(false);
        initButtons(labels);
    }

    /**
    * Constructs and styles the button array.
    * @param labels The button labels.
    */
    private void initButtons(String[] labels) {
        buttons = new JButton[labels.length];
        for(int i = 0; i < buttons.length; i++) {
            buttons[i] = new JButton(labels[i]);

            // Only outer borders are thick.
            int lb = (i == 0) ? 2 : 1;
            int rb = (i == buttons.length - 1) ? 2 : 0;

            buttons[i].setBorder(BorderFactory.createMatteBorder(2, lb, 2, rb, trim));
            buttons[i].setFocusPainted(false);
            buttons[i].setFont(font);
            buttons[i].setBackground(prim);
            buttons[i].setForeground(trim);
            add(buttons[i]);
        }
    }

    /**
    * Enable/disable the buttons.
    * @param enabled Is the button enabled?
    */
    public void setEnabled(boolean enabled) {
        if(buttons != null)
            for(int i = 0; i < buttons.length; i++)
                buttons[i].setEnabled(enabled);
    }

    /**
    * Listen to all the buttons.
    * @param listener The listening object.
    */
    public void addActionListener(ActionListener listener) {
        if(buttons != null)
            for(int i = 0; i < buttons.length; i++)
                buttons[i].addActionListener(listener);
    }
}