首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nimbus -覆盖TableHeader的颜色

Nimbus -覆盖TableHeader的颜色
EN

Stack Overflow用户
提问于 2014-11-10 09:05:22
回答 1查看 1.1K关注 0票数 4

当使用Nimbus L&F时,我想重写JTable中标题的背景色。我实际上是在对Nimbus L&F进行“主题化”,即对它进行小的调整。

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

下面是一个SSCCS

代码语言:javascript
复制
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 &F,所以它使用画家s做任何事情。我打赌我可以在Painter中重写一些UIManager,但是我不想从头开始重做一个画家。尼姆布斯的画家们都很先进,他们使用渐变和什么东西。我想利用这一点。这只是我想要改变的颜色。

EN

回答 1

Stack Overflow用户

发布于 2014-11-10 23:17:55

这里有一个可能的解决方案--但非常丑陋--解决方案。

Nimbus在很大程度上依赖于Painter。Nimbus之所以看起来不错,是因为它使用了渐变、阴影等等。这是Painter的工作。我们真的,真的不想做自己的画家。尼姆布斯画家是相当复杂的,并产生美丽的结果。所以我们想利用他们。不要自己动手!

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

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

skin.laf文件中我们可以看到什么颜色是用来做什么的。在我们的例子中,我们可以看到控制表标题背景色的实际上是nimbusBlueGrey颜色。我们不能仅仅更改nimbusBlueGrey的值,因为这会影响使用这种颜色的Nimbus中的所有内容。所以我们得想点别的办法。这就是它变得丑陋的地方。

在特定情况下,我们对表标题感兴趣,因为它们在默认情况下看起来(例如,当鼠标不在表头上时,表没有被禁用,列标题没有按下,等等)。这就是我们下面要集中讨论的问题。但是,对于其他人想要做的任何特殊装饰,这种技术也是一样的。

技术是首先启动NimbusLookAndFeel的临时实例。我们这样做只是为了让我们能够“偷”它所生成的一个画家。我们比安全,保持这幅画,然后启动NimbusLookAndFeel的真实。现在,我们可以替换我们的特定画家,这样我们就可以交换我们以前保存的那个了。

代码语言:javascript
复制
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));
        }

    }

}

不以这个为荣,但很管用。有人有更好的主意吗?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26840096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档