8

我目前正在尝试创建一组类似于 Eclipse 格式化程序首选项中使用的切换按钮:

Eclipse 的格式化程序首选项

目前我已经尝试过以下方式:

public class Exercise extends JFrame {

    private String[] buttonNames = {"A", "B", "C", "D", "E"};

    Exercise() {
        final JPanel topPanel = new JPanel();
        topPanel.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        int tabCount = 0;
        final ButtonGroup topButtonGroup = new ButtonGroup();
        for (String buttonName : buttonNames) {
            JToggleButton tabButton = new JToggleButton(buttonName);
            topButtonGroup.add(tabButton);
            c.fill = GridBagConstraints.HORIZONTAL;
            c.insets = new Insets(0, -6, 0, -7); // Questionable line
            c.gridx = tabCount;
            c.gridy = 0;
            topPanel.add(tabButton, c);
            tabCount++;
        }
        this.add(topPanel);
        this.setVisible(true);
        this.pack();
    }

    public static void main(String[] args) {
        new Exercise();
    }
}

结果如下:

没有间距的结果

我对我的代码有一些担忧。首先,我不明白为什么我必须将插图设为负数。根据Oracle 的教程,“[b] 默认情况下,每个组件都没有外部填充。” 因此,默认情况下不应该没有空格吗?没有负插图,结果如下所示:

没有设置负插图的结果

其次,我想让切换按钮变暗而不是在切换“打开”时变成蓝色。有没有简单的方法通过 Java Swing 做到这一点?最后,一般来说有没有更好的方法?我很想知道 Eclipse 是如何设法让切换按钮看起来像是完美连接的。

更新

我已尝试按照建议使用 BoxLayout。不幸的是,这似乎并没有解决问题。结果几乎与上图相同。这是修改后的构造函数:

Exercise() {
    final JPanel topPanel = new JPanel();
    topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
    final ButtonGroup topButtonGroup = new ButtonGroup();
    for (String buttonName : buttonNames) {
        JToggleButton tabButton = new JToggleButton(buttonName);
    //    tabButton.setBorder(BorderFactory.createBevelBorder(
    //              BevelBorder.RAISED, Color.LIGHT_GRAY, Color.DARK_GRAY));
        topButtonGroup.add(tabButton);
        topPanel.add(tabButton);
    }
    this.add(topPanel);
    this.setVisible(true);
    this.pack();
}

有趣的是,当我尝试添加上面注释的边框时,按钮之间的额外间距不知何故消失了。结果如下:

使用 BoxLayout

我希望尽可能保持按钮的一般外观,但边缘更矩形,以便切换按钮看起来更加连接。

4

2 回答 2

5

您可以使用 BoxLayout 之类的布局来消除空间。GridBagLayout 并不是唯一的布局。推荐阅读:http ://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

您还可以调用 JButton 函数,如 setBorder() 和 setBackground() 来实现您提到的效果。一如既往,API 是您最好的朋友:http ://docs.oracle.com/javase/7/docs/api/

于 2014-01-23T14:01:02.283 回答
4

看来我犯了一个尴尬的错误。我尝试了 dic19 提出的将Seaglass 的外观与 JTabbedPane 结合使用的建议,我几乎得到了我想要的:

带有 Seaglass 的选项卡式窗格

但后来我意识到 JTabbedPane 的默认外观和感觉正是我想要的:

默认外观

我使用的代码类似于Oracle在JTabbedPane 教程中使用的代码:

public class SeaGlassExercise {

    public static void initWindow() {
        JFrame frame = new JFrame("Application Name");
        CustomTabbedPane content = new CustomTabbedPane();
        frame.setContentPane(content);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLocationByPlatform(true);
//        try {
//            UIManager.setLookAndFeel(
//        "com.seaglasslookandfeel.SeaGlassLookAndFeel");
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        SwingUtilities.updateComponentTreeUI(frame);
        frame.pack();
        frame.setVisible(true);
    }

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

}

class CustomTabbedPane extends JPanel {

    public CustomTabbedPane() {
        super(new GridLayout(1, 1));
        JTabbedPane tabbedPane = new JTabbedPane();
        JComponent panel1 = makeTextPanel("Panel #1");
        tabbedPane.addTab("AAA", panel1);
        JComponent panel2 = makeTextPanel("Panel #2");
        tabbedPane.addTab("BBB", panel2);
        JComponent panel3 = makeTextPanel("Panel #3");
        tabbedPane.addTab("CCC", panel3);
        JComponent panel4 = makeTextPanel("Panel #4");
        tabbedPane.addTab("DDD", panel4);
        add(tabbedPane);
        tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
    }

    protected JComponent makeTextPanel(String text) {
        JPanel panel = new JPanel();
        JLabel filler = new JLabel(text);
        filler.setHorizontalAlignment(JLabel.CENTER);
        panel.setLayout(new GridLayout(1, 1));
        panel.add(filler);
        return panel;
    }
}

虽然我知道 Java Swing 依赖于平台的默认外观在不同平台上是不同的,但我从没想过 JTabbedPane 看起来与教程中显示的有如此大的不同:

Oracle 的 JTabbedPane 映像

于 2014-01-26T03:54:50.563 回答