tutorial ejemplos descargar javafx

ejemplos - javafx tutorial



Usabilidad de las propiedades de JavaFX fuera del alcance de la vista de la GUI (2)

Me encontré con esto hoy y fue útil que alguien señalara los hilos. Los errores causados ​​por esto pueden ser insidiosos.

Estoy usando esta solución extensivamente. No puede enlazar Bidirectional con ThreadSafeObjectProperty, pero puede vincularse a una propiedad de FX y actualizarla utilizando ThreadSafePropertySetter.

Los setters devuelven un futuro. Que se puede usar para controlar las condiciones de carrera causadas por Platform.runLater.

Está en Scala:

class SafePublishProperty[T](init: T) { val writable = new ReadOnlyObjectWrapper[T](init) def readOnly: ObjectExpression[T] = writable.getReadOnlyProperty } class ThreadSafeBooleanProperty(init: Boolean) { protected val property = new ReadOnlyBooleanWrapper(init) def value: BooleanExpression = property.getReadOnlyProperty def setValue(value: Boolean): Future[Boolean] = { val promise = Promise[Boolean] if (Platform.isFxApplicationThread) { property.setValue(value) promise.success(true) } else try { Platform.runLater(() => { property.setValue(value) promise.success(true) }) } catch { case _: IllegalStateException => property.setValue(value) promise.success(true) } promise.future } } class ThreadSafeObjectProperty[T](init: T) { protected val property = new SafePublishProperty[T](init) def value: ObjectExpression[T] = property.readOnly def setValue(value: T): Future[Boolean] = { val promise = Promise[Boolean] if (Platform.isFxApplicationThread) { property.writable.setValue(value) promise.success(true) } else { try { Platform.runLater(() => { property.writable.setValue(value) promise.success(true) }) } catch { case _: IllegalStateException => property.writable.setValue(value) promise.success(true) } } promise.future } } object ThreadSafePropertySetter { def execute(function: () => Unit): Future[Boolean] = { val promise = Promise[Boolean] if (Platform.isFxApplicationThread) { function.apply() promise.success(true) } else { try { Platform.runLater(() => { function.apply() promise.success(true) }) } catch { case ex: IllegalStateException => function.apply() promise.success(true) } } promise.future } }

Uso típico:

class SomeExample { private val propertyP = new ThreadSafeBooleanProperty(true) def property: BooleanExpression = propertyP.value private class Updater extends Actor { override def receive: Receive = { case update: Boolean => propertyP.setValue(update) } } }

Después de trabajar algún tiempo con JavaFX (Java8), encontré que el concepto de Propiedades es muy útil, lo que permite usar variables que cumplen con los requisitos para estar obligado a actualizar los cambios usando un árbol de cálculo, por ejemplo:

class Person { StringProperty name; ... } Person owner; Person human; owner.name().bind(human.name());

Eso permite vincular los controles de la GUI al ''modelo'', para actualizar automáticamente en el cambio.

Entonces comencé a usar Propiedades también en el modelo (mis objetos de datos estoy haciendo mis operaciones funcionales). Pero el JavaFX es una implementación de interfaz gráfica de usuario única y la configuración de dicha propiedad vinculada a algunos controles de la GUI solo está permitida, si se realiza en el hilo de JavaFX. De lo contrario, se lanzará una excepción:

Exception in thread "Thread-5" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-5

Si ahora comienzo a escribir código multiproceso, finalmente no puedo usar estas Propiedades, incluso si me encantaría. No puedo permitirme encapsular cada cambio en una llamada Platform.runLater () para pasarlo al hilo de JavaFX.

¿Por qué JavaFX no proporciona un enlace de propiedad seguro para subprocesos? (¿O si?)


Usabilidad de las propiedades de JavaFX fuera del alcance de la vista de la GUI

Las propiedades de JavaFX definitivamente se pueden usar fuera del alcance de la vista de la GUI. El tutorial básico de Oracle JavaFX binding demuestra esto al crear un programa java no GUI simple que representa un objeto Bill donde el monto total de la factura se expone a través de una propiedad JavaFX.

¿Por qué JavaFX no proporciona un enlace de propiedad seguro para subprocesos? (¿O si?)

JavaFX no es compatible con el enlace de propiedad seguro para subprocesos. Probablemente la razón por la que no es compatible con el enlace de propiedad seguro para subprocesos es porque no es necesario.

Aunque JavaFX internamente tiene una arquitectura de subprocesos múltiples con un subproceso de representación, un subproceso de aplicación, etc., externamente a los desarrolladores, realmente solo expone el subproceso de aplicación única. Desde el punto de vista de un desarrollador, el desarrollador codifica su aplicación como un único sistema de subprocesos. El desarrollador y las implementaciones internas de JavaFX pueden suponer que todo se ejecuta en un entorno de subproceso único y la codificación es mucho más simple (consulte Conjuntos de herramientas de subprocesamiento múltiple: un sueño fallido) y Cómo ejecutar dos UI de JavaFX en subprocesos diferentes reales para obtener información de fondo sobre por qué este es el caso). La implementación de la propiedad, sabiendo que se está ejecutando en dicho entorno, también puede asumir una única arquitectura de subprocesos y omitir los controles de seguridad de subprocesos incorporados.

JavaFX tiene la capacidad de engendrar nuevos hilos para tareas concurrentes (y también se puede usar cualquiera de las muchas instalaciones concurrentes para el desarrollo estándar de Java). La API concurrente de JavaFX tiene la capacidad de retroalimentar los valores de las propiedades (como el porcentaje de trabajo realizado para la ejecución de tareas) de manera segura para hilos, pero eso se hace de una manera muy específica. La API de tarea tiene métodos especializados para modificar tales propiedades (por ejemplo, progreso de actualización ) e internamente utiliza comprobaciones de hilos y llamadas como Platform.runLater para garantizar que el código se ejecute de manera segura para hilos.

Por lo tanto, las utilidades de simultaneidad JavaFX no logran la seguridad de subprocesos a través de las capacidades integradas del mecanismo de propiedad JavaFX, sino que a través de comprobaciones y llamadas explícitas dentro de la implementación de utilidad de simultaneidad para un conjunto de propiedades muy específico y limitado. Incluso entonces, los usuarios deben tener mucho cuidado al usar estas utilidades ya que a menudo asumen que pueden hacer cosas como modificar las propiedades de la etapa GUI de JavaFX directamente desde sus tareas simultáneas (aunque la documentación indica que esto no debe hacerse); se debe tener el mismo cuidado si se utilizan utilidades concurrentes Java estándar como el paquete java.util.concurrent en lugar de javafx.concurrent.

Es posible que alguien pueda crear una extensión del mecanismo de propiedad JavaFX para comportarse mejor en un entorno seguro para subprocesos, pero nadie ha creado tal extensión hasta la fecha.

Pero el JavaFX es una implementación de interfaz gráfica de usuario única y la configuración de dicha propiedad vinculada a algunos controles de la GUI solo está permitida, si se realiza en el hilo de JavaFX.

El título de la pregunta es "Usabilidad de las propiedades de JavaFX fuera del alcance de la vista de GUI", pero el problema particular que describes es un subconjunto bastante específico de esto, donde creo que tienes la siguiente combinación de cosas:

  1. Propiedades en una clase modelo.
  2. Las propiedades de la clase de modelo se pueden leer y escribir mediante la secuencia de la aplicación JavaFX u otra cadena de usuario.
  3. Las propiedades de la clase de modelo pueden vincularse a elementos de la GUI activa, como el texto en un campo de texto o una etiqueta que se muestra en la pantalla.

De fábrica, esto no funcionará porque el sistema JavaFX asume que las propiedades de los componentes de la GUI de JavaFX solo se leen o modifican en la cadena de aplicaciones JavaFX. Además, internamente para soportar oyentes de enlace y cambio, las propiedades mismas necesitan mantener listas de oyentes y propiedades enlazadas para modificar, y estas listas probablemente suponen que solo se accederá a ellas o se modificarán a partir de un único hilo. Quizás pueda evitar esto asegurándose de que cada lectura o escritura se realice en un solo hilo al envolver las invocaciones usando Platform.runLater para realizar la llamada en el subproceso de la aplicación JavaFX, pero a partir de su pregunta, este es exactamente el tipo de código que usted es tratando de evitar

IMO para el caso de uso que describí en los puntos anteriores, no hay otra solución y se debe usar el ajuste Platform.runLater. Es posible ocultar parte de la complejidad y repetición de las llamadas a runLater al proporcionar métodos de fachada para acceso a propiedades y actualizaciones (similar a la implementación de Tarea concurrente JavaFX), pero tal sistema es probablemente un poco complejo de implementar (especialmente si desea lograr una solución genérica para toda la propiedad / subsistema de enlace, en lugar de una solución especializada para un par de propiedades específicas como la tarea tiene).

¿Cuáles son las propiedades de JavaFX para entonces?

El primer caso de uso existente es para soportar el modelo de programación GUI basado en enlace para aplicaciones de GUI JavaFX. Las propiedades de JavaFX se usan ampliamente con la API de JavaFX y cualquier aplicación que use esa API.

Como JavaFX ahora se incluye en todas las nuevas distribuciones Oracle JDK estándar, también puede usar las propiedades de programas que no son JavaFX. Por ejemplo, hay discusiones sobre cómo usar estas propiedades en beans de entidad JPA, por ejemplo . Estos casos de uso de la API que no son JavaFX son actualmente muy raros en mi experiencia.

Aunque las propiedades JavaFX y los paquetes de enlace se encuentran dentro del espacio de nombres del paquete javafx, no dependen de otros paquetes JavaFX. En un futuro JDK modular, como se propone que sea Java 9, sería posible tener un programa Java que dependa de un módulo de propiedad y vinculación JavaFX y no tener ninguna dependencia de otros módulos para el desarrollo de la GUI JavaFX (que podría ser útil para ciertos sistemas de servidor sin cabeza, que son el objetivo principal de implementación para muchas aplicaciones Java).

Un diseño similar fue configurado originalmente para otras instalaciones JavaFX como las líneas de tiempo y las transiciones, de modo que un sistema Java en tiempo real con programación de tareas basada en tiempo a través de Timelines podría hacer uso de un módulo de animación / línea de tiempo de JavaFX sin depender del resto. el sistema JavaFX (pero no estoy seguro de que el diseño original haya llegado hasta hoy, por lo que ya no es posible y el pulso de base del módulo de animación generalmente está codificado al mínimo de 60 fps tal vez bloqueado a una frecuencia de actualización de pantalla) dependiendo de la implementación).

Las propiedades de JavaFX no son la solución genérica para la administración de propiedades para Java, pero probablemente sean la implementación más cercana y completa de una solución de este tipo que he visto hasta ahora. Lo ideal (como recuerdo que el líder del proyecto JavaFX, Richard Bair) es que la funcionalidad de la propiedad estaría integrada en el lenguaje de programación Java, por lo que el soporte proviene no solo de una API, sino también de una sintaxis de lenguaje mejorada. Tal vez alguna versión futura de Java, como 10+, pueda tener instalaciones como estas. Por supuesto, esa es una vieja discusión que probablemente se remonta al comienzo del lenguaje Java y las especificaciones JDK. Aún así, el mundo no es ideal y el mecanismo de propiedad JavaFX (incluso con su tipo de sintaxis voluminosa y la falta de soporte incorporado para seguridad de subprocesos), sigue siendo una herramienta útil para muchas aplicaciones. También tenga en cuenta que hay extensiones para otros idiomas como Scala a través de ScalaFX que hacen que el mecanismo de propiedad JavaFX parezca parte de la sintaxis para ese idioma.

Las bibliotecas de terceros como EasyBind mejoran el mecanismo de propiedad JavaFX para admitir mejor los paradigmas de programación, como la programación reactiva funcional.

Por ahora, si quisiera hacer un uso extensivo de las instalaciones de tipo de propiedad en un programa JavaFX, probablemente lo basaría en una combinación de propiedades JavaFX y (potencialmente) EasyBind y ReactFX , ya que parece ser la mejor solución para Java.

No utilizaría una solución de este tipo en un entorno altamente concurrente en el que el subprocesamiento no esté dividido en compartimentos debido a la falta de soporte de seguridad de subprocesos en las bibliotecas subyacentes. Las propiedades se basan en cambios de efectos secundarios en objetos mutables, lo cual es una cosa bastante difícil de razonar en los programas de subprocesos múltiples. Incluso si la implementación de la propiedad interna se modificó para permitir lecturas / escrituras seguras para hilos en las propiedades, no estoy seguro de que sea un enfoque tan bueno. Para sistemas altamente concurrentes que requieren mucha comunicación entre subtareas concurrentes, el uso de otro paradigma de programación como Actores (por ejemplo, akka / erlang ) o la comunicación de procesos secuenciales puede ser más apropiado que las propiedades vinculadas.