Javafx: la misma etiqueta en dos (o más) lugares en la misma vista -- java campo con javafx campo con javafx-8 campo con fxml camp Relacionados El problema

JavaFx: Same Label in two(or more) places in the same view


1
vote

problema

Español

No sé si extraño algo, pero no puedo lograrlo, tengo la misma etiqueta dos veces o más en la misma vista. Realmente no quiero duplicarlo, simplemente use la misma etiqueta con el mismo texto / herramienta / estilo.

Un ejemplo simple:

  <?xml version="1.0" encoding="UTF-8"?>  <?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.control.Label?> <AnchorPane xmlns="http://javafx.com/javafx"             xmlns:fx="http://javafx.com/fxml"             fx:controller="stackoverflow.dummy.Controller">         <Label fx:id="myLabel"/>         <!--<Label fx:id="myLabel"/>-->  ofc this doesn't work.         <!--<Label fx:id="myLabel"/>--> </AnchorPane>   

Si lo intento con <fx:reference> aparece una sola vez, si lo intento con <fx:copy> dice que necesito un constructor de copia, así que creo que simplemente extraño una solución fácil. Debería existir.

NOTA: Realmente no quiero desear duplicar el código como: MyLabel1, Mylabel2, ..., ya que todos ellos tienen el mismo texto / herramienta / estilo.

También sé que puedo crear un archivo .fxml3 separado donde creo la etiqueta y la use a través de <fx:include> , pero preferiría resolverlo en el mismo .fxml Dado que es una cosa realmente simple, creo que no vale la pena crear un nuevo .fxml6 solo para esto.

Original en ingles

I don't know if I miss something, but I cannot manage to achieve that, I have the same label twice or more on the same view. I don't really want to duplicate it just use the same label with the same text/tooltip/style.

A simple example:

<?xml version="1.0" encoding="UTF-8"?>  <?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.control.Label?> <AnchorPane xmlns="http://javafx.com/javafx"             xmlns:fx="http://javafx.com/fxml"             fx:controller="stackoverflow.dummy.Controller">         <Label fx:id="myLabel"/>         <!--<Label fx:id="myLabel"/>-->  ofc this doesn't work.         <!--<Label fx:id="myLabel"/>--> </AnchorPane> 

If I try with <fx:reference> it appears only once, if I try with <fx:copy> it says I need a copy constructor, so I think I simply miss some easy solution. It should exist.

Note: I don't really want want to duplicate the code like: myLabel1, myLabel2, ..., since all of them are having the same text/tooltip/style.

I also know I can create a separate .fxml file where I build the label and use it via <fx:include> but I would prefer solving it in the same .fxml since it is a really simple thing I think it doesn't worth creating a new .fxml only for this.

           

Lista de respuestas

3
 
vote
vote
La mejor respuesta
 

Problema

No es posible agregar el mismo Label varias veces al gráfico de escena. Esto está documentado por Node ( énfasis Mine):

Un nodo puede ocurrir como máximo en cualquier lugar de la gráfica de escena. Específicamente, un nodo debe aparecer más de una vez en todos los siguientes: como el nodo raíz de un Scene , los niños ObservableList de un Parent , o como el clip de un Node .

La gráfica de escena no debe tener ciclos. Existiría un ciclo si un nodo es un antepasado de sí mismo en el árbol, teniendo en cuenta el contenido CONTENIDO ObservableList , Parent NIÑOS ObservableList < / Código>, y Node0 Relaciones clip mencionadas arriba.

Si un programa agrega un nodo secundario a un Node11111 (incluyendo Node2 , Node3 , etc.) y ese nodo ya está Un niño de un Group14 Node4 Group15 Si un programa intenta Modifique la gráfica de escena de cualquier otra forma que viole las reglas anteriores, se lanza una excepción, el intento de modificación se ignora y el gráfico de escena se restaura a su estado anterior.

La parte enfatizada explica por qué el Node6616 aparece una vez cuando se usa Node7 .

SOLUCIÓN

La única solución a su problema es duplicar el Node8 . Hay al menos dos opciones que puede usar para lograr esto.

Uso Node9

Una forma de hacerlo usando Scene0 ( énfasis Mine):

El elemento Scene1 crea una copia de un elemento existente. Como Scene2 , se utiliza con el atributo Group23 o una variable de script. El atributo "fuente" del elemento especifica el nombre del objeto que se copiará. El tipo de origen debe definir un constructor de copia que se utilizará para construir la copia del valor de origen.

En este momento, ninguna clase de plataforma Javafx proporciona un constructor de este tipo de copia, por lo que este elemento se proporciona principalmente para su uso por desarrolladores de aplicaciones. Esto puede cambiar en una versión futura.

Como se indica en la documentación, el uso de Scene4 requiere que la clase tenga un constructor de copia. La documentación también establece que ninguna de las clases principales de Javafx proporciona constructores de copia. Esto significa que tendrá que subclase Scene5 y proporcionar el constructor necesario, como se muestra en respuesta de FunkyJelly . Para garantizar que las propiedades permanezcan actualizadas, puede enlazar las propiedades dentro del constructor:

  Scene6  

De esa manera, solo necesita inyectar el "Master" Scene7 y cualquier actualización, se propagará a todas las copias. Usando este diseño, debe tener en cuenta que las propiedades enlazadas no se pueden configurar directamente; Tratar de establecer una propiedad encuadernada resultará en excepciones. Es posible que desee documentar el constructor se unirá las propiedades, no solo copiar los valores.

Use los enlaces de expresión

Otra opción es unir las propiedades necesarias en el archivo FXML. Aún estaría creando múltiples Scene8 S, pero solo necesitaría inyectar el "Master" Scene9 , como antes.

  ObservableList0  

Esto utiliza el vinculación de expresión capacidades de javafx fxml. Esta opción puede desordenar el archivo FXML, pero no requiere que cree una subclase de ObservableList1 .

 

Problem

It is not possible to add the same Label multiple times to the scene graph. This is documented by Node (emphasis mine):

A node may occur at most once anywhere in the scene graph. Specifically, a node must appear no more than once in all of the following: as the root node of a Scene, the children ObservableList of a Parent, or as the clip of a Node.

The scene graph must not have cycles. A cycle would exist if a node is an ancestor of itself in the tree, considering the Group content ObservableList, Parent children ObservableList, and Node clip relationships mentioned above.

If a program adds a child node to a Parent (including Group, Region, etc) and that node is already a child of a different Parent or the root of a Scene, the node is automatically (and silently) removed from its former parent. If a program attempts to modify the scene graph in any other way that violates the above rules, an exception is thrown, the modification attempt is ignored and the scene graph is restored to its previous state.

The emphasized part explains why the Label only appears once when using <fx:reference>.

Solution

The only solution to your problem is to duplicate the Label. There are at least two options you can use to accomplish this.

Use <fx:copy>

One way to do this by using <fx:copy> (emphasis mine):

The <fx:copy> element creates a copy of an existing element. Like <fx:reference>, it is used with the fx:id attribute or a script variable. The element's "source" attribute specifies the name of the object that will be copied. The source type must define a copy constructor that will be used to construct the copy from the source value.

At the moment, no JavaFX platform classes provide such a copy constructor, so this element is provided primarily for use by application developers. This may change in a future release.

As stated in the documentation, using <fx:copy> requires the class to have a copy constructor. The documentation also states that none of the core JavaFX classes provide copy constructors. This means you'll have to subclass Label and provide the needed constructor, as shown in funkyjelly's answer. To ensure the properties stay up-to-date you can bind the properties inside the constructor:

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());   }  } 

That way you only need to inject the "master" Label and any updates to it will be propagated to all the copies. Using this design you must keep in mind that bound properties cannot be set directly; trying to set a bound property will result in exceptions. You might want to document the constructor will bind the properties, not just copy the values.

Use Expression Bindings

Another option is to bind the needed properties in the FXML file. You would still be creating multiple Labels but you would only need to inject the "master" Label, as before.

<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> 

This uses the expression binding capabilities of JavaFX FXML. This option may clutter the FXML file but it doesn't require you to create a subclass of Label.

 
 
 
 
0
 
vote

"Realmente no quiero que desee duplicar el código como: MyLabel1, Mylabel2, ..., ya que todos ellos tienen el mismo texto / herramienta / estilo". y si usted ¿Simplemente cree múltiples referencias apuntando al mismo objeto de etiqueta?

o extensión de la etiqueta para incluir un constructor de copia:

  ObservableList2  

luego en FXML usando Copiar:

  ObservableList3  
 

"I don't really want want to duplicate the code like: myLabel1, myLabel2, ..., since all of them are having the same text/tooltip/style." What if you just create multiple references pointing to the same label object ?

Or extend Label to include a copy constructor :

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

Then in FXML using copy:

<MyLabel fx:id="myLabel1"/> <fx:copy source="myLabel1"/> 
 
 
     
     

Relacionados problema

1  Comunicación Javafx entre controladores  ( Javafx communication between controllers ) 
Soy nuevo en JavaFX , por lo que necesito ayuda para compartir datos entre dos controladores. Tengo una ventana simple que tiene un menú simple: @FXML L...

0  Las opciones de checkcombobox están vacías  ( Checkcombobox choices are empty ) 
Hola, estoy aprendiendo Javafx y quiero crear un menú desplegable con múltiples selecciones. Creo que necesito usar checkcombobox. Lo implemento, pero no most...

0  Rellene un camino SVG con evento OnMouseEntered en Javafx  ( Refill a svg path with onmouseentered event in javafx ) 
Estoy trabajando en un proyecto personal que incluye un documento .fxml (creado a partir de un archivo .svg con NetBeans). Aquí está el mapa como puedas Ver...

0  ¿Cómo impide que un control etiquetado cambie el tamaño de otros componentes cuando se cambie su texto?  ( How do i prevent a labeled control from resizing other components when its text ) 
Como lo implica el título, cuando cambio el texto de un javafx.scene.control.label, cambia el tamaño de todos los componentes que están contenidos en el mismo...

2  JAVAFX Forma Cambia el tamaño dinámico  ( Javafx shape resize dynamically ) 
Necesito tener un anclorpano con un derrame cerebral a su alrededor que cambie de tamaño cuando se cambie la etapa, déjame poner algunas imágenes para explica...

1  La propiedad anotada con @fxml es nula cuando uso Spring Security y Javafx  ( Property anottated with fxml is null when i use spring security and javafx ) 
Estoy desarrollando una aplicación Javafx con seguridad de primavera habilitada en ella. Luego, he creado un formulario FXML que tiene un campo de texto con I...

1  ¿Constantes reutilizables para diseños FXML?  ( Reusable constants for fxml layouts ) 
Esto es algo un seguimiento a mi anterior Pregunta . De alguna manera, obtuve la solución para mi pregunta de aquí , pero nunca respondió realmente a mi pre...

5  Javafx 2 - Escribe un objeto principal al archivo FXML  ( Javafx 2 write parent object to fxml file ) 
Sé que puedo cargar un archivo FXML en un objeto principal con lo siguiente: parent = FXMLLoader.load(getClass().getResource(fxmlFile.getAbsolutePath()...

32  ¿Cómo controlar el retraso de Javafx ToolTip?  ( How to control the javafx tooltips delay ) 
Estaba jugando con 'código> javafx Tooltip . Me di cuenta de que para mí personalmente el retraso entre el flujo de sobre algo y la información sobre herram...

0  Javafx 2.2 Cómo Setlowerbound y SetupperBound en Dateaxis en LinChart generado por FXML  ( Javafx 2 2 how to setlowerbound and setupperbound in dateaxis in linechart gener ) 
Tengo un diseño de WHIT JAVAFX SCENE SCENEBRY para mi solicitud. En mi linecho, dano algunos gráficos dependiendo de las fechas. Por defecto, Javafx LinChart ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos