Reputation: 1925
I'm pretty new to this whole JavaFX thing, as you can probably tell. This is an issue I ran into recently while playing around with the Canvas node. I've got a BorderPane as my root node, and I'd like to have a Canvas occupy all available space within the center of it. However, I'm having some trouble implementing that exact behavior. Here's the just of what I've been trying:
public void start(Stage stage){
BorderPane root=new BorderPane();
Canvas canvas=new Canvas(250,250);
//canvas.widthProperty().bind(root.widthProperty());
//canvas.heightProperty().bind(root.heightProperty());
GraphicsContext gc=canvas.getGraphicsContext2D();
new AnimationTimer(){
@Override
public void handle(long l){
double width=canvas.getWidth(),height=canvas.getHeight();
gc.clearRect(0,0,width,height);
gc.strokeRect(0,0,width,height);
gc.strokeLine(0,0,width,height);
gc.strokeLine(0,height,width,0);
}
}.start();
root.setCenter(canvas);
root.setBottom(new Button("Placeholder"));
root.setTop(new Button("Placeholder"));
stage.setScene(new Scene(root));
stage.show();
}
Instead of expanding as the Pane does, my Canvas just stays centered within it, retaining its original size. If the two commented lines near the top are re-added, the Canvas grows and shrinks as the Pane does, but without regarding the dimensions of its center (as expected). Is there a way to apply this sort of binding behavior to just the center of the BorderPane, or perhaps another way to do this entirely that I'm unaware of?
Upvotes: 4
Views: 3607
Reputation: 63
EDIT: Just found a much nicer solution today (19.05.2014):
http://fxexperience.com/2014/05/resizable-grid-using-canvas/
So much easier and shorter than mine -.-
Now my original approach:
I had the same problem as you do.
I found a really ugly workaround you can use, but maybe there is another method doing this...
My Workaround:
class MyCanvas {
private Canvas cv;
private StackPane box;
public MyCanvas(Stage stg) {
cv = new Canvas(500, 500);
box = new StackPane();
box.getChildren().add(cv);
//When the Stage size changes, the canvas size becomes resetted
//but the Hbox expandes automatically to fit the with again
//and so the canvas become resized to fit the HBox
stg.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
resize();
}
});
stg.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
resize();
}
});
box.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
adapt();
}
});
box.heightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
adapt();
}
});
paint();
}
private void paint(){
//Paint something ....
GraphicsContext ctx = cv.getGraphicsContext2D();
double w = cv.getWidth();
double h = cv.getHeight();
ctx.clearRect(0, 0, w, h);
ctx.setFill(Color.BLUE);
ctx.fillRect(0, 0, w, h);
}
//Add this HBox to your content pane
public StackPane getBox() {
return box;
}
public void resize(){
cv.setWidth(50);
cv.setHeight(50);
}
private void adapt(){
cv.setHeight(box.getHeight());
cv.setWidth(box.getWidth());
paint();
}
}
And in your Main:
public class Root extends Application{
public static void main(String[] args){ launch(args); }
public void start(Stage stg){
MyCanvas cv = new MyCanvas(stg);
BorderPane pane = new BorderPane();
pane.setCenter(pane.getBox());
stg.setScene(new Scene(pane));
stg.show();
}
}
Hope this helps you solving your problem.
nZeloT
Upvotes: 1