2

我试图用这个线程中的彩色进度条来解决我的问题。解决方案是存在的,但后来我遇到了另一个问题:我无法从我的代码中动态更改颜色。我想直接从我的代码中完成,而不是使用预定义的 .css。通常我可以做到,但是当我尝试使用多个进度条进行时遇到了一些困难。

public class JavaFXApplication36 extends Application {

    @Override
    public void start(Stage primaryStage) {
        AnchorPane root = new AnchorPane();
        ProgressBar pbRed = new ProgressBar(0.4);
        ProgressBar pbGreen = new ProgressBar(0.6);
        pbRed.setLayoutY(10);
        pbGreen.setLayoutY(30);

        pbRed.setStyle("-fx-accent: red;");       // line (1)
        pbGreen.setStyle("-fx-accent: green;");   // line (2)

        root.getChildren().addAll(pbRed, pbGreen);
        Scene scene = new Scene(root, 150, 50);
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

我总是得到 2 个红色进度条!似乎第 (1) 行中的代码更改了 ProgressBar 类的样式,而不是实例。

另一个奇怪的时刻是删除第 (1) 行不会导致 2 个绿色进度条。所以我可以认为第 (2) 行完全没用!!为什么?!这肯定会变得很奇怪。

有没有办法为单独的进度条设置不同的颜色?

4

1 回答 1

4

另请参阅StackOverflow JavaFX ProgressBar 社区 Wiki


您可以使用一种解决方法,直到提交并修复了修复问题中示例代码的错误。

此答案中的代码对内容进行节点查找ProgressBar,然后将进度条的条颜色动态修改为您喜欢的任何值。

import javafx.application.Application;
import javafx.beans.value.*;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ProgressBarDynamicColor extends Application {
  public static void main(String[] args) { launch(args); }
  @Override public void start(Stage stage) {
    PickedColorBar aquaBar = new PickedColorBar(0.4, Color.AQUA);
    PickedColorBar fireBar = new PickedColorBar(0.6, Color.FIREBRICK);

    HBox layout = new HBox(20);
    layout.getChildren().setAll(aquaBar, fireBar);
    layout.setStyle("-fx-background-color: -fx-box-border, cornsilk; -fx-padding: 15;");

    stage.setScene(new Scene(layout));
    stage.show();

    aquaBar.wasShown();
    fireBar.wasShown();
  }

  class PickedColorBar extends VBox {
    private final ProgressBar bar;
    private final ColorPicker picker;

    private boolean wasShownCalled = false;

    final ChangeListener<Color> COLOR_LISTENER = new ChangeListener<Color>() {
      @Override public void changed(ObservableValue<? extends Color> value, Color oldColor, Color newColor) {
        setBarColor(bar, newColor);
      }
    };

    public PickedColorBar(double progress, Color initColor) {
      bar    = new ProgressBar(progress);
      picker = new ColorPicker(initColor);

      setSpacing(10);
      setAlignment(Pos.CENTER);
      getChildren().setAll(bar, picker);
    }

    // invoke only after the progress bar has been shown on a stage.     
    public void wasShown() {
      if (!wasShownCalled) {
        wasShownCalled = true;
        setBarColor(bar, picker.getValue());
        picker.valueProperty().addListener(COLOR_LISTENER);
      }  
    }

    private void setBarColor(ProgressBar bar, Color newColor) {
      bar.lookup(".bar").setStyle("-fx-background-color: -fx-box-border, " + createGradientAttributeValue(newColor));
    }

    private String createGradientAttributeValue(Color newColor) {
      String hsbAttribute = createHsbAttributeValue(newColor);
      return "linear-gradient(to bottom, derive(" + hsbAttribute+ ",30%) 5%, derive(" + hsbAttribute + ",-17%))";
    }

    private String createHsbAttributeValue(Color newColor) {
      return 
        "hsb(" + 
          (int)  newColor.getHue()               + "," + 
          (int) (newColor.getSaturation() * 100) + "%," + 
          (int) (newColor.getBrightness() * 100) + "%)";
    }
  }
}

该代码使用 css 属性的内联字符串处理来操作区域背景。未来的 JavaFX 版本(例如 JDK8+)将包括一个公共 Java API 来操作后台属性,从而使 Java 程序中的属性字符串处理变得过时。

示例程序输出:

颜色选择器进度

于 2012-11-21T01:18:51.157 回答