Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

210
Vistas
Animar agregando componentes a un panel

Quiero implementar algún tipo de sistema de notificación en mi aplicación pero tengo problemas con el cálculo de la posición real de mi notificación. Todas las notificaciones deben aparecer en una etapa separada y cada notificación debe estar alineada entre sí y cada notificación es un VBox simple con dos etiquetas (título y mensaje).

Creé una pequeña aplicación independiente con el problema que tengo.

Tan pronto como presione el botón en el escenario principal, se creará un VBox y se agregará a una segunda etapa de notificación. Tan pronto como sea necesario agregar una segunda notificación, esta segunda notificación debe estar debajo de la primera notificación y así sucesivamente. Por lo tanto, necesito encontrar la altura de la primera notificación para colocar la segunda notificación debajo.

Sé que podría usar un VBox en su lugar, pero en mi aplicación la notificación debería hacer una animación fluida y empujar las otras notificaciones más abajo. Eliminé toda la animación y eliminé parte de las notificaciones para que el ejemplo sea lo más pequeño posible.

El problema es que todos los cuadros de notificación tienen la misma altura, pero no la tienen (si modifica el texto y lo hace más largo o más pequeño).

 package whatever; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.Pane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.stage.Screen; import javafx.stage.Stage; import javafx.stage.StageStyle; public class NotificationTest { private Stage notificationStage; private Pane contentPane; private static final Integer NOTIFICATION_WIDTH = 250; private Double notificationOffset = 0.0; private static final Integer SPACING_BETWEEN_NOTIFICATIONS = 20; public void start() { Stage mainStage = new Stage(); TextField textField = new TextField("Some long text for testing purpose with even more letters in oder to create at least one linebreak..."); Button button = new Button("Add Notification"); button.setOnAction(actionEvent -> { addNotification(textField.getText()); }); VBox vBox = new VBox(10); vBox.getChildren().addAll(textField, button); mainStage.setScene(new Scene(vBox, 300, 300)); mainStage.show(); } private void addNotification(String text) { if(notificationStage == null) { notificationStage = new Stage(); notificationStage.setWidth(NOTIFICATION_WIDTH); notificationStage.setHeight(Screen.getPrimary().getVisualBounds().getHeight() - 50); notificationStage.setX(Screen.getPrimary().getVisualBounds().getWidth() - 260); notificationStage.setY(50); contentPane = new Pane(); contentPane.setStyle("-fx-background-color: transparent"); notificationStage.setScene(new Scene(contentPane)); notificationStage.initStyle(StageStyle.TRANSPARENT); notificationStage.getScene().setFill(Color.TRANSPARENT); notificationStage.show(); } VBox notificationBox = new VBox(10); notificationBox.setMaxWidth(NOTIFICATION_WIDTH); notificationBox.setMinWidth(NOTIFICATION_WIDTH); notificationBox.setStyle("-fx-background-radius: 10; -fx-background-color: red"); notificationBox.getChildren().add(new Label("Title of Notification")); Label message = new Label(text); message.setWrapText(true); notificationBox.getChildren().add(message); notificationBox.setLayoutY(notificationOffset); contentPane.getChildren().add(notificationBox); // Needs to be done - otherwise the height would be 0 contentPane.layout(); System.out.println(notificationBox.getHeight()); notificationOffset += notificationBox.getHeight() + SPACING_BETWEEN_NOTIFICATIONS; } }

Usé la herramienta ScenicView para verificar la altura y dice que la altura es 79, pero System.out me dice que la altura es 10.4. El valor 79 parece correcto, pero ¿cómo puedo obtener este valor en mi aplicación?

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

La respuesta corta es use applyCss() :

 contentPane.applyCss(); contentPane.layout();

De la documentación:

Si es necesario, aplique estilos a este Nodo y sus elementos secundarios, si los hay. Este método normalmente no necesita invocarse directamente, pero puede usarse junto con Parent.layout() para dimensionar un Nodo antes del siguiente pulso.

La respuesta larga y mejor es usar un VBox o un ListView .

Para agregar animación de diseño, use LayoutAnimator.java . Puede encontrar más detalles aquí .

Editar: un mre de usar LayoutAnimator para animar notificaciones recién agregadas:

 import javafx.application.Application; import javafx.scene.*; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.stage.*; public class NotificationTest extends Application { private Stage notificationStage; private Pane contentPane; private static final int NOTIFICATION_WIDTH = 250, SPACING_BETWEEN_NOTIFICATIONS = 20; private static final String LONG_TEXT = "Some long text for testing purpose with even more letters in oder to create " + "at least one linebreak..."; private int counter = 0; @Override public void start(Stage mainStage) throws Exception { mainStage = new Stage(); TextField textField = new TextField(LONG_TEXT); Button button = new Button("Add Notification"); button.setOnAction(actionEvent -> { addNotification(textField.getText()); }); VBox vBox = new VBox(10, textField, button); mainStage.setScene(new Scene(vBox, 300, 300)); mainStage.show(); } private void addNotification(String text) { if(notificationStage == null) { notificationStage = new Stage(); notificationStage.setWidth(NOTIFICATION_WIDTH); notificationStage.setX(Screen.getPrimary().getVisualBounds().getWidth() - 260); notificationStage.setY(50); contentPane = new VBox(SPACING_BETWEEN_NOTIFICATIONS); contentPane.setStyle("-fx-background-color: transparent"); notificationStage.setScene(new Scene(contentPane)); notificationStage.initStyle(StageStyle.TRANSPARENT); //animate using LayoutAnimator https://gist.github.com/jewelsea/5683558 LayoutAnimator ly = new LayoutAnimator(); ly.observe(contentPane.getChildren()); notificationStage.show(); } VBox notificationBox = new VBox(10); notificationBox.setMaxWidth(NOTIFICATION_WIDTH); notificationBox.setMinWidth(NOTIFICATION_WIDTH); notificationBox.setStyle("-fx-border-color: black"); notificationBox.getChildren().add(new Label("Title of Notification")); Label message = new Label(counter++ + ": " +text); message.setWrapText(true); notificationBox.getChildren().add(message); contentPane.getChildren().add(0, notificationBox); } public static void main(String[] args) { launch(null); } }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda