Vertical ProgressBar JavaFX

时间:2014-05-15 02:29:26

标签: javafx-2 progress-bar

我有一个StackPane,大小为(15px宽,400px高)。我想要一个" Vertical ProgressBar"到那个StackPane。我正在做的是将进度条旋转90度。但是,progressBar无法适应具有该旋转的堆栈窗格。它只是在StackPane中心显示为一个小的平方进度条。

我该如何解决?

2 个答案:

答案 0 :(得分:7)

示例垂直进度条。

class UpwardProgress {
    private ProgressBar progressBar    = new ProgressBar();
    private Group       progressHolder = new Group(progressBar);

    public UpwardProgress(double width, double height) {
        progressBar.setMinSize(StackPane.USE_PREF_SIZE, StackPane.USE_PREF_SIZE);
        progressBar.setPrefSize(height, width);
        progressBar.setMaxSize(StackPane.USE_PREF_SIZE, StackPane.USE_PREF_SIZE);
        progressBar.getTransforms().setAll(
                new Translate(0, height),
                new Rotate(-90, 0, 0)
        );
    }

    public ProgressBar getProgressBar() {
        return progressBar;
    }

    public Group getProgressHolder() {
        return progressHolder;
    }
}

用于示例应用。

lookatthestars

import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.scene.*;
import javafx.scene.canvas.*;
import javafx.scene.control.*;
import javafx.scene.image.PixelWriter;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.transform.*;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.Random;

class UpwardProgress {
    private ProgressBar progressBar    = new ProgressBar();
    private Group       progressHolder = new Group(progressBar);

    public UpwardProgress(double width, double height) {
        progressBar.setMinSize(StackPane.USE_PREF_SIZE, StackPane.USE_PREF_SIZE);
        progressBar.setPrefSize(height, width);
        progressBar.setMaxSize(StackPane.USE_PREF_SIZE, StackPane.USE_PREF_SIZE);
        progressBar.getTransforms().setAll(
                new Translate(0, height),
                new Rotate(-90, 0, 0)
        );
    }

    public ProgressBar getProgressBar() {
        return progressBar;
    }

    public Group getProgressHolder() {
        return progressHolder;
    }
}

public class StarCounter extends Application {

    public static final Color INDIA_INK = Color.rgb(35, 39, 50);

    private static final int CANVAS_SIZE      = 400;
    private static final int N_STARS          = 1_000;

    private final Canvas canvas = new Canvas(CANVAS_SIZE, CANVAS_SIZE);
    private final Random random = new Random(42);
    private final IntegerProperty visibleStars = new SimpleIntegerProperty(0);
    private       Timeline timeline;

    @Override
    public void start(final Stage stage) {
        Group root = initProgress();
        clearCanvas();

        visibleStars.addListener((observable, oldValue, newValue) -> {
            if (newValue.intValue() > oldValue.intValue()) {
                addStars(newValue.intValue() - oldValue.intValue());
            }
        });

        stage.setScene(
            new Scene(
                new HBox(canvas, root),
                INDIA_INK
            )
        );
        stage.show();

        runSimulation();

        stage.getScene().setOnMouseClicked(event -> {
            resetSimulation();
            runSimulation();
        });
    }

    private Group initProgress() {
        UpwardProgress upwardProgress = new UpwardProgress(15, 400);

        ProgressIndicator bar = upwardProgress.getProgressBar();
        bar.setStyle("-fx-base: skyblue; -fx-accent: gold;");
        bar.progressProperty().bind(visibleStars.divide(N_STARS * 1.0));

        return upwardProgress.getProgressHolder();
    }

    private void resetSimulation() {
        clearCanvas();
        if (timeline != null) {
            timeline.stop();
            timeline = null;
        }
    }

    private void runSimulation() {
        timeline = new Timeline(
            new KeyFrame(
                Duration.seconds(0),
                new KeyValue(visibleStars, 0)
            ),
            new KeyFrame(
                Duration.seconds(10),
                new KeyValue(visibleStars, N_STARS)
            )
        );
        timeline.play();
    }

    private void clearCanvas() {
        canvas.getGraphicsContext2D().setFill(INDIA_INK);
        canvas.getGraphicsContext2D().fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
    }

    private void addStars(int nStarsToAdd) {
        GraphicsContext context = canvas.getGraphicsContext2D();
        PixelWriter writer = context.getPixelWriter();
        for (int i = 0; i < nStarsToAdd; i++) {
            writer.setColor(random.nextInt(CANVAS_SIZE), random.nextInt(CANVAS_SIZE), Color.GOLD);
        }
    }

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

答案 1 :(得分:2)

还有另一种选择,即制作您自己的自定义垂直进度条。听起来太多但不是。这种方法的优点是在UI中更加一致,并且更加动态易用。我使用@jewel的上述答案,但在进度条的UI一致性和动态行为方面苦苦挣扎。

方法是使用vbox作为进度条,在其中使用另一个vbox作为bar。

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.device.ui.VerticalProgressBarController">
    <children>
        <VBox fx:id="progress_bar" alignment="BOTTOM_CENTER" prefHeight="450.0" prefWidth="20.0" style="-fx-border-color: black; -fx-border-radius: 2 2 2 2;">
         <children>
            <VBox fx:id="bar" prefHeight="0.0" prefWidth="20.0" style="-fx-border-radius: 2 2 2 2;"/>
         </children>
        </VBox>
    </children>
</VBox>

可以在控制器中动态调整prefHeightprogress-bar bar,在.fxml文件中静态调整prefHeight。由于此处只有bar是我需要动态调整的,因此将其0设置为public class VerticalProgressBarController implements Initializable { @FXML VBox progress_bar; @FXML VBox bar; private double progress_bar,fixed_capacity; public void initialize(URL location, ResourceBundle resources) { progressBarHeight = progress_bar.getPrefHeight(); bar.setMaxHeight(progressBarHeight); // initial bar color setGreenBar(); // set the max capacity of the progress bar fixed_capacity = 100; // pass in the proportion; here wanted to show 15 on a scale of 100 updateProgressBar(15 / fixed_capacity); } public void setGreenBar(){ bar.setStyle("-fx-background-color: green"); } public void setYellowBar(){ bar.setStyle("-fx-background-color: yellow"); } public void setRedBar(){ bar.setStyle("-fx-background-color: red"); } public void updateProgressBar(double progress){ bar.setPrefHeight(progressBarHeight * progress); if(progress <= .60){ setGreenBar(); } else if(progress > .60 && progress <= .75){ setYellowBar(); }else { setRedBar(); } } 并在相应的控制器中进行适当调整。

SELECT id,price,product_id FROM price order by price ASC limit 1

enter image description here