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. の 3 つのドットから始め...ますString
  2. 追加文字を 1 つずつ追加し始めます。
  3. の幅を取得しますJLabel
  4. FontMetrics文字を追加すると、テキストの長さをピクセル単位で測定するために 使用します
  5. テキストのピクセル長がテキストの幅よりも小さい限り、文字を追加し続けます。JLabel
  6. の幅より大きくなったらJLabel、ループから抜けます。
  7. この新しく形成されたテキストをあなたのテキストとして設定しますJLabel

次のようになります。

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

       ^^^ YOUR LABEL ^^^  

を簡単に始める方法を次に示しFontMetricsます。そこでの喧嘩は避けてください。受け入れられた答えが言うことをするだけです:Java: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 に答える