Как создать ButtonGroup с подключенными кнопками в Java?

в настоящее время я пытаюсь создать группу переключателей, которые похожи на те, которые используются в настройках форматирования Eclipse:

Formatter preferences of 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();
    }
}

результат выглядит следующим образом:

Result without spacing

у меня есть несколько проблем с моим кодом. Во-первых, я не понимаю, почему я должен сделать вставки отрицательный. Согласно учебник Oracle, "[b]y по умолчанию каждый компонент не имеет внешнего заполнения.- Значит, по умолчанию не должно быть пробелов? Без отрицательных вставок результат выглядит следующим образом:

Result without setting negative insets

во-вторых, я хотел бы, чтобы кнопка переключения потемнела, а не стала синей с включенным "on". Есть ли простой способ сделать это через 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();
}

интересно, когда я попытался добавить границу, как прокомментировано выше, дополнительное расстояние между кнопками каким-то образом исчезло. Результат выглядит следующим образом:

With BoxLayout

Как можно Я хотел бы сохранить общий вид кнопки, как и раньше, но края будут более прямоугольными, чтобы переключатели выглядели более связанными.

2 ответов


вы можете использовать макет, как BoxLayout для устранения пространства. GridBagLayout-не единственный макет. Рекомендуемое чтение:http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

вы также можете вызвать функции JButton, такие как setBorder() и setBackground() для достижения упомянутых вами эффектов. Как всегда, API-ваш лучший друг:http://docs.oracle.com/javase/7/docs/api/


Кажется, я совершил досадную ошибку. Я попробовал предложение dic19 использовать Seaglass' посмотрите и почувствуйте вместе с JTabbedPane, и я получил почти то, что хотел:

Tabbed Pane with Seaglass

но затем я понял, что внешний вид по умолчанию для JTabbedPane был именно тем, что я хотел:

Default look and feel

код, который я использовал, аналогичен тому, который используется в JTabbedPane учебник by Оракул:

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's image for JTabbedPane