Java Swing macOS 按钮在被选中时是灰色的而不是蓝色的
Java Swing macOS buttons are grey instead of blue when selected
我的 Swing 程序中有一个错误,当组件被选中时,JButton
和 JToggleButton
组件的背景为灰色而不是蓝色。这是 JToggleButton
上问题的屏幕截图,但按下 JButton
.
时会出现同样的问题
我试过用
手动设置背景
button.setBackground(Color.BLUE);
button.setOpaque(true);
但这只是在按钮周围画了一个小边框:
还添加了 button.setBorderPainted(false);
,它删除了边框,但也完全删除了 macOS 按钮外观 + 为文本提供了更深的背景颜色:
看起来边框 (AquaButtonBorder) 阻止了背景颜色的改变?因为简单地设置 button.setBackground(Color.BLUE);
绝对没有任何作用。
外观设置为 UIManager.getSystemLookAndFeelClassName()
,但也尝试了 UIManager.getCrossPlatformLookAndFeelClassName()
,但未成功。
Java 规范:运行 在 Java 11,但同样的问题在 Java 17
中仍然存在
系统规格:M1 MacBook Pro,macOS 版本 12.4
Sooo,我花了很多时间研究“Aqua”外观的源代码,我发现 AquaButtonUI
有一个“按钮类型”客户端 属性用于(除其他外)确定边框类型。
Sooo,我提取了所有内部“类型”并进行了快速测试...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir"));
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private String[] keys = new String[]{
"toolbar",
"icon",
"text",
"toggle",
"combobox",
"comboboxInternal",
"comboboxEndCap",
"square",
"gradient",
"bevel",
"textured",
"roundRect",
"recessed",
"well",
"help",
"round",
"texturedRound",
"segmented-first",
"segmented-middle",
"segmented-last",
"segmented-only",
"segmentedRoundRect-first",
"segmentedRoundRect-middle",
"segmentedRoundRect-last",
"segmentedRoundRect-only",
"segmentedTexturedRounded-first",
"segmentedTexturedRounded-middle",
"segmentedTexturedRounded-last",
"segmentedTexturedRounded-only",
"segmentedTextured-first",
"segmentedTextured-middle",
"segmentedTextured-last",
"segmentedTextured-only",
"segmentedCapsule-first",
"segmentedCapsule-middle",
"segmentedCapsule-last",
"segmentedCapsule-only",
"segmentedGradient-first",
"segmentedGradient-middle",
"segmentedGradient-last",
"segmentedGradient-only",
"disclosure",
"scrollColumnSizer"
};
public TestPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new BorderLayout());
JPanel contentPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (String key : keys) {
JToggleButton btn = new JToggleButton(key);
btn.putClientProperty("JButton.buttonType", key);
contentPane.add(btn, gbc);
}
add(new JScrollPane(contentPane));
}
}
}
一般来说,我发现 bevel
和 segmented-only
会达到你想要的结果(虽然 segment-first/middle/last
看起来很有趣)
我的 Swing 程序中有一个错误,当组件被选中时,JButton
和 JToggleButton
组件的背景为灰色而不是蓝色。这是 JToggleButton
上问题的屏幕截图,但按下 JButton
.
我试过用
手动设置背景button.setBackground(Color.BLUE);
button.setOpaque(true);
但这只是在按钮周围画了一个小边框:
还添加了 button.setBorderPainted(false);
,它删除了边框,但也完全删除了 macOS 按钮外观 + 为文本提供了更深的背景颜色:
看起来边框 (AquaButtonBorder) 阻止了背景颜色的改变?因为简单地设置 button.setBackground(Color.BLUE);
绝对没有任何作用。
外观设置为 UIManager.getSystemLookAndFeelClassName()
,但也尝试了 UIManager.getCrossPlatformLookAndFeelClassName()
,但未成功。
Java 规范:运行 在 Java 11,但同样的问题在 Java 17
中仍然存在系统规格:M1 MacBook Pro,macOS 版本 12.4
Sooo,我花了很多时间研究“Aqua”外观的源代码,我发现 AquaButtonUI
有一个“按钮类型”客户端 属性用于(除其他外)确定边框类型。
Sooo,我提取了所有内部“类型”并进行了快速测试...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
System.out.println(System.getProperty("user.dir"));
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private String[] keys = new String[]{
"toolbar",
"icon",
"text",
"toggle",
"combobox",
"comboboxInternal",
"comboboxEndCap",
"square",
"gradient",
"bevel",
"textured",
"roundRect",
"recessed",
"well",
"help",
"round",
"texturedRound",
"segmented-first",
"segmented-middle",
"segmented-last",
"segmented-only",
"segmentedRoundRect-first",
"segmentedRoundRect-middle",
"segmentedRoundRect-last",
"segmentedRoundRect-only",
"segmentedTexturedRounded-first",
"segmentedTexturedRounded-middle",
"segmentedTexturedRounded-last",
"segmentedTexturedRounded-only",
"segmentedTextured-first",
"segmentedTextured-middle",
"segmentedTextured-last",
"segmentedTextured-only",
"segmentedCapsule-first",
"segmentedCapsule-middle",
"segmentedCapsule-last",
"segmentedCapsule-only",
"segmentedGradient-first",
"segmentedGradient-middle",
"segmentedGradient-last",
"segmentedGradient-only",
"disclosure",
"scrollColumnSizer"
};
public TestPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new BorderLayout());
JPanel contentPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (String key : keys) {
JToggleButton btn = new JToggleButton(key);
btn.putClientProperty("JButton.buttonType", key);
contentPane.add(btn, gbc);
}
add(new JScrollPane(contentPane));
}
}
}
一般来说,我发现 bevel
和 segmented-only
会达到你想要的结果(虽然 segment-first/middle/last
看起来很有趣)