2015-11-20 4 views
1

Я использую TextFlow с текстом внутри настраиваемого элемента управления JavaFX, и этот элемент управления помещается в TitledPane.TitledPane не изменяется по вертикали при использовании TextFlow в настраиваемом элементе управления

декларация управления:

public class CustomControl extends Control { 
    @Override 
    protected Skin<?> createDefaultSkin() { 
     return new CustomControlSkin(this); 
    } 
} 

декларация кожи:

public class CustomControlSkin extends SkinBase<CustomControl> implements Skin<CustomControl> { 
    public CustomControlSkin(CustomControl customControl) { 
     super(customControl); 
     TextFlow textFlow = new TextFlow(); 
     textFlow.getChildren().add(new Text("This is a long long long long long long long long long long long long long long text")); 
     getChildren().add(new StackPane(textFlow)); 
    } 
} 

Применение:

@Override 
public void start(Stage primaryStage) throws Exception { 
    TitledPane titledPane = new TitledPane(); 
    titledPane.setContent(new CustomControl()); 
    Scene scene = new Scene(new StackPane(titledPane)); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

Когда Scene получить изменения размеров по горизонтали, Текст получает завернуты и его высота увеличивается. Тем не менее, TitledPane не изменяется по вертикали.

TextFlow used in a custom control

Это не происходит, когда TextFlow помещается непосредственно в TitledPane без использования пользовательского элемента управления.

TextFlow used directly in the TitledPane

Использование Scenic View я заметил, что когда TextFlow используется в пользовательском элементе управления, расположение границы элемента управления отличаются от оценок в родителей. Собственно, границы в родительском языке, по-видимому, правильно вычислены, но не используются.

Scene graph

Это может быть источником этой проблемы. Я экспериментировал, все будут вычислять методы (Min/Pref/Max) Height, но не смогли правильно изменить размер TitledPane.

Любая идея, почему TextFlow ведет себя по-разному при использовании в пользовательском элементе управления/скине и как правильно изменить размер TitledPane?

ответ

1

Я доложил об этой проблеме Oracle, и это было принято как ошибка JavaFX: JDK-8144128

В качестве обходного пути для этой ошибки, я сделал следующее:

  • Установить смещение содержимого управления для ориентации .HORIZONTAL

    public class CustomControl extends Control { 
        @Override 
        protected Skin<?> createDefaultSkin() { 
         return new CustomControlSkin(this); 
        } 
    
        @Override 
        public Orientation getContentBias() { 
         return Orientation.HORIZONTAL; 
        } 
    } 
    
  • computeMinHeight Переопределение кожи, чтобы использовать ширину узла вместо -1 при вызове node.minHeight

    public class CustomControlSkin extends SkinBase<CustomControl> implements Skin<CustomControl> { 
        public CustomControlSkin(CustomControl customControl) { 
         super(customControl); 
         TextFlow textFlow = new TextFlow(); 
         textFlow.getChildren().add(new Text("This is a long long long long long long long long long long long long long long text")); 
         getChildren().add(new StackPane(textFlow)); 
        } 
    
        @Override 
        protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { 
         double minY = 0; 
         double maxY = 0; 
         boolean firstManagedChild = true; 
         for (int i = 0; i < getChildren().size(); i++) { 
          Node node = getChildren().get(i); 
          if (node.isManaged()) { 
           final double y = node.getLayoutBounds().getMinY() + node.getLayoutY(); 
           if (!firstManagedChild) { 
            minY = Math.min(minY, y); 
            maxY = Math.max(maxY, y + node.minHeight(width)); 
           } else { 
            minY = y; 
            maxY = y + node.minHeight(width); 
            firstManagedChild = false; 
           } 
          } 
         } 
         double minHeight = maxY - minY; 
         return topInset + minHeight + bottomInset; 
        } 
    }