12

テキストがオーバーランする可能性のある複数行のラベルがあります。これを行う場合は、オーバーランしなくなるまで、または最小サイズに達するまで、フォント サイズを小さくしたいと考えています。これにより、文字列全体が表示されるまでラベルのサイズが変更されることが期待されます。

私の問題は、テキストがオーバーランしたかどうかをテストする方法がわからないことです。ラベルのテキストが楕円文字列で終わるかどうかをテストしてみましたが、ラベルの textProperty に楕円が技術的に追加されていないと思います。それで、これをテストする良い方法を知っている人はいますか?

4

4 に答える 4

4

短く残念な答え: 信頼できる方法でこれを行うことはできません。

少し長い答えは、ラベル自体はオーバーフローしているかどうかさえ知らないということです。ラベルのサイズが変更されるたびに、スキン クラス ( LabeledSkinBase) が表示されるテキストを更新します。ただし、このクラスは JavaFX utils クラスを使用して、楕円形のテキストを計算します。ここでの問題は、ラベルの寸法で楕円体が必要な場合、それぞれのメソッドが楕円体の文字列を返すだけであることです。スキン自体は、テキストが実際に楕円体化されたかどうかについて通知されることはなく、表示されたテキストを返された結果に更新するだけです。

あなたが試すことができるのは、スキンクラスの表示されたテキストを確認することですが、それは保護されています. LabelSkinしたがって、 をサブクラス化し、そのようなものを実装する必要があります。

package com.sun.javafx.scene.control.skin;

import java.lang.reflect.Field;

import javafx.scene.control.Label;

@SuppressWarnings("restriction")
public class TestLabel extends LabelSkin {
  private LabeledText labelledText;

  public TestLabel(Label label) throws Exception {
    super(label);

    for (Field field : LabeledSkinBase.class.getDeclaredFields()) {
      if (field.getName().equals("text")) {
        field.setAccessible(true);
        labelledText = (LabeledText) field.get(this);
        break;
      }
    }
  }

  public boolean isEllipsoided() {
    return labelledText != null && labelledText.getText() != null && !getSkinnable().getText().equals(labelledText.getText());
  }
}

ラベルにこのスキンを使用すると、テキストが楕円体であるかどうかを検出できるはずです。ループとリフレクションについて疑問がある場合: Java では、他の方法でテキスト フィールドにアクセスすることはできませんでした。これは、これを行うべきではないことを示す強力な指標になる可能性があります ;-) それでも: 動作します!

免責事項:JavaFX 8のみを確認しました

于 2014-12-19T16:13:54.480 に答える
2

minisu は、この回答でオーバーランを検出する方法を投稿しました: https://stackoverflow.com/a/15178908/9492864

この方法はすべてのラベル付けで機能し、JavaFX 8 のボタンでテストしました。たとえば、needsLayoutProperty にリスナーを追加できます。

labeled.needsLayoutProperty().addListener((observable, oldValue, newValue) -> {
   String originalString = labeled.getText();
   Text textNode = (Text) labeled.lookup(".text"); // "text" is the style class of Text
   String actualString = textNode.getText();

   boolean clipped = !actualString.isEmpty() && !originalString.equals(actualString);

   System.out.println("is " + originalString + " clipped: " + clipped);
});
于 2018-06-08T08:25:02.120 に答える