#java #javafx #fxml #scenebuilder
Вопрос:
Нужен ли @FXML для каждой декларации или только для первой?
Другими словами, должен ли я использовать
@FXML
public Label timerLabel = new Label();
@FXML
public TextField mainTextField, projectTextField ;
@FXML
public Button goButton, deleteAllButton ;
@FXML
public ComboBox<String> projectComboBox ;
@FXML
public TableView<Entry> mainTable ;
@FXML
public TableColumn<Entry, String> titleColumn, timeColumn, dateColumn ;
@FXML
public TableColumn<Entry, Boolean> checkColumn, buttonColumn ;
@FXML
public checkBox checkAllCheckBox ;
Или
@FXML
public Label timerLabel = new Label();
public TextField mainTextField, projectTextField ;
public Button goButton, deleteAllButton ;
public ComboBox<String> projectComboBox ;
public TableView<Entry> mainTable ;
public TableColumn<Entry, String> titleColumn, timeColumn, dateColumn ;
public TableColumn<Entry, Boolean> checkColumn, buttonColumn ;
public checkBox checkAllCheckBox ;
Спасибо!
Комментарии:
1. Попробуйте их обоих 😉
2. @Romeo Просто хочу отметить, что ваше заявление
public Label timerLabel = new Label();
с комментариями@FXML
неверно. Ссылки с аннотациями@FXML
инициализируются во время загрузки fxml и не должны инициализироваться извне.3. Что вы подразумеваете под «инициализировать метку времени»? Вы никогда не должны писать
timerLabel = new TimerLabel()
, если определение ссылки на метку времени было аннотировано@FXML
.4. На самом деле вам не нужны никакие
@FXML
аннотации, если ваши поля таковыpublic
. Конечно, вы все равно никогда не должны создавать эти поляpublic
; вы должны ихprivate
создавать , и в этом случае требуются все@FXML
аннотации. Но с кодом, как он есть, пропуск аннотаций не будет иметь никакого значения.5. Я думаю, что пришло время FXMLLoader зарегистрировать ошибку или предупредить, если поле с комментариями @FXML уже создано во время загрузки. Или используйте экземпляр, как в setController().
Ответ №1:
@FXML
Аннотация позволяет FXMLLoader
вводить значения, определенные в файле FXML, в ссылки в классе контроллера. Другими словами, если вы аннотируете свой timerLabel
с @FXML
, то он будет инициализирован, FXMLLoader
когда load()
метод вызывается элементом в файле FXML с. fx:id="timerLabel"
Как отмечали другие в комментариях, это означает, что вы никогда не должны писать такой код, как
@FXML
private Label timerLabel = new Label();
Здесь timerLabel
сначала будет инициализировано new Label();
значение, созданное вами в коде, а затем почти сразу же будет повторно инициализировано значение, определенное в файле FXML. Это в лучшем случае излишне, а в худшем-вводит в заблуждение. Если вы неправильно сопоставите имена переменных fx:id
, ваша переменная будет ссылаться на неправильную Label
, и ошибку будет очень трудно отследить.
Чтобы перейти к вашему актуальному вопросу:
Когда FXMLLoader
файл FXML загружается, он попытается ввести в контроллер любые элементы, имеющие fx:id
атрибут. Он будет искать
- Любое
public
поле с именем переменной, соответствующимfx:id
атрибуту, или - Любое поле (
public
или нет) с именем переменной, соответствующимfx:id
атрибуту, который аннотирован@FXML
.
Таким образом, в вашем примере , поскольку все ваши поля есть public
, вы можете опустить все @FXML
аннотации (даже первые), и это все равно будет работать.
Однако, если вы будете следовать надлежащей практике и создадите свои поля private
, то каждое объявление должно быть аннотировано @FXML
, чтобы инъекция работала.
Так
@FXML
private Label timerLabel;
@FXML
private TextField mainTextField;
и т. Д. Будет работать, но
@FXML
private Label timerLabel;
private TextField mainTextField;
не будет.
Комментарии:
1. Требуется ли инъекция? Есть ли способ просто запросить у загрузчика интересующий меня элемент управления (по fx:id)?
2. Не уверен, что понимаю этот вопрос. Разве не это именно то, что делает инъекция?
Ответ №2:
для каждого
fx:id="somename"
тебе нужна
@FXML
public SomeClass somename;
Я предпочитаю писать это в одной строке, потому что ее легче читать, когда их много
@FXML public SomeClass somename;
без инициализации
@FXML
public Label timerLabel = new Label(); // this is wrong
Комментарии:
1. не
timerLabel = new Label();
будет отменен анFXMLLoader
?2. Этот ответ вводит в заблуждение, поскольку
@FXML
он не нужен, когда поле открыто. Такpublic SomeClass somename;
что без@FXML
тоже работает, но вам это нужноsomename
, например, когда это неpublic
так@FXML private SomeClass somename;
.
Ответ №3:
@FXML
private TextField idTextField;
@FXML
private TextField passwordTextField;
или
@FXML
private TextField idTextField, passwordTextField;