Swing允许在JLabel之类的组件中使用html。 This文档详细讨论了这一点。它还显示了如何更改特定文本的颜色。

我正在使用具有数千个此类组件的现有swing应用程序。我想在任何使用位置更改链接的颜色。一次只做一个很麻烦。默认情况下,如果未指定颜色,swing似乎会将其渲染为蓝色。

如何将此默认值更改为其他内容?

最佳答案

因此,在深入研究代码之后,我学到了...

  • HTML由HTMLEditorKit和关联的API呈现
  • HTMLEditorKit使用的默认样式表在AppContext中集中/全局维护。

  • 来自HTMLEditorKit#getStyleSheet
     AppContext appContext = AppContext.getAppContext();
     StyleSheet defaultStyles = (StyleSheet) appContext.get(DEFAULT_STYLES_KEY);
    

    这很重要,因为它意味着您无需花费大量时间尝试查看标签的外观和感觉代码,并且您应该能够在单个位置更改全局样式表并影响所有内容的获取方式呈现...这可能是一件好事和坏事...

    下一个问题是,您实际上无法访问StyleSheet中的AppContext,因为DEFAULT_STYLES_KEYprivate static final Object ...

    这意味着您必须创建一个实例HTMLEditorKit并使用getStyleSheet获取对其的引用...
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.text.html.HTMLEditorKit;
    import javax.swing.text.html.StyleSheet;
    import sun.awt.AppContext;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    HTMLEditorKit kit = new HTMLEditorKit();
                    StyleSheet styleSheet = kit.getStyleSheet();
                    styleSheet.addRule("a {color:#ff0000;}");
    
                    JLabel label = new JLabel("<html><a href=http://stackoverflow.com/questions/tagged/java>Stackoverflow</a></html>");
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(label);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
    }
    

    08-26 17:10