0

I'm a newbie in JavaFx. I wanted to create a custom progress bar using Canvas and add it directly to my fxml file (instead of using java code).

This is my custom canvas class:

public class CircularProgressBar extends Canvas {

    public CircularProgressBar() {
        super();
        draw(); // this call here doesn't work
    }

    public void draw() {
        GraphicsContext gc = this.getGraphicsContext2D();

        gc.setLineWidth(1.0);
        gc.setStroke(Color.GREEN);
        gc.setFill(Color.RED);

        // draw progress bar
    }
}

And the fxml file:

<?imports...?>

<GridPane fx:controller="com.mypackage.MainController">

    <CircularProgressBar fx:id="progressBar"
                         width="500"
                         height="500"
                         GridPane.columnSpan="2"
                         GridPane.rowIndex="0"/>
</GridPane>

When the application starts, CircularProgressBar() constructor (and therefore the draw() method) is called but nothing is shown in the canvas. But if I call progressBar.draw() manually in my application class it works correctly.

I want the canvas to automatically draw when the application starts. What should I do? Am I doing something wrong?

Mahozad
  • 18,032
  • 13
  • 118
  • 133
  • 1
    Think about the size of your canvas at the point in time when the constructor is called! – mipa Aug 30 '19 at 13:12
  • Most likely you'd be better of using shapes to create your control anyways. This only requires you to modify the parts that change instead of having to redraw everything on every change. – fabian Aug 30 '19 at 20:40
  • If you want a "CircularProgressBar", you might want to look at using a [ProgressIndicator](https://docs.oracle.com/javase/8/javafx/user-interface-tutorial/progress.htm), with some [custom CSS styling](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html#progressindicator) to control its look if needed. – jewelsea Aug 30 '19 at 21:27

1 Answers1

0

When the constructor for your Canvas subclass is called, the object is not part of a Scene and hasn't been through a layout pass. Perhaps the un-shown parts of your draw() method rely on the dimensions of the Canvas that haven't been set yet?

See How to make canvas Resizable in javaFX?

React to changes in width or height with a listener that calls your draw method.

swpalmer
  • 3,890
  • 2
  • 23
  • 31
  • yes they depend on the canvas width and height. What do you think I should do? – Mahozad Sep 01 '19 at 20:29
  • I've updated my answer with a reference to another that explains how to handle Canvas resizing. Which is effectively what is happening in this case - you are drawing before layout or the FXML loader setting the width and height properties. – swpalmer Sep 01 '19 at 20:59