3

当 JLabel 中的文本太长时,文本末尾会出现 3 个可见的点。是否可以将它们放在开头?

4

3 回答 3

4

您可以考虑使用FontMetrics. 类查看当前字体下的文本长度。

_________________________________
|
| This is some really long text that I want to fit in the small label
|________________________________

       ^^^ YOUR LABEL ^^^  

假设您想将该长文本放入该标签中。
这是你可以做的(这只是一个疯狂的猜测,我正在做这个)

  1. 从你的三个点...开始String
  2. 开始一个一个地添加附加字符。
  3. 获取您的JLabel.
  4. 用于FontMetrics在添加更多字符时测量文本的长度(以像素为单位)
  5. 只要文本的像素长度小于您的宽度,就继续添加更多字符JLabel
  6. 一旦它变得大于 的宽度JLabel,就退出循环。
  7. 将此新形成的文本设置为您的文本JLabel

你最终应该是这样的:

_________________________________
|
| ...This is some really long tex
|________________________________

       ^^^ YOUR LABEL ^^^  

这是一个简单的入门方法FontMetrics。避免那里的争吵。只要按照公认的答案去做:Java: Friendlier way to get an instance of FontMetrics

SSCCE 符合 OP 真正想要的,而不是我解释的

package stack;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Toolkit;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class BackwardsDots extends JFrame{

    JLabel label = new JLabel(){
                        @Override
                        public Dimension getPreferredSize(){
                            return new Dimension(200,100);
                        }
                    };
    String text = "This is a design requirement and not my whim";
    FontMetrics fm;
    Font theFontBeingUsed;
//--------------------------------------------------------------------------------  
    public BackwardsDots(){
        getContentPane().add(label);
        pack();

        theFontBeingUsed = new Font("Ubuntu",Font.BOLD,14);
        fm = Toolkit.getDefaultToolkit().getFontMetrics(theFontBeingUsed);



        label.setText(trimmedStringCalculator(text));
        label.setToolTipText(text);
        label.setBorder(BorderFactory.createDashedBorder(Color.RED));
        label.addComponentListener(new ComponentListener(){

            @Override
            public void componentHidden(ComponentEvent arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void componentMoved(ComponentEvent arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void componentResized(ComponentEvent arg0) {
                label.setText(trimmedStringCalculator(text));
            }

            @Override
            public void componentShown(ComponentEvent arg0) {
                // TODO Auto-generated method stub

            }

        });

        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
//--------------------------------------------------------------------------------
    private String trimmedStringCalculator(String inputText){
        String ellipses = "...";
        String textToBeDisplayed = "";

        int widthOfJLabel = label.getWidth();

        for(int i = text.length()-1; i >= 0; i--){
            if(fm.stringWidth(ellipses + textToBeDisplayed) <= widthOfJLabel){
                textToBeDisplayed = text.charAt(i) + textToBeDisplayed;
            }
        }

        String finalText;
        if(textToBeDisplayed.equals(inputText)){
            finalText = inputText;
        }else{
            finalText = ellipses.concat(textToBeDisplayed);
        }

        return finalText;
    }
//--------------------------------------------------------------------------------  
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                new BackwardsDots();
            }
        });
    }
}

输出
在此处输入图像描述

于 2013-10-22T14:25:06.757 回答
2

我有另一个解决方案,它依赖于 LabelUI。首先是代码:

LabelUI labelUI = new MetalLabelUI() {
    @Override
    protected String layoutCL(JLabel label, FontMetrics fontMetrics, String text, Icon icon, Rectangle viewR, Rectangle iconR, Rectangle textR) {
        String clipString = "...";
        // Use reversed text, because first characters may be larger or thinner than last ones.
        String reversedText = new StringBuilder(text).reverse().toString();
        // Let Swing do its magic.
        String result = super.layoutCL(label, fontMetrics, reversedText, icon, viewR, iconR, textR);

        // Not using .equals is intentional. Previous method will return a different instance
        // if and only if a clip operation occurred.
        if (result != text) {
            // Use the same character count, but starting with the end.
            result = clipString
                    + text.substring(text.length() - result.length() + clipString.length());
        } else {
            // Restore the original
            result = text;
        }

        return result;
    }

};

我们的目标是让 Swing 计算所有内容,包括其剪裁的字符串,并以此为提示执行我们自己的左剪裁。诀窍是我们必须将反转的字符串提供给 super 方法,因为我们的结果将剪切前导字符,我们需要确保计算是正确的。字符有不同的宽度。

对我来说,主要优点是开销很小,与当前在 UI 之前计算新大小的解决方案相比,UI 将开始做同样的事情。

编辑:更改代码以在未剪辑时恢复原始字符串。

于 2016-06-07T12:57:49.440 回答
0

我认为这是一种系统行为,而不是JLabel's,所以你不能真正做到这一点。

于 2013-10-22T14:03:53.540 回答