随着 JDK 版本的不断发布,预定义的 Java 外观变得越来越出众,但是有时您需要特殊的 LAF。例如,要处理照片,您需要一个外观朴素、主题灰暗的整洁GUI (所有使用的颜色都有严格的灰度梯度),以便不会干扰颜色的正确分辨。
自从 JDK 1.4 开始,UIManager 类就允许在尽量少影响或不影响现有代码的情况下插入不同的外观。由于该类是标准 Swing API 的一部分,因此可以将很多兼容的 LAF 轻松插入到应用程序中。
如果您发现了喜欢的外观,您可以通过简单的命令行切换将它安装到 NetBeans 中(当然是安装到您的 NetBeans 平台应用程序中):
--look-and-feel 《name of the L&F class》
经过一些测试之后,我决定保留除了主窗口之外每个 GUI 部分的原始外观,在主窗口中我只更改了组件颜色(Mac OS X 就是一个特例;请参见下面内容)。
正如您所知,更改 Swing 组件的颜色通常是 c.setForeground() 和 c.setBackground() 的事。由于 NetBeans 平台是基于 Swing 的,因此并没有很多不同。但是也有几个例外。例如,这些标准方法不适用 ListView(Node 对象最常用的视图组件之一)。在 blueMarine 中,通过 清单 7 中的代码已经解决了这个问题,该代码首先检索内部的 Jlist,然后根据需要更改其属性。类似的代码也适用于基于树的组件(这些组件也有相同的问题)。
Listing 7. An enhanced ListView.
public class EnhancedListView extends ListView {
protected JList jList;
@Override
protected JList createList() {
jList = super.createList();
jList.setOpaque(isOpaque());
jList.setBackground(getBackground());
jList.setForeground(getForeground());
return jList;
}
@Override
public void setBackground (Color color) {
super.setBackground(color);
if (jList != null) {
jList.setBackground(color);
}
}
@Override
public void setForeground (Color color){
super.setForeground(color);
if (jList != null) {
jList.setForeground(color);
}
}
@Override
public void setOpaque (boolean opaque){
super.setOpaque(opaque);
if (jList != null) {
jList.setOpaque(opaque);
}
}
}
我发现了基于树的组件存在的另一个问题:即使使用前面列出的代码,树单元仍以黑白颜色显示。而且,通过检查源代码很容易找到原因:通常,NetBeans 的树具有一个特殊的单元格渲染器,它执行很多操作,如支持 HTML 显示(以便您可以使用多个文本样式);该单元格渲染器还选择在前景和背景之间对比明确的颜色主题。在大多数情况下,这是一个比较明智的方法,但是当您想要微调颜色时,这个方法就不太合适。通过清单 8 中所示的几行代码解决了这个问题。下面是安装修补后的渲染器的方法:
PatchedNodeRenderer nodeRenderer = new PatchedNodeRenderer(tree.getCellRenderer());
tree.setCellRenderer(nodeRenderer);
Listing 8. A patched cell renderer for controlling colors in JTree’s.
class PatchedNodeRenderer extends DefaultTreeCellRenderer {
private TreeCellRenderer peer;
public PatchedNodeRenderer (final TreeCellRenderer peer) {
this.peer = peer;
}
@Override
public Component getTreeCellRendererComponent (final JTree jTree,
final Object object, final boolean selected, final boolean expanded,
final boolean leaf, final int row, final boolean hasFocus)
{
final Component component = peer.getTreeCellRendererComponent(
jTree, object, selected, expanded, leaf, row, hasFocus);
component.setBackground(
selected ? getBackgroundSelectionColor() : getBackgroundNonSelectionColor());
component.setForeground(
selected ? getTextSelectionColor() : getTextNonSelectionColor());
return component;
}
}
关于外观,Mac OS X 提出了一些特殊的问题。对美学很挑剔的 Mac 用户注意到,一段时间以前,甚至 Apple 创建的 Java 实现都没有精确地复制操作系统外观。这样便促使了第三方产品 Quaqua 的出现,Quaqua 解决了所有这些问题并实现了像素精度的 Aqua GUI。(实际上这些问题远超出像素精度:例如,Apple Mac OS LAF 下的 Java JFileChooser 与本机的相比精度不够。)由于 Quaqua 的普通外观由 UIManager 类处理,而它在 blueMarine 中的集成也不是问题,因此除了几个 还有少数Quaqua 问题由项目的开发人员解决了。