2014-07-02 14 views
7

In javaFX per ridimensionare una tela non esiste un tale metodo per farlo, l'unica soluzione è estendere da Canvas.Come rendere la tela ridimensionabile in javaFX?

class ResizableCanvas extends Canvas { 

    public ResizableCanvas() { 
     // Redraw canvas when size changes. 
     widthProperty().addListener(evt -> draw()); 
     heightProperty().addListener(evt -> draw()); 
    } 

    private void draw() { 
     double width = getWidth(); 
     double height = getHeight(); 

     GraphicsContext gc = getGraphicsContext2D(); 
     gc.clearRect(0, 0, width, height); 

    } 

    @Override 
    public boolean isResizable() { 
     return true; 
    } 
} 

si estende dalla tela di canapa è l'unica soluzione per fare tela ridimensionabile? perché questa soluzione funziona solo se non vogliamo usare FXML, se dichiariamo in fxml una tela come possiamo renderla ridimensionabile?

questo è il mio codice:

package sample; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Scene; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.layout.AnchorPane; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

public class Main extends Application { 

    Controller controller; 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml")); 
     AnchorPane root = loader.load(); // controller initialized 
     controller = loader.getController(); 
     GraphicsContext gc = controller.canvas.getGraphicsContext2D(); 
     gc.setFill(Color.AQUA); 
     gc.fillRect(0, 0, root.getPrefWidth(), root.getPrefHeight()); 
     primaryStage.setTitle("Hello World"); 
     primaryStage.setScene(new Scene(controller.Pane, controller.Pane.getPrefWidth(), controller.Pane.getPrefHeight())); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

Perché questa soluzione non funziona se usi FXML? –

+0

se uso la soluzione, influenzerò l'oggetto della classe su tela di FXML, la tela sarà ridimensionabile ma quando compilo il codice la tela non è visibile non so perché. – HinoHara

+0

Guardando il tuo codice ... Penso che probabilmente 'root.getPrefWidth()' e 'root.getPrefHeight()' non stanno dando quello che ti aspetti. Per provare, basta provare a codificare qualcosa e vedere se funziona. Inoltre, stai impostando la larghezza e l'altezza della tela in FMXL? –

risposta

3

C'è una guida che penso che si possono trovare utili per la creazione di una tela ridimensionabile:

JavaFx tip - resizable canvas

pezzo di codice dal guida:

/** 
* Tip 1: A canvas resizing itself to the size of 
*  the parent pane. 
*/ 
public class Tip1ResizableCanvas extends Application { 

    class ResizableCanvas extends Canvas { 

     public ResizableCanvas() { 
      // Redraw canvas when size changes. 
      widthProperty().addListener(evt -> draw()); 
      heightProperty().addListener(evt -> draw()); 
     } 

     private void draw() { 
      double width = getWidth(); 
      double height = getHeight(); 

      GraphicsContext gc = getGraphicsContext2D(); 
      gc.clearRect(0, 0, width, height); 

      gc.setStroke(Color.RED); 
      gc.strokeLine(0, 0, width, height); 
      gc.strokeLine(0, height, width, 0); 
     } 

     @Override 
     public boolean isResizable() { 
      return true; 
     } 

     @Override 
     public double prefWidth(double height) { 
      return getWidth(); 
     } 

     @Override 
     public double prefHeight(double width) { 
      return getHeight(); 
     } 
    } 
+1

In questa soluzione manca un punto importante del suggerimento collegato: "Associare le proprietà di larghezza e altezza di Canvas alle proprietà width e height del riquadro principale" ad es.se la tela viene aggiunta a uno StackPane: canvas.widthProperty(). bind (stackPane.widthProperty()); canvas.heightProperty(). Bind (stackPane.heightProperty()); – sys64738

2

Preso da http://werner.yellowcouch.org/log/resizable-javafx-canvas/: Per rendere ridimensionabile una tela JavaFx, è necessario eseguire l'override dei metodi min/pref/max. Rendilo ridimensionabile e implementa il metodo di ridimensionamento.

Con questo metodo non è necessario alcun ascoltatore di larghezza/altezza per attivare un nuovo aggiornamento. Inoltre, non è più necessario legare le dimensioni della larghezza e dell'altezza al contenitore.

public class ResizableCanvas extends Canvas { 

@Override 
public double minHeight(double width) 
{ 
    return 64; 
} 

@Override 
public double maxHeight(double width) 
{ 
    return 1000; 
} 

@Override 
public double prefHeight(double width) 
{ 
    return minHeight(width); 
} 

@Override 
public double minWidth(double height) 
{ 
    return 0; 
} 

@Override 
public double maxWidth(double height) 
{ 
    return 10000; 
} 

@Override 
public boolean isResizable() 
{ 
    return true; 
} 

@Override 
public void resize(double width, double height) 
{ 
    super.setWidth(width); 
    super.setHeight(height); 
    <paint> 
} 
+0

Non so di questo; sembra che l'API sia cambiata forse (ad es. cosa è pain()?) – bbarker

+0

Risposta perfetta. – GOXR3PLUS

1

La classe tela ha solo bisogno di ignorare isResizable() (tutto il resto, che è suggerita in altri esempi, non è effettivamente necessario):

public class ResizableCanvas extends Canvas 
{ 
    public boolean isResizable() 
    { 
     return true; 
    } 
} 

E nell'applicazione della proprietà width e height della tela deve essere vincolato al genitore della tela:

@Override 
public void start(Stage primaryStage) throws Exception 
{ 
    ... 
    StackPane pane = new StackPane(); 
    ResizableCanvas canvas = new ResizableCanvas(width, height); 

    canvas.widthProperty().bind(pane.widthProperty()); 
    canvas.heightProperty().bind(pane.heightProperty()); 

    pane.getChildren().add(_canvas); 
    ... 
} 

ascoltatori possono essere aggiunti alla larghezza in height, al fine di ridisegnare la tela, quando viene ridimensionato (ma se yo ne hai bisogno e dove collocarlo, dipende dalla tua applicazione):

widthProperty().addListener(this::paint); 
heightProperty().addListener(this::paint);