Пользовательский компонент не отображается JavaFX [дубликат]

Собственно, подумайте об этом в другом случае. Предположим, что если ваш список таков:

[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]

, и если вы напишете myList[0][0] = 5, вы получите:

>>> 
[[5, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> 

Как и ожидалось. Но так как вы определяете свою переменную списка следующим образом:

[[1] * 4] * 3

Python обработает ваши коды по этому шаблону. Поэтому, если вы напишете myList[0][0] и ваш список, как указано выше, Python обработает его, как [1]*3. Вот почему все списки первых элементов изменены.

22
задан Freewind 12 May 2014 в 05:12
поделиться

1 ответ

<fx:root> обеспечивает решение проблемы определения повторно используемого компонента с помощью FXML.

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

VBox vbox = new VBox();
vbox.getChildren().add(new MyComponent());

. Проблема в том, что вам нужен класс Java, который является подклассом Node, а также FXML. В чистой Java (без FXML) вы можете сделать это с помощью:

public class MyComponent extends HBox {
    private TextField textField ;
    private Button button ;

    public MyComponent() {
        textField = new TextField();
        button = new Button();
        this.getChildren().addAll(textField, button);
    }
}

Использование FXML для определения настраиваемого компонента без элемента <fx:root> представляет проблему, потому что вам нужен FXML, чтобы быть чем-то вроде узла, а затем другой экземпляр узла для представления класса, обертывающего его:

<HBox>
<TextField fx:id="textField"/>
<Button fx:id="button" />
</HBox>

и

public class MyComponent extends HBox {
    @FXML
    private TextField textField ;
    @FXML
    private Button button ;
    public MyComponent() {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("MyComponent.fxml"));
            loader.setController(this);
            HBox hbox = loader.load();
            this.getChildren().add(hbox);
        } catch (IOException exc) {
            // handle exception
        }
    }
}

Это приводит к тому, что MyComponent состоит из HBox, обертывающего HBox, обертывающий TextField и кнопка. Дополнительный избыточный HBox является результатом необходимости использования одного узла для корня FXML и одного узла для представления компонента.

<fx:root> дает механизм для создания Узла в качестве компонента (класс Java) и затем проинструктировать файл FXML использовать этот узел в качестве его корня:

<fx:root type="javafx.scene.layout.HBox">
<TextField fx:id="textField" />
<Button fx:id="button" />
</fx:root>

и

public class MyComponent extends HBox {
    @FXML 
    private TextField textField ;
    @FXML
    private Button button ;
    public MyComponent() {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("MyComponent.fxml"));
            loader.setController(this);
            loader.setRoot(this);
            loader.load();
        } catch (IOException exc) {
            // handle exception
        }
    }
}

Теперь MyComponent имеет ту же структуру, что и исходная версия all-Java , a HBox, содержащий TextField и Button. Вы не можете сделать это с помощью FXML без элемента <fx:root>.

51
ответ дан James_D 21 August 2018 в 04:42
поделиться
  • 1
    И важная часть также заключается в том, что вы можете использовать MyComponent в других документах FXML, как и любой другой элемент управления. Вы можете создать целые иерархии, подобные этому. – Puce 6 September 2016 в 20:01
Другие вопросы по тегам:

Похожие вопросы: