ninja007
ninja007

Reputation: 53

how to fix custom timeline problem JavaFx?

I have seen this timeline build here then I have tried to make I timeline using hbox and sperators and labels, but I fall in a representation errors

the following controller allows me to build this timeline this above nodes

public class GuiMainController implements Initializable {

    @FXML 
    private BorderPane borderPane; 

    public void getUnit1(){
        //This will fill the Time Line Unit in your Gui
                VBox vbox = new VBox();
                HBox hbox = new HBox();
                hbox.setManaged(false);
                for (int i =0; i < 24; i++) {
                    //For each unit create a new instance
                    AnchorPane anchorPane = new AnchorPane();
                    anchorPane.setPrefHeight(30);
                    anchorPane.setPrefWidth(66);

                    Separator separatorR = new Separator();
                    separatorR.setLayoutX(66);
                    separatorR.setLayoutY(14);
                    separatorR.setOrientation(Orientation.VERTICAL);
                    separatorR.setPrefHeight(15);

                    Separator separatorM = new Separator();
                    separatorM.setLayoutY(14);
                    separatorM.setOrientation(Orientation.VERTICAL);
                    separatorM.setPrefHeight(15);

                    Separator separatorL = new Separator();
                    separatorL.setLayoutX(33);
                    separatorL.setLayoutY(20);
                    separatorL.setOrientation(Orientation.VERTICAL);
                    separatorL.setPrefHeight(10);
                    separatorL.setPrefWidth(6);

                    Label lblT = new Label();
                    lblT.setText(i+"h");

                    Label lblTT = new Label();
                    lblTT.setLayoutX(66);
                    lblTT.setText((i+1)+"h");

                    anchorPane.getChildren().addAll(separatorL,lblT,separatorM,separatorR,lblTT);
                    hbox.getChildren().add(anchorPane);
                }
                borderPane.getChildren().add(hbox);
    }
    public void initialize(URL arg0, ResourceBundle arg1) {
        getUnit1();
    }
}

enter image description here

How can I made this timeline, any help are appreciated to get some like this enter image description here

Upvotes: 0

Views: 51

Answers (1)

fabian
fabian

Reputation: 82461

Imho you shouldn't get any layouts involved here, since this way you rely on the exact implementation of those layouts. Furthermore I'm not sure Seperator should be involved here. You could use a Path though and calculate the positions of all the lines on the axis.

private static Label createLabel(String text, double layoutY, double majorTickDistance, int index) {
    Label label = new Label(text);

    // label width should be exactly the distance between ticks
    label.setMaxWidth(Region.USE_PREF_SIZE);
    label.setMinWidth(Region.USE_PREF_SIZE);
    label.setPrefWidth(majorTickDistance);

    // center text
    label.setAlignment(Pos.BASELINE_CENTER);
    label.setLayoutY(layoutY);

    // align center of the label with major tick
    label.setLayoutX((index + 0.5) * majorTickDistance);
    return label;
}

/**
 * @param majorTickDistance the width between major ticks
 * @param minorTicks the number of minor ticks between major ticks
 * @param majorTickHeight the height of major tick markers
 * @param minorTickHeight the height of minor tick markers
 * @param firstText the first text for the first major tick
 * @param text the text for other ticks
 */
private static Pane createAxis(double majorTickDistance, int minorTicks,
        double majorTickHeight, double minorTickHeight, String firstText, String... text) {
    final double labelY = majorTickHeight + 3;
    final double minorTickDistance = majorTickDistance / minorTicks;

    // initialize path with first major tick and horizontal line
    Path path = new Path(
            new MoveTo(0, 0), new HLineTo(majorTickDistance * text.length),
            new MoveTo(0, 0), new VLineTo(majorTickHeight)
    );

    // add path and first label
    Pane pane = new Pane(path, createLabel(firstText, labelY, majorTickDistance, -1));

    for (int i = 0; i < text.length; i++) {
        double offset = i * majorTickDistance;

        // add minor ticks
        for (int j = 1; j < minorTicks; j++) {
            double x = offset + j * minorTickDistance;
            path.getElements().addAll(new MoveTo(x, 0), new VLineTo(minorTickHeight));
        }
        offset += majorTickDistance;

        // add major tick at the end of the current interval
        path.getElements().addAll(new MoveTo(offset, 0), new VLineTo(majorTickHeight));

        // add label below major tick
        pane.getChildren().add(createLabel(text[i], labelY, majorTickDistance, i));
    }

    pane.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);

    return pane;
}

@Override
public void start(Stage primaryStage) throws Exception {

    Scene scene = new Scene(new StackPane(createAxis(30, 5, 10, 5, "1", "2", "3", "4", "5", "6")), 400, 400);

    primaryStage.setScene(scene);
    primaryStage.show();
}

Upvotes: 2

Related Questions