使用Nimbus L& F时,我想覆盖JTable
s中标题的背景颜色。我有效地"主题" Nimbus L& F,即对其进行小幅调整。
无论我尝试什么,它似乎都没有效果。
这是SSCCS:
public class MyTest {
public static void main(String[] args) {
new MyTest();
}
public MyTest() {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
Logger.getLogger(MyTest.class.getName()).log(Level.SEVERE, null, ex);
}
UIManager.put("TableHeader.background", Color.RED);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
DefaultTableModel model = new DefaultTableModel(
new Object[][]{
{"hhvt ", "er sdf", "sfdg"},
{"hyshg ", "dh sdf", "jer"}
},
new Object[]{"Col A", "Col B", "Col C"}
);
JTable table = new JTable(model);
setLayout(new BorderLayout());
add(new JScrollPane(table));
}
}
}
结果如下:
我非常清楚Nimbus是一个Synth L& F所以它几乎可以使用Painter个。我打赌我可以覆盖Painter
中的一些UIManager
,但我不想从头开始重做一个画家。 Nimbus的画家非常先进,他们使用渐变和你有什么。我想利用这一点。它只是我想改变的颜色。
答案 0 :(得分:2)
这是一个可能 - 但非常丑陋 - 解决方案。
Nimbus严重依赖Painter
。 Nimbus看起来很好的原因是因为它使用了渐变,阴影和不是。这是Painter
的工作。我们真的,真的不想做我们自己的画家。 Nimbus Painters相当复杂,产生了美丽的效果。所以我们想要利用它们。不要自己做!
Nimbus有很多自动生成的源代码。所有源代码都是从skin.laf
XML文件(位于JDK源中)生成的,但XML文件未在运行时使用。大多数自动生成的源文件实际上是特定于类型的Painter
。例如,TableHeaderRendererPainter
(负责绘制表格标题的画家)等画家类。问题是所有自动生成的源代码都是包私有的。
初始化NimbusLookAndFeel实例时设置画家。在此之后他们不会改变。
从skin.laf
文件中我们可以看到用于什么颜色。在我们的例子中,我们可以看到它实际上是nimbusBlueGrey
颜色,它控制着表头的背景颜色。我们不能只改变nimbusBlueGrey
的值,因为这会影响使用此颜色的Nimbus中的所有。所以我们需要提出一些其他的东西。这就是丑陋的地方。
在特定情况下,我们对表标题感兴趣,因为它们默认情况下看起来(即当鼠标不在它们之上时,表格未被禁用,列标题未被按下等)。所以这就是我们将在下面集中讨论的内容。但是对于任何其他类型的特殊装饰,这种技术都是相同的。
该技术首先启动NimbusLookAndFeel
的临时实例。我们这样做只是为了“偷”它生成的一个画家。我们比安全保持这个画家,然后开始NimbusLookAndFeel
真实。现在我们可以替换我们特定的Painter,以便我们交换之前保存的那个。
public class MyTest {
public static void main(String[] args) throws UnsupportedLookAndFeelException {
new MyTest();
}
public MyTest() throws UnsupportedLookAndFeelException {
// Start dummy instance of L&F
NimbusLookAndFeel nimbusTmp = new NimbusLookAndFeel();
Object nimbusBlueGreyOrg = UIManager.get("nimbusBlueGrey"); // original value
UIManager.put("nimbusBlueGrey", Color.RED); // the color we want
try {
UIManager.setLookAndFeel(nimbusTmp);
} catch (UnsupportedLookAndFeelException ex) {
Logger.getLogger(MyTest.class.getName()).log(Level.SEVERE, null, ex);
}
Object painter = UIManager.get("TableHeader:\"TableHeader.renderer\"[Enabled].backgroundPainter");
// We've got what we came for. Now unload the dummy.
UIManager.getLookAndFeel().uninitialize(); // important to avoid UIDefaults change listeners firing
UIManager.put("nimbusBlueGrey", nimbusBlueGreyOrg); // revert
// Load the L&F for real.
UIManager.setLookAndFeel(new NimbusLookAndFeel());
// Swap in the value we saved previously
UIManager.put("TableHeader:\"TableHeader.renderer\"[Enabled].backgroundPainter", painter);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
DefaultTableModel model = new DefaultTableModel(
new Object[][]{
{"hhvt ", "er sdf", "sfdg"},
{"hyshg ", "dh sdf", "jer"}},
new Object[]{"Col A", "Col B", "Col C"}
);
JTable table = new JTable(model);
setLayout(new BorderLayout());
add(new JScrollPane(table));
}
}
}
不为此感到自豪,但它确实有效。谁有更好的想法?