Ken*_*ama 7 java layout swing gridbaglayout jtogglebutton
我目前正在尝试创建一组切换按钮,这些按钮类似于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();
}
}
Run Code Online (Sandbox Code Playgroud)
结果如下:

我的代码有几个问题.首先,我不明白为什么我必须让插图消极.根据Oracle的教程 "默认情况下,每个组件都没有外部填充." 因此,默认情况下不应该没有空格吗?没有负面插图,结果如下所示:

其次,我希望切换按钮变暗而不是转为蓝色并切换为"打开".有没有简单的方法通过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();
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,当我尝试添加上面注释的边框时,按钮之间的额外间距不知何故消失了.结果如下:

我希望尽可能保持按钮的一般外观,但是边缘应该更加矩形,以便切换按钮看起来更加连接.
您可以使用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 结合使用,我几乎得到了我想要的结果:

但后来我意识到 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;
}
}
Run Code Online (Sandbox Code Playgroud)
尽管我知道 Java Swing 的默认依赖于平台的外观和感觉在不同平台上是不同的,但我从未想象过 JTabbedPane 看起来会与教程中显示的内容如此不同:
