2012-09-12 17 views
5

He estado tratando de trabajar con la transformación de escalado en JavaFX, pero no he sido capaz de entenderlo. Básicamente, tengo un Panel que contiene un gráfico complejo y me gustaría poder reescalarlo. La parte de escalado funciona bien, sin embargo, el panel de desplazamiento adjunto no se adaptará al gráfico.Escalado en JavaFX y ScrollPanes

Por razones de simplicidad, voy a publicar un breve ejemplo en el que mi gráfica se sustituye por una etiqueta:

public class TestApp extends Application { 
    @Override public void start(final Stage stage) throws Exception { 
     final Label label = new Label("Hello World"); 
     label.getTransforms().setAll(new Scale(0.5, 0.5)); 

     label.setStyle("-fx-background-color:blue"); 
     label.setFont(new Font(200)); 

     final ScrollPane scrollPane = new ScrollPane(); 
     scrollPane.setContent(label); 

     stage.setScene(new Scene(scrollPane)); 
     stage.setWidth(200); 
     stage.setHeight(100); 
     stage.show(); 
    } 

    public static void main(String[] args) { 
     Application.launch(args); 
    } 
} 

la etiqueta se escala correctamente, pero las barras del panel de desplazamiento que encierra todavía habrá cabida a un componente de el tamaño original.

que he probado hasta ahora:

  • Jugando con las etiquetas min y tamaño pref
  • envolviendo la etiqueta dentro de un grupo (no hay barras de desplazamiento aparecerán en absoluto)
  • escalar el Grupo encierra en vez que la etiqueta

¿Qué me falta? ¿Qué puedo hacer para que el ScrollPane se adapte a la vista de contenido?

Gracias por su ayuda.

+0

escalable, panel de desplazamiento pannable: https://stackoverflow.com/a/44314455/1386911 –

Respuesta

3

Implementé la escala en un ScrollPane para Gráficos y otros nodos en this example of scrollpane viewports, transforms and layout bounds in JavaFX. El código se implementó cuando estaba aprendiendo JavaFX por primera vez, así que seguramente el código podría estar más limpio y quizás haya formas más simples de lograr esto (por ejemplo, usar un Grupo como contenedor para el nodo escalado como se sugiere en el ScrollPane documentation).

Una clave para conseguir la solución que quería (barras de desplazamiento aparecen sólo cuando has y el nodo es mayor que el área de visualización visible), fue este código:

// create a container for the viewable node. 
final StackPane nodeContainer = new StackPane(); 
nodeContainer.getChildren().add(node); 

// place the container in the scrollpane and adjust the pane's viewports as required. 
final ScrollPane scrollPane = new ScrollPane(); 
scrollPane.setContent(nodeContainer); 
scrollPane.viewportBoundsProperty().addListener(
    new ChangeListener<Bounds>() { 
    @Override public void changed(ObservableValue<? extends Bounds> observableValue, Bounds oldBounds, Bounds newBounds) { 
    nodeContainer.setPrefSize(
     Math.max(node.getBoundsInParent().getMaxX(), newBounds.getWidth()), 
     Math.max(node.getBoundsInParent().getMaxY(), newBounds.getHeight()) 
    ); 
    } 
}); 

... 

// adjust the view layout based on the node scalefactor. 
final ToggleButton scale = new ToggleButton("Scale"); 
scale.setOnAction(new EventHandler<ActionEvent>() { 
    @Override public void handle(ActionEvent actionEvent) { 
    if (scale.isSelected()) { 
     node.setScaleX(3); node.setScaleY(3); 
    } else { 
     node.setScaleX(1); node.setScaleY(1); 
    } 
    // runlater as we want to size the container after a layout pass has been performed on the scaled node. 
    Platform.runLater(new Runnable() { 
     @Override public void run() { 
     nodeContainer.setPrefSize(
      Math.max(nodeContainer.getBoundsInParent().getMaxX(), scrollPane.getViewportBounds().getWidth()), 
      Math.max(nodeContainer.getBoundsInParent().getMaxY(), scrollPane.getViewportBounds().getHeight()) 
     ); 
     } 
    }); 
    } 
}); 
+0

Gracias por su respuesta. El código produce algunos efectos secundarios bastante extraños (por ejemplo, al reducir la escala, las barras de desplazamiento no se adaptarán correctamente hasta que se muevan), pero el enfoque es seguramente correcto. Esto me ayudó mucho. – sarcan

8

De acuerdo con el documento ScrollPane que podría intente envolver un Panel en un Grupo para que ScrollPane se desplace por el límite visual, no por el límite real del diseño.

ScrollPane layout calculations are based on the layoutBounds rather than the 
boundsInParent (visual bounds) of the scroll node. If an application wants the 
scrolling to be based on the visual bounds of the node (for scaled content etc.), 
they need to wrap the scroll node in a Group.