JavaFX ProgressBar: как изменить цвет бара?

Я пытаюсь изменить цвет панели в ProgressBar с помощью

pBar.setStyle("-fx-accent: green");

но я столкнулся с проблемой: это не работает для меня! (Или я просто ничего не понимаю)

вот код:

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();
}
}

Я всегда получаю две красные панели прогресса! Кажется, что код в строке (1) изменяет стиль класса ProgressBar, а не экземпляр.

Еще один странный момент заключается в том, что удаление строки (1) не приводит к 2 зеленым индикаторам хода. Поэтому я могу понять, что линия (2) абсолютно бесполезна!! ЗАЧЕМ?! Это определенно странно.

Есть ли способ установить отдельные цвета для отдельных панелей progressbars?

Ответ 1

Ответ обновлен, чтобы добавить простой неанимированный пример с несколькими индикаторами выполнения

В коде вашего вопроса должно отображаться два разных цветных индикатора выполнения, тот факт, что он не является ошибкой в ​​системе обработки css JavaFX. Зарегистрируйтесь здесь об ошибке с проектом runtime: http://javafx-jira.kenai.com.

В качестве обходного пути вместо вызова setStyle на индикаторах выполнения определите цвета акцента, используемые для цветовых индикаторов выполнения в таблице стилей, и добавьте класс стиля в индикаторы выполнения. Затем вы можете создавать несколько индикаторов выполнения в одном приложении, все с разными цветами.

Как указывает Улук, вы можете использовать JavaFX 2.2 caspian.css в сочетании с справочник JavaFX 2 css и учебник JavaFX 2 css, чтобы определить, как стилизовать вещи.

Вот пример кода, который настраивает индикатор выполнения на основе информации в этих ссылках.

Пример css:

/** progress.css
    place in same directory as 
    ColoredProgressBarStyleSheet.java or SimpleColoredProgressBar.java
    ensure build system copies the css file to the build output path */

.root { -fx-background-color: cornsilk; -fx-padding: 15; }

.progress-bar { -fx-box-border: goldenrod; }

.green-bar  { -fx-accent: green;  }
.yellow-bar { -fx-accent: yellow; }
.orange-bar { -fx-accent: orange; }
.red-bar    { -fx-accent: red;    }

Простая программа-пример:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

// shows multiple progress bars drawn in different colors.
public class SimpleColoredProgressBar extends Application {
     public static void main(String[] args) { launch(args); }

     @Override public void start(Stage stage) {
         final VBox layout = new VBox(10);
         layout.setAlignment(Pos.CENTER);
         layout.getChildren().setAll(
             new ColoredProgressBar("red-bar",    0.2),
             new ColoredProgressBar("orange-bar", 0.4),
             new ColoredProgressBar("yellow-bar", 0.6),
             new ColoredProgressBar("green-bar",  0.8)
         );
         layout.getStylesheets().add(getClass().getResource("progress.css").toExternalForm());
         stage.setScene(new Scene(layout));
         stage.show();
    }

    class ColoredProgressBar extends ProgressBar {
        ColoredProgressBar(String styleClass, double progress) {
            super(progress);
            getStyleClass().add(styleClass);
        }
    }
}

Простой пример программы:

coloredbars

Более сложная программа-образец с одним анимированным индикатором выполнения, который динамически меняет цвет в зависимости от достигнутого прогресса:

import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.event.*;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

// shows a progress bar whose bar changes color depending on the amount of progress.
public class ColoredProgressBarStyleSheet extends Application {
  public static void main(String[] args) { launch(args); }

  private static final String RED_BAR    = "red-bar";
  private static final String YELLOW_BAR = "yellow-bar";
  private static final String ORANGE_BAR = "orange-bar";
  private static final String GREEN_BAR  = "green-bar";
  private static final String[] barColorStyleClasses = { RED_BAR, ORANGE_BAR, YELLOW_BAR, GREEN_BAR };

  @Override public void start(Stage stage) {
    final ProgressBar bar = new ProgressBar();

    final Timeline timeline = new Timeline(
      new KeyFrame(Duration.millis(0),    new KeyValue(bar.progressProperty(), 0)),
      new KeyFrame(Duration.millis(3000), new KeyValue(bar.progressProperty(), 1))
    );

    Button reset = new Button("Reset");
    reset.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        timeline.playFromStart();
      }
    });

    bar.progressProperty().addListener(new ChangeListener<Number>() {
      @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
        double progress = newValue == null ? 0 : newValue.doubleValue();
        if (progress < 0.2) {
          setBarStyleClass(bar, RED_BAR);
        } else if (progress < 0.4) {
          setBarStyleClass(bar, ORANGE_BAR);
        } else if (progress < 0.6) {
          setBarStyleClass(bar, YELLOW_BAR);
        } else {
          setBarStyleClass(bar, GREEN_BAR);
        }
      }

      private void setBarStyleClass(ProgressBar bar, String barStyleClass) {
        bar.getStyleClass().removeAll(barColorStyleClasses);
        bar.getStyleClass().add(barStyleClass);
      }
    });    

    final VBox layout = new VBox(10);
    layout.setAlignment(Pos.CENTER);
    layout.getChildren().setAll(bar, reset);
    layout.getStylesheets().add(getClass().getResource("progress.css").toExternalForm());
    stage.setScene(new Scene(layout));
    stage.show();

    timeline.play();
  }    
}

Более сложный вывод тестовой программы:

sample program output

Ответ 2

Вы должны переопределить (или настроить) стиль с помощью селекторов CSS JavaFX. См. Caspian.css для получения дополнительной информации. В своей таблице стилей определите:

.progress-bar .bar {
    -fx-background-color:
        -fx-box-border,
        linear-gradient(to bottom, derive(-fx-accent,95%), derive(-fx-accent,10%)),
        red; /* this line is the background color of the bar */
    -fx-background-insets: 0, 1, 2;
    -fx-padding: 0.416667em; /* 5 */
}