JavaFx: одна и та же метка в двух (или более) местах в одном представлении

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

1
задан Sunflame 15 January 2019 в 09:31
поделиться

2 ответа

«Я действительно не хочу дублировать код, например: myLabel1, myLabel2, ..., поскольку все они имеют одинаковый текст / подсказку / стиль.» Что если вы просто создать несколько ссылок, указывающих на один и тот же объект метки?

Или расширить Label, включив в него конструктор копирования:

public MyLabel(MyLabel aLabel) {
this.property1 = aLabel.property1;
this.property2 = aLabel.property2;
...
}

Затем в FXML с помощью copy:

<MyLabel fx:id="myLabel1"/>
<fx:copy source="myLabel1"/>
0
ответ дан funkyjelly 15 January 2019 в 09:31
поделиться

Задача

Невозможно добавить одно и то же Label несколько раз в граф сцены. Это задокументировано в Node ( emphasis mine):

Узел может встречаться не более одного раза в любом месте графа сцены. В частности, узел должен появляться не более одного раза во всех следующих случаях: в качестве корневого узла в Scene, дочерних ObservableList в Parent или в качестве фрагмента Node.

Граф сцены не должен иметь циклов. Цикл будет существовать, если узел является предком самого себя в дереве, учитывая Group содержимое ObservableList, Parent children ObservableList и Node отношений клипа, упомянутых выше.

Если программа добавляет дочерний узел к Parent (включая Group, Region и т. Д.), И этот узел уже является дочерним по отношению к другому Parent или корню Scene ], узел автоматически (и без вывода сообщений) удаляется из своего прежнего родителя. Если программа пытается изменить граф сцены любым другим способом, который нарушает вышеуказанные правила, возникает исключение, попытка модификации игнорируется, и граф сцены восстанавливается в своем предыдущем состоянии.

Выделенная часть объясняет, почему Label появляется только один раз при использовании <fx:reference> .

Решение

Единственное решение вашей проблемы - дублирование Label. Для этого можно использовать как минимум два варианта.

Используйте <fx:copy>

Один из способов сделать это, используя <fx:copy> ( выделение шахта):

Элемент <fx:copy> создает копию существующего элемента. Как и <fx:reference>, он используется с атрибутом fx:id или переменной сценария. Атрибут «source» элемента указывает имя объекта, который будет скопирован. Тип источника должен определять конструктор копирования, который будет использоваться для создания копии из исходного значения.

На данный момент ни один из классов платформы JavaFX не предоставляет такой конструктор копирования, поэтому этот элемент предоставляется в первую очередь для использования разработчиками приложений. Это может измениться в будущем выпуске.

Как указано в документации, использование <fx:copy> требует, чтобы класс имел конструктор копирования. В документации также говорится, что ни один из основных классов JavaFX не предоставляет конструкторы копирования. Это означает, что вам придется создать подкласс Label и предоставить необходимый конструктор, как показано в ответе funkyjelly . Чтобы обеспечить актуальность свойств, вы можете связать свойства внутри конструктора:

public class CopyableLabel extends Label {

  public CopyableLabel(CopyableLabel label) {
    // You only mentioned the text, tooltip, and style properties
    // in your question. Bind more properties as needed.
    textProperty().bind(label.textProperty());
    tooltipProperty().bind(label.tooltipProperty());
    styleProperty().bind(label.styleProperty());
  }

}

Таким образом, вам нужно только ввести «master» Label, и любые обновления к нему будут распространяться на все копии. Используя этот дизайн, вы должны иметь в виду, что связанные свойства не могут быть установлены напрямую; попытка установить связанное свойство приведет к исключениям. Возможно, вы захотите задокументировать, что конструктор будет связывать свойства, а не просто копировать значения.

Использовать привязки выражений

Другой вариант - связать необходимые свойства в файле FXML. Вы все равно будете создавать несколько Label с, но вам нужно будет только ввести «master» Label, как и раньше.

<VBox xmlns="http://javafx.com/javafx/" xmlns:fx="http://javafx.com/fxml/1">

  <Label fx:id="master"/>
  <Label text="${master.text}" tooltip="${master.tooltip}" style="${master.style}"/>
  <Label text="${master.text}" tooltip="${master.tooltip}" style="${master.style}"/>
  <Label text="${master.text}" tooltip="${master.tooltip}" style="${master.style}"/>
  <!-- repeat as needed -->

</VBox>

Здесь используются возможности привязки выражений JavaFX FXML. Эта опция может загромождать файл FXML, но не требует создания подкласса Label.

0
ответ дан Slaw 15 January 2019 в 09:31
поделиться
Другие вопросы по тегам:

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