我在 Java Swing 应用程序中使用 FlatMacDarkLaf 主题。我需要在 JScrollPane 中自定义滚动条的轨道和滑块颜色,同时保持现有的 FlatLaf 滚动条设计完好无损。我的目标是仅更改颜色而不更改 FlatLaf 提供的滚动条 UI。
附加:JDK 21 |蚂蚁构建
我尝试了以下代码来更改滚动条的颜色:
JScrollBar verticalScrollBar = jScrollPane1.getVerticalScrollBar();
verticalScrollBar.setUI(new javax.swing.plaf.basic.BasicScrollBarUI() {
@Override
protected void configureScrollBarColors() {
this.thumbColor = new Color(86, 86, 86);
this.trackColor = new Color(18, 18, 18);
}
});
但是,这种方法用BasicScrollBarUI替换了FlatLaf提供的滚动条UI,这不是我想要的。我需要一种方法来仅更改轨道和拇指颜色,同时保持 FlatLaf 滚动条设计。
要修改同一类型的所有组件(即全局默认值),请使用 UI 默认值:
UIManager.put("ScrollBar.track", Color.RED.darker());
UIManager.put("ScrollBar.thumb", Color.RED);
要覆盖各个组件的属性(即特定实例值),请在它们上使用
JComponent.putClientProperty
。文档中的示例:
myScrollPane.putClientProperty( "JScrollBar.showButtons", true );
每个组件都存在一个样式属性(
FlatClientProperties.STYLE
键),它接受 String
CSS 类型样式或 Map<String, Object>
属性。在这两种方式中,只需删除文档中指定的密钥的 "Component."
部分即可。例如 "JScrollBar.showButtons"
变为 "showButtons"
。
有关更多信息,您可以阅读本答案相应部分提供的资源链接。
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatDarkLaf;
import java.awt.Color;
import java.awt.Component;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Main {
/**
* @return A simple example {@code JScrollPane} with default contents.
*/
private static JScrollPane createListScrollPane() {
final Object[] listItems = new Object[20];
for (int i = 0; i < listItems.length; ++i)
listItems[i] = String.format("List item %02d", i);
final JList<?> list = new JList<>(listItems);
list.setVisibleRowCount(5);
return new JScrollPane(list);
}
/**
* Customizes the colors of the vertical scroll bar (as an example).
* @param pane
* @param trackColor Scroll bar background color.
* @param thumbColor Thumb color.
*/
private static void customizeListScrollPane(final JScrollPane pane,
final Color trackColor,
final Color thumbColor) {
final JScrollBar scrollBar = pane.getVerticalScrollBar();
//The style must be a String or a Map<String,Object> (see the documentation of FlatClientProperties.STYLE).
final Map<String, Object> style = new HashMap<>();
if (trackColor != null)
style.put("track", trackColor);
if (thumbColor != null)
style.put("thumb", thumbColor);
//putClientProperty will modify the style only for the specified scrollBar:
scrollBar.putClientProperty(FlatClientProperties.STYLE, style);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
//Initialize FlatLaf:
FlatDarkLaf.setup();
//Modify default colors inherited by every scroll bar (optional, just for demonstration):
UIManager.put("ScrollBar.track", Color.RED.darker());
UIManager.put("ScrollBar.thumb", Color.RED);
//Create frame contents (2 scroll panes inheriting default colors, and 3 other with modified ones):
final JPanel contents = new JPanel();
contents.setLayout(new BoxLayout(contents, BoxLayout.Y_AXIS));
for (int i = 0; i < 5; ++i) {
if (i == 0)
contents.add(new JLabel("Inheriting defaults:", JLabel.CENTER));
else if (i == 2)
contents.add(new JLabel("Custom colors for individual instance:", JLabel.CENTER));
final JScrollPane pane = createListScrollPane();
if (i >= 2)
customizeListScrollPane(pane, Color.GREEN.darker(), Color.CYAN);
contents.add(pane);
}
for (final Component component: contents.getComponents())
((JComponent) component).setAlignmentX(0.5f); //Because of BoxLayout.
//Show application:
final JFrame frame = new JFrame("Customized color in scroll bar");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(contents);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}