简体   繁体   English

Java-Swing:使用HTML设置所选文本颜色

[英]Java-Swing: Setting Selected Text Color with HTML

I'm having problems finding out how to set the Color of my JList's Selected Text using HTML. 我在查找如何使用HTML设置我的JList的选定文本的颜色时遇到问题。

Using Java Swing and HTML I've managed to color specific sections of each String in my JList, my example looks like this: 使用Java Swing和HTML我已经设法为我的JList中的每个String的特定部分着色,我的示例如下所示:

在此输入图像描述

This is ideal as I can set as many different colors as I want for each entry! 这是理想的,因为我可以为每个条目设置多种不同的颜色!

However, when the text is selected, only the default Black text turns White! 但是,选择文本时,只有默认的黑色文本变为白色! The html-colored text keeps its color instead of also turning white, this leads to some pretty hard-to-read text for some colors: html颜色的文本保持其颜色而不是变为白色,这导致一些非常难以阅读的文本的某些颜色:

在此输入图像描述

How would I be able to set the Text's Color when Selected? 如何在选择时设置文本颜色?

I've tried using JList's setSelectionForeground(Color.WHITE) method on the JList but it did not affect the html-colored text (although it did affect the non-html-colored text) 我已经尝试在JList上使用JList的setSelectionForeground(Color.WHITE)方法,但它不影响html颜色的文本(尽管它确实影响了非html颜色的文本)

I've also read up on Oracle's HTML-in-Swing tutorial (where I first found out about coloring with HTML) but could not find a solution. 我还阅读了Oracle的HTML-in-Swing教程(我首先发现了HTML着色)但找不到解决方案。

Here is the code to my short example: 这是我的简短示例的代码:

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.UIManager;
import java.awt.Color;

public class JListSelectionColorTest extends JFrame {

    private String[] exampleText = {"Some example text without any color changes",
        "Some more example text without color changes",
        "Even more plain text!", 
        "<html>Uncolored Text! <font color=orange>Now some example Text with color!</font> more Uncolored Text!</html>", 
        "<html>Uncolored Text! <font color=green>And some more example text with color! Text, Text, Text!</font> more Uncolored Text!</html>",
        "<html>Uncolored Text! <font color=red>A string with red color, Text Text Text!</font> more Uncolored Text!</html>",
        "<html>Uncolored Text! <font color=blue>And finally a string with blue color, Text Text Text!</font> more Uncolored Text!</html>",
        "<html>Uncolored Text! <font color=purple><selection color=white>Testing if some html can turn the selection color white!</selection></font> more Uncolored Text!</html>"};

    public JListSelectionColorTest() {
        super("JList Selection Color Test");

        // Set the Look and Feel of the window to the Native System's Look and Feel
        // (When using the default Look and Feel the problem still persists!)
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Create a JList of Strings containing the exampleText String array
        JList<String> exampleJList = new JList<String>(exampleText);

        // Set the JList's text selection color to white
        exampleJList.setSelectionForeground(Color.WHITE); // This doesn't seem to affect the html-colored text's selection foreground

        // Add the JList to the JFrame
        add(exampleJList);

        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }
    public static void main(String[] args) {
        new JListSelectionColorTest();
    }
}

One way, use a ListCellRenderer that uses replaceAll(...) to strip the HTML code out of your selected String. 一种方法是使用ListCellRenderer,它使用replaceAll(...)从您选择的String中删除HTML代码。 God I hate to use regex with HTML, and this won't work if your String has non-HTML angle brackets, < or > in it. 上帝我讨厌在HTML中使用正则表达式,如果您的String中包含非HTML尖括号<> ,则无法使用。

import javax.swing.DefaultListCellRenderer;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.UIManager;

import java.awt.Color;
import java.awt.Component;

public class JListSelectionColorTest extends JFrame {

   private String[] exampleText = {
         "Some example text without any color changes",
         "Some more example text without color changes",
         "Even more plain text!",
         "<html>Uncolored Text! <font color=orange>Now some example Text with color!</font> more Uncolored Text!</html>",
         "<html>Uncolored Text! <font color=green>And some more example text with color! Text, Text, Text!</font> more Uncolored Text!</html>",
         "<html>Uncolored Text! <font color=red>A string with red color, Text Text Text!</font> more Uncolored Text!</html>",
         "<html>Uncolored Text! <font color=blue>And finally a string with blue color, Text Text Text!</font> more Uncolored Text!</html>",
         "<html>Uncolored Text! <font color=purple><selection color=white>Testing if some html can turn the selection color white!</selection></font> more Uncolored Text!</html>" };

   public JListSelectionColorTest() {
      super("JList Selection Color Test");

      try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {
         e.printStackTrace();
      }
      JList<String> exampleJList = new JList<String>(exampleText);

      exampleJList.setCellRenderer(new MyCellRenderer());
      exampleJList.setSelectionForeground(Color.WHITE); 
      add(exampleJList);

      pack();
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setLocationRelativeTo(null);
      setVisible(true);
   }

   public static void main(String[] args) {
      new JListSelectionColorTest();
   }

   private static class MyCellRenderer extends DefaultListCellRenderer {
      // create a non-greedy regex to capture anything between angle brackets.
      private String regex = "\\<.*?\\>";

      @Override
      public Component getListCellRendererComponent(JList<?> list,
            Object value, int index, boolean isSelected, boolean cellHasFocus) {
         if (value == null) {
            return super.getListCellRendererComponent(list, value, index,
                  isSelected, cellHasFocus);
         }

         // only interested in selected Strings
         if (isSelected) {
            String valueStr = value.toString(); // get the String
            valueStr = valueStr.replaceAll(regex, "");  // extract the HTML
            value = valueStr;  // put back into value Object variable
         }
         return super.getListCellRendererComponent(list, value, index,
               isSelected, cellHasFocus);
      }
   }
}

A better solution: use JSoup to strip out the HTML. 一个更好的解决方案:使用JSoup去除HTML。
Better still, create a class that holds HTML and non-HTML Strings, have the List hold objects of this class, and swap the Strings in the renderer. 更好的是,创建一个包含HTML和非HTML字符串的类,让List保持此类的对象,并在渲染器中交换字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM