Test for Label overrun

前端 未结 4 2444
慢半拍i
慢半拍i 2021-02-20 09:58

I have a multiline label whose text has a chance of overrunning. If it does this, I want to decrease the font size until it isn\'t overrunning, or until it hits some minimum siz

4条回答
  •  无人及你
    2021-02-20 10:17

    The short and disappointing answer: You simply cannot do this in a reliable way.

    The slightly longer answer is, that the label itself does not even know whether it's overflown or not. Whenever a label is resized, the skin class (LabeledSkinBase) is responsible for updating the displayed text. This class, however, uses a JavaFX utils class to compute the ellipsoided text. The problem here is that the respective method just returns a string that is ellipsoid if this is required by the label's dimensions. The skin itself never gets informed about whether the text was actually ellipsoided or not, it just updates the displayed text to the returned result.

    What you could try is to check the displayed text of the skin class, but it's protected. So you would need to do is to subclass LabelSkin, and implement something like that:

    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());
      }
    }
    

    If you use this skin for you Label, you should be able to detect whether your text is ellipsoided. If you wonder about the loop and the reflection: Java didn't allow me to access the text field by other means, so this may be a strong indicator that you really should not do this ;-) Nevertheless: It works!

    Disclaimer: I've only checked for JavaFX 8

提交回复
热议问题