Below is the Main.class
and the Controller.class
, i tried to make it as simpler as possible.
The program outputs the below window:
The black is a StackPane
named visualizerStackPane
and inside it is a Canvas
named visualizerCanvas
. What i want to do is the Canvas
inside the StackPane
to be resized accordingly to the StackPane
size substract 4 . But everything fails when you resize the window.
What you have to try...
1)Maximize the window and then normalize it back.
2)Increase the size of the window and slowly decrease it back.
Why this is happening?I have this problem 3 months now and i can't find a solution...
I have also looked JavaFX - Resize Canvas when screen is resized but the problem here seems to be different...
Main.java:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
//Scene
Scene scene = new Scene(new Controller(), 400, 400);
primaryStage.setScene(scene);
//Show
primaryStage.show();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java:
I have modified the Controller class to paint the Canvas and removed the bindings from Initialize
method , it doesn't work it produces the below:
If i don't set the width and height of the Canvas manually it doesn't even get painted...I don't know why .
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
public class Controller extends StackPane {
@FXML
private GridPane container;
@FXML
private GridPane topGridPane;
@FXML
private StackPane visualizerStackPane;
@FXML
private Canvas visualizerCanvas;
@FXML
private VBox topRightVBox;
@FXML
private StackPane mediaFileStackPane;
@FXML
private GridPane bottomGridPane;
// ------------------------------
GraphicsContext gc;
int canvasWidth = 0;
int canvasHeight = 0;
/**
* Constructor
*/
public Controller() {
// ------------------------FXMLLoader ---------------------------------
FXMLLoader loader = new FXMLLoader(getClass().getResource("Controller.fxml"));
loader.setController(this);
loader.setRoot(this);
try {
loader.load();
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Controller FXML can't be loaded!", ex);
}
}
/**
* Called as soon as FXML FILE has been loaded
*/
@FXML
private void initialize() {
gc = visualizerCanvas.getGraphicsContext2D();
// // VisualizerStackPane inside which visualizerCanvas is
// visualizerCanvas.widthProperty().bind(visualizerStackPane.widthProperty().subtract(4));
// visualizerCanvas.heightProperty().bind(visualizerStackPane.heightProperty().subtract(4));
//
// Add width and height change listeners
visualizerStackPane.widthProperty().addListener((observable, oldValue,
newValue) -> resizeVisualizerCanvas(newValue.doubleValue(), visualizerStackPane.getHeight()));
visualizerStackPane.heightProperty().addListener((observable, oldValue,
newValue) -> resizeVisualizerCanvas(visualizerStackPane.getWidth(), newValue.doubleValue())
);
repaintCanvas();
}
/**
* Repaints the Canvas
*/
public void repaintCanvas() {
//Clear the previous rectangle
gc.clearRect(0, 0, canvasWidth, canvasHeight);
// Draw the
gc.setFill(Color.RED);
gc.fillRect(0, 0, canvasWidth, canvasHeight);
// Draw the Line
gc.setLineWidth(3);
gc.setStroke(Color.WHITE);
gc.strokeLine(0, canvasHeight, canvasWidth, 0);
}
/**
* Resizes the visualizerCanvas to the given values.
*
* @param width
* the width
* @param height
* the height
*/
public void resizeVisualizerCanvas(double width, double height) {
if (width > 0 && height > 0) {
this.canvasWidth = (int) width;
this.canvasHeight = (int) height;
// Print something
System.out.println("Canvas Width is:" + width+" , Canvas Height is:"+height +" Canvas is Resizable: "+visualizerCanvas.isResizable());
// Repaint the Canvas
repaintCanvas();
// ---------------------------Below i have tried several things to
// solve the problem....
// Set the width and height of Canvas
visualizerCanvas.setWidth(width);
visualizerCanvas.setHeight(height);
// Careful with contentBias here
prefWidth(-1);
prefHeight(-1);
// autosize()
// System.out.println("Content Bias is:"+this.getContentBias())
}
}
}
Controller.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<fx:root prefHeight="212.0" prefWidth="456.0" type="StackPane" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
<padding>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</padding>
<children>
<GridPane fx:id="container">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="50.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="50.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" percentHeight="40.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" percentHeight="60.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane fx:id="topGridPane" gridLinesVisible="true" GridPane.columnSpan="2">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="50.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="50.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<StackPane fx:id="visualizerStackPane" style="-fx-border-color: white; -fx-border-width: 1.5; -fx-background-color: rgb(0,0,0,0.95);">
<children>
<Canvas fx:id="visualizerCanvas" />
</children>
</StackPane>
<VBox fx:id="topRightVBox" GridPane.columnIndex="1">
<children>
<StackPane prefHeight="150.0" prefWidth="200.0">
<children>
<Region style="-fx-background-color: rgb(255,255,255,0.7);" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-font-weight: bold;" text="text here" />
</children>
</StackPane>
<StackPane fx:id="mediaFileStackPane" maxWidth="1.7976931348623157E308" />
</children>
</VBox>
</children>
</GridPane>
<GridPane fx:id="bottomGridPane" gridLinesVisible="true" GridPane.columnSpan="2" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="20.0" prefWidth="35.0" />
<ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="10.0" percentWidth="60.0" prefWidth="343.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="20.0" prefWidth="52.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<StackPane prefHeight="150.0" prefWidth="200.0" GridPane.columnIndex="2">
<children>
<Region style="-fx-background-color: rgb(255,255,255,0.7);" />
<Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-font-weight: bold;" text="text here" textAlignment="CENTER" wrapText="true" StackPane.alignment="CENTER" />
</children>
</StackPane>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="5.0" />
</children>
</GridPane>
</children>
</GridPane>
</children>
</fx:root>
Finally:
A big thanks to the person who will manage to solve this problem :).