多色JLabel

时间:2017-10-03 10:30:30

标签: java swing

我想以不同的方式创建一个多色的JLabel。 (多色=不同前景色的文本部分)

到目前为止我找到的唯一解决方案(我目前使用的解决方案)是在html中设置文本。但是我遇到了问题......

当LayoutManager决定缩小JLabel时,在JLabel中使用纯文本,文本会被裁剪,并添加“...”。 (例如:“我的长文” - >变成:“我的长篇大论......”)

在JLabel中使用html,文本被包装在空格字符的某处,剩下的部分留在可绘制区域之外,并且当JLabel的高度不变时不可见。 (例如:“我的长文” - >变成:“我的长篇”)

在我的情况下,JLabel呈现在JTable中,由用户调整大小,更不用说在不同的屏幕分辨率下。

我尝试在html中添加“nowrap”属性或“”-tag,但看起来这样会被忽略。

离开我 - 我想 - 用一个解决方案:自己画标签。 或不? 有什么建议? 实例

谢谢。

这是一个非常简单的例子: 尝试水平调整此面板的大小,看看JLabel的内部文本会发生什么......

(没有对用户的指示,第二个JLabel的文本不是完整的内容)

- >在这个例子中,JLabel的高度发生了变化,但是当在框架的JTable中渲染时,行的高度不会改变,我不希望它改变。如果不使用HTML,它也不会改变高度......

import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class MultiJLabel extends JFrame { public MultiJLabel() { super("Multi-colored JLabel test"); JPanel pnl = new JPanel(); pnl.setLayout(new BorderLayout()); pnl.add(new JLabel("This is a test of My Long Text"), BorderLayout.NORTH); pnl.add(new JLabel("<html>This is a test of <font color='#ffbebe'>My Long Text</font></html>"), BorderLayout.SOUTH); this.getContentPane().add(pnl); this.pack(); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) { new MultiJLabel(); } }

Here's a picture of the original problem, where our users are not aware that the client's Order Number is not what the grid is showing, because this column has HTML-formatted text to show multi-colors.

2 个答案:

答案 0 :(得分:1)

谢谢大家的评论,但我很不耐烦并创建了自己的JLabel。 我知道它可能是一个糟糕的编程版本,但它对我有用... 你可以通过改变上面的例子来测试它:

JMultiColorLabel lbl = new JMultiColorLabel("This is a test of My Long Text");
lbl.setColors(new int[]{10,15}, new Color[]{Color.RED,Color.BLUE});
lbl.setPreferredSize(new Dimension(200,20));
pnl.add(lbl, BorderLayout.SOUTH);

并使用此课程:

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.util.HashMap;

import javax.swing.JLabel;

public class JMultiColorLabel
    extends JLabel
    {
    private static final String             STRING_OVERFLOW     = "...";

    private HashMap<Integer, Color>     extraColors             = new HashMap<Integer, Color>();

    public JMultiColorLabel(String text)
        {
        super(text);
        }

    public void setColors(int[] indices, Color[] colors)
        {
        for (int i = 0; i < indices.length; i++)
            this.extraColors.put(indices[i], colors[i]);
        }

    protected void paintComponent(Graphics g)
        {
        // Get text-contents of Label
        String text = this.getText();

        // No text in the JLabel? -> No risk: super
        if (text == null || text.length() == 0)
            {
            super.paintComponent(g);
            return;
            }

        // Content Array of characters to paint
        char[] chars = text.toCharArray();

        // Draw nice and smooth
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

         // Draw background
        if (this.isOpaque())
          {
          g2d.setColor(this.getBackground());
          g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
          }

        // FontMetrics to calculate widths and height
        FontMetrics fm = g2d.getFontMetrics();

        // Available space
        Insets ins = this.getInsets();
        int maxSpace = this.getWidth()-(ins.left+ins.right);
        boolean overflow = (fm.stringWidth(text) > maxSpace);

        // Starting offset
        int offset = ins.left+1;

        // The start Color is the default
        g2d.setColor(this.getForeground());

        // Loop over characters
        for (int i = 0; i < chars.length; i++)
            {
                // Switch Color?
            if (this.extraColors.containsKey(i))
                g2d.setColor(this.extraColors.get(i));

                // Check if we still have enough room for this character
            if (overflow && offset >= (maxSpace-fm.stringWidth(STRING_OVERFLOW)))
                { // Draw overflow and stop painting
                g2d.drawString(STRING_OVERFLOW, offset, (fm.getHeight()+ins.top));
                return;
                }
            else // We have the space -> Draw the character
                g2d.drawString(String.valueOf(chars[i]), offset, (fm.getHeight()+ins.top));

                // Move cursor to the next horizontal position
            offset += fm.charWidth(chars[i]);
            }
        }
    }

答案 1 :(得分:0)

要在JLabels中使用html-text时阻止换行,请将文本换行在nobr(不间断)标记中:

new JLabel("<html><nobr>This is a test of <font color='#ffbebe'>My Long Text</font></nobr></html>")

使用nobr - 标记时,该行不会被包装,但也不会被截断。因此,在显示的文本末尾不会有任何省略号(...),但它会被切断。

缺少的...在表格中实际上可能是有利的,因为省略号没有额外的宽度丢失,因此显示的内容更多。但是对于用户来说,没有它们的内容可能就不那么明显了。