2015-10-14 2 views
2

Допустим я следующее расположение:Сделать компонент видимым, когда удалось ложна

<VBox xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1"> 
    <children> 
     <TextField fx:id="textField" /> 
     <ListView fx:id="list" visible="true" /> 
    </children> 
</VBox> 

Как только я называю listView.setManaged(false) ListView не является невидимым, независимо от того, какое обрамление свойства я устанавливаю. Возможно, я пропустил некоторые.

Какие свойства я должен установить, чтобы увидеть ListView с этими образцами значений:
Left = 100
Top = 200
Ширина = 300
Высота = 400

+1

Но первый, почему вы хотите, чтобы установить ListView не удалось? –

+0

Это часть пользовательского компонента, и я не хочу, чтобы ListView занимал место. Он показан как вид наложения, служащий в качестве входа автозаполнения. Я знаю, что это может быть достигнуто другими способами. Тем не менее, я хочу понять, почему я не могу заставить это работать, и я хочу лучше понять JavaFX. – T3rm1

ответ

1

Решение

Оберните ListView в неуправляемом контейнере. Любой контейнер будет делать, например, Group или любой Pane или подкласс подкласса. Не устанавливайте сам режим ListView неуправляемым.

фон

неуправляемый в данном контексте, означает явный вызов setManaged(false) на узле контейнера. Это означает, что автоматическая компоновка отключена для узла, а код приложения пользователя должен явно управлять свойствами макета (например, размером и шириной узла и запросить автоматическую компоновку детей неуправляемого узла). Поэтому парадоксально, что ваш код приложения должен явно управлять макетом контейнера.

Если вы сделаете ListView сам неуправляемым, моя догадка (и это просто догадка) заключается в том, что это нарушает внутренний алгоритм компоновки для ListView и предотвращает корректное отображение ListView, поскольку компоненты внутри ListView, вероятно, ожидают для управления ListView.

Когда вы помещаете ListView в другой контейнер, который неуправляемый, тогда сам ListView по-прежнему управляется, поэтому его макет не разбивается, но макет не пересекается с обычным макетом сцены, а неуправляемый контейнер становится корнем для компоновки ListView. Таким образом, вы можете вручную установить местоположение и предпочтительный размер неуправляемого контейнера (и его дочерних элементов), эффективно достигнув цели создания макета для управления ListView.

Применимость

я отметил такое же поведение для других элементов управления, как TextField, так что это, вероятно, общий шаблон, который может быть использован для неуправляемого отображения какого-либо контроля.

Также обратите внимание, что этот запрос несколько необычен. Для большинства приложений неуправляемые элементы управления не требуются. Встроенные менеджеры макетов могут обрабатывать большое количество макетов. Когда требуется настраиваемый макет, метод должен создать собственный менеджер макетов (например, новый подкласс Pane) и переопределить layoutChildren() и методы computePrefHeight/computePrefWidth/computeMinHeight/computeMinWidth. Это позволяет вашему приложению или компоненту взаимодействовать дружелюбно с автоматической системой компоновки JavaFX. Для примера такого функционального стиля просмотрите код встроенных менеджеров макета, например StackPane.

Образец

Вот пример приложения, чтобы продемонстрировать эти принципы и достижения проклейки и размещения целей, заявленных для ListView в вашем вопросе.Я оценил скриншот на половину размера, чтобы он не занимал слишком много места. Измерения немного обманчивы, так как визуально для меня это не похоже, что список размещен на 100, 200 с размером 300, 400, но я измерил его в графическом приложении, и он помещается и имеет размер, как ожидалось.

unmanaged

import javafx.application.Application; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class Unmanageable extends Application { 
    @Override 
    public void start(final Stage stage) throws Exception { 
     TextField textField = new TextField(); 

     ListView<String> listView = new ListView<>(); 
     listView.getItems().addAll("Sally", "Sells", "Seashells", "At", "The", "Seashore"); 
     listView.setStyle("-fx-base: lightcoral;"); 

     Group unmanagedContainer = new Group(listView); 
     unmanagedContainer.setManaged(false); 
     unmanagedContainer.relocate(100, 200); 

     listView.setMinSize(ListView.USE_PREF_SIZE, ListView.USE_PREF_SIZE); 
     listView.setPrefSize(300, 400); 
     listView.setMaxSize(ListView.USE_PREF_SIZE, ListView.USE_PREF_SIZE); 

     VBox layout = new VBox(textField, unmanagedContainer); 
     layout.setMinSize(600, 800); 
     layout.setStyle("-fx-background-color: azure;"); 

     stage.setScene(new Scene(layout)); 
     stage.show(); 

     System.out.println(unmanagedContainer.getBoundsInParent()); 
    } 

    public static void main(String[] args) throws Exception { 
     launch(args); 
    } 
} 

Выход:

BoundingBox [minX:100.0, minY:200.0, minZ:0.0, width:300.0, height:400.0, depth:0.0, maxX:400.0, maxY:600.0, maxZ:0.0] 
+0

Большое спасибо за ваши усилия. Я могу следовать твоей догадке, и я думаю, что это правдоподобно. – T3rm1

Смежные вопросы