Nimbus - 覆盖TableHeader的颜色 [英] Nimbus - override color for TableHeader

查看:119
本文介绍了Nimbus - 覆盖TableHeader的颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Nimbus L& F时,我想覆盖 JTable 中标题的背景颜色。我实际上正在点击Nimbus L& F,即对它进行小幅调整。



无论我尝试什么它似乎都没有效果。



这是一个几乎可以做任何事情。我打赌我可以在 UIManager 中覆盖一些 Painter ,但我不想从头开始重做一个Painter。 Nimbus中的画家非常先进,他们使用渐变和你有什么。我想利用这一点。这只是我想要改变的颜色。

解决方案

这是一个可能 - 但非常难看 - 的解决方案。



Nimbus严重依赖于 Painter 。 Nimbus看起来很好的原因是因为它使用了渐变,阴影和不是。这是 Painter 的工作。我们真的,真的不想做我们自己的画家。 Nimbus Painters相当复杂,产生了美丽的效果。所以我们想要利用它们。不要自己做!



Nimbus有很多自动生成的源代码。所有源代码都是从 skin.laf XML文件(位于JDK源代码中)生成的,但XML文件未在运行时使用。大多数自动生成的源文件实际上是特定于类型的 Painter 。例如, TableHeaderRendererPainter (负责绘制表格标题的画家)等画家类。问题是所有自动生成的源代码都是包私有的。



在初始化NimbusLookAndFeel实例时设置画家。在此之后他们不会改变。



skin.laf 文件,我们可以看到用于什么颜色。在我们的例子中,我们可以看到它实际上是 nimbusBlueGrey 颜色,它控制着表头的背景颜色。我们不能只改变 nimbusBlueGrey 的值,因为这会影响使用此颜色的Nimbus中的所有。所以我们需要提出其他的东西。这就是它变得丑陋的地方。



在特定情况下,我们对表标题感兴趣,因为它们默认看起来(即当鼠标不在它们之上时,表未被禁用,未按下列标题等)。所以这就是我们将在下面集中讨论的内容。但是对于任何其他类型的特殊装饰,这种技术都是相同的。



该技术首先启动<$的临时实例C $ C> NimbusLookAndFeel 。我们这样做只是因为我们可以窃取它产生的一个画家。我们比安全保持这个画家,然后开始 NimbusLookAndFeel 真实。现在我们可以替换我们特定的Painter,以便我们交换之前保存的那个。

  public class MyTest {

public static void main(String [] args)throws UnsupportedLookAndFeelException {
new MyTest();
}

public MyTest()抛出UnsupportedLookAndFeelException {

//启动L& F
的虚拟实例NimbusLookAndFeel nimbusTmp = new NimbusLookAndFeel();
Object nimbusBlueGreyOrg = UIManager.get(nimbusBlueGrey); //原始值
UIManager.put(nimbusBlueGrey,Color.RED); //我们想要的颜色
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);

//我们得到了我们的目标。现在卸载假人。
UIManager.getLookAndFeel()。uninitialize(); //重要的是要避免UIDefaults更改侦听器触发
UIManager.put(nimbusBlueGrey,nimbusBlueGreyOrg); // revert

//加载L& F for real。
UIManager.setLookAndFeel(new NimbusLookAndFeel());

//交换我们之前保存的值
UIManager.put(TableHeader:\TableHeader.renderer \[Enabled] .backgroundPainter,画家);

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);

}
});
}

公共类TestPane扩展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));
}

}

}

不为此感到自豪,但它有效。谁有更好的想法?


I would like to override the background color of headers in JTables when using the Nimbus L&F. I'm effectively "theming" the Nimbus L&F, i.e. making small adjustments to it.

Whatever I try it doesn't seem to have effect.

Here's an 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));
        }

    }

}

Here's the result:

I'm well aware that Nimbus is a Synth L&F so it uses Painters for just about anything. I bet I could override some Painter in UIManager but I don't want to redo a Painter from scratch. The Painters in Nimbus are quite advanced, they use gradients and what have you. I would like to take advantage of that. It's just the color I would like to change.

解决方案

Here's a possible - but quite ugly - solution.

Nimbus relies heavily on Painters. The reason why Nimbus looks good is because it uses gradients, shadows and what not. That's the job of the Painter. We really, really don't want to do our own Painters. The Nimbus Painters are quite complex and produce beautiful results. So we want to leverage them. Not do them ourselves!

Nimbus has a lot of auto-generated source code. All source code is generated off the skin.laf XML file (which is in the JDK source) but the XML file is not used at runtime. Most of the auto-generated source files are in fact type-specific Painters. For example there's a painter class for TableHeaderRendererPainter (a painter responsible for painting table headers) and so on. The problem is that all auto-generated source code is package-private.

Painters are set when an instance of NimbusLookAndFeel is initialized. They don't change after this.

From skin.laf file we can see what colors are used for what. In our case we can see it's really the nimbusBlueGrey color that governs the background color of the table headers. We can't just change the value of nimbusBlueGrey as that would affect everything in Nimbus that uses this color. So we need to come up with something else. And this is where it gets ugly.

In the specific case we're interested in table headers as they look by default (i.e. when the mouse is not over them, the table is not disabled, the column header is not pressed, etc). So this is what we'll concentrate on below. But the technique would be the same for any other type of special decoration that somebody would want to do.

The technique is to first start up a temporary instance of the NimbusLookAndFeel. We do this only so we can 'steal' one of the Painters it has generated. We than safe keep this Painter and then start the NimbusLookAndFeel for real. Now we can replace our specific Painter so that we swap in the one we saved previously.

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));
        }

    }

}

Not proud of this, but it works. Anyone with better ideas ?

这篇关于Nimbus - 覆盖TableHeader的颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆