我是用Java语言开发的,我正在努力寻找一种智能的解决方案,以便即使在使用JLabel的多行文本时也能正确地将前景色设置为html。
我知道Swing在将前景设置为html文本时遇到了问题。我想使用正则表达式来发现label的文本是否为html格式,如果是,则向其添加一个font标签。问题是为了让它正常工作,我必须在方法的末尾调用setText()。为了避免StackOverflowException,必须采取一些措施。这就是我想要的正则表达式:<html>(<font [^>]*>)?((.*)(<\\/font><\\/html>)|(.*)<\\/html>)
因此,在覆盖JLabel的类中,我覆盖了JLabel.getText()方法:
@Override
public String getText()
{
String superText = super.getText();
if (superText == null)
return superText;
Matcher m = pattern.matcher(superText);
if (m.matches())
{
String text = "<html><font color=\""+retrieveHexColor()+"\">"+TempUtils.nvl(m.group(5), m.group(3))+"</font></html>";
if (superText.equals(text))
return superText;
superText = text;
}
setText(superText);
return superText;
}那么TempUtils.nvl就只是
public static <T> T nvl(T value, T defaultValue)
{
return value == null ? defaultValue : value;
}我不太喜欢这个解决方案。你能帮帮我吗?我想,如果我能在(<\\/font><\\/html>)和(.*)<\\/html>)之间找到最长的匹配,我就可以很容易地解决我的问题。
编辑:我被要求编写一些代码来测试我所说的话:
public static void main(String[] args)
{
final JPanel panel = new JPanel(new BorderLayout());
JLabel overriddenLabel = new JLabel("<html>aBc<br>deEEEF</html>", JLabel.CENTER) {
Color foreground = Color.cyan;
{
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e)
{
foreground = Color.black;
repaint();
}
@Override
public void mouseExited(MouseEvent e)
{
foreground = Color.cyan;
repaint();
}
});
}
@Override
public Color getForeground()
{
return foreground;
}
};
JFrame frame = new JFrame("AD");
panel.add(overriddenLabel);
frame.setContentPane(panel);
frame.setVisible(true);
frame.setSize(new Dimension(300,300));
}正如您所看到的,设置非html文本可以使其正常工作。
EDIT2:吃完午饭回来了。我的解决方案与此类似。它能工作,但我不喜欢它。
public static void main(String[] args)
{
final JPanel panel = new JPanel(new BorderLayout());
JLabel overriddenLabel = new JLabel("<html>aBc<br>deEEEF</html>", JLabel.CENTER) {
Color foreground = Color.cyan;
{
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e)
{
foreground = Color.black;
repaint();
}
@Override
public void mouseExited(MouseEvent e)
{
foreground = Color.cyan;
repaint();
}
});
}
@Override
public Color getForeground()
{
return foreground;
}
public String colorToHex(Color color)
{
if (color == null)
return null;
String hexColor = Integer.toHexString(color.getRGB() & 0xffffff);
if (hexColor.length() < 6)
hexColor = "000000".substring(0, 6 - hexColor.length()) + hexColor;
return "#"+hexColor;
}
@Override
public String getText()
{
Pattern pattern = Pattern.compile("<html>(<font [^>]*>)?((.*)(<\\/font><\\/html>)|(.*)<\\/html>)");
String superText = super.getText();
if (superText == null)
return superText;
Matcher m = pattern.matcher(superText);
if (m.matches())
{
String text = "<html><font color=\""+colorToHex(foreground)+"\">"+(m.group(5) == null ? m.group(3) : m.group(5))+"</font></html>";
if (superText.equals(text))
return superText;
superText = text;
}
setText(superText);
return superText;
}
};
JFrame frame = new JFrame("AD");
panel.add(overriddenLabel);
frame.setContentPane(panel);
frame.setVisible(true);
frame.setSize(new Dimension(300,300));
}发布于 2016-02-03 04:33:52
可行的解决方案,无需使用regexp。
public static void main(String[] args) {
final JPanel panel = new JPanel(new BorderLayout());
JLabel overriddenLabel = new JLabel("<html>aBc<br>deEEEF</html>", JLabel.CENTER) {
Color foreground = Color.cyan;
{
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setForeground(Color.black);
repaint();
}
@Override
public void mouseExited(MouseEvent e) {
setForeground(Color.cyan);
repaint();
}
});
}
};
overriddenLabel.setForeground(Color.cyan);
JFrame frame = new JFrame("AD");
panel.add(overriddenLabel);
frame.setContentPane(panel);
frame.setVisible(true);
frame.setSize(new Dimension(300, 300));
}我不知道您为什么要覆盖getForeground,您并没有对它做任何特殊的事情
发布于 2016-02-03 00:57:21
我终于为我的问题找到了正确的正则表达式。如果有人需要它,它就在这里:
<html>(<[^>]*>)*(([^<]*)(<\/?br\/?>)?[^<]*)(<\/[^>]*>)*<\/html>
谢谢。
https://stackoverflow.com/questions/35151080
复制相似问题