我有一个StackPane,大小为(15px宽,400px高)。我想要一个" Vertical ProgressBar"到那个StackPane。我正在做的是将进度条旋转90度。但是,progressBar无法适应具有该旋转的堆栈窗格。它只是在StackPane中心显示为一个小的平方进度条。
我该如何解决?
答案 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;
}
}
用于示例应用。
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>
可以在控制器中动态调整prefHeight
和progress-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