Skip to content

Commit

Permalink
Merge pull request #181 from dlsc-software-consulting-gmbh/enhancemen…
Browse files Browse the repository at this point in the history
…t-add-start-angle

Add dynamic start angle functionality to CircleProgressIndicator
  • Loading branch information
dlemmermann authored May 24, 2024
2 parents a4ffa10 + 340c2d8 commit adf3173
Show file tree
Hide file tree
Showing 10 changed files with 824 additions and 307 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
import com.dlsc.gemsfx.CircleProgressIndicator;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.concurrent.Service;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Separator;
import javafx.scene.control.Slider;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
Expand All @@ -36,12 +40,23 @@ public void start(Stage primaryStage) {
String firstStyle = styles[0];
// add style
progressIndicator.getStyleClass().add(firstStyle);
styleComboBox.setMaxWidth(Double.MAX_VALUE);
styleComboBox.setValue(firstStyle);
styleComboBox.valueProperty().addListener(it -> {
progressIndicator.getStyleClass().removeAll(styles);
progressIndicator.getStyleClass().add(styleComboBox.getValue());
});

// start Angle
Label startAngleLabel = new Label("Start Angle");
Slider startAngleSlider = new Slider(0, 360, 90);
progressIndicator.startAngleProperty().bind(startAngleSlider.valueProperty());
Label startAngleValue = new Label();
startAngleValue.setPrefWidth(30);
startAngleValue.textProperty().bind(Bindings.format("%.0f", startAngleSlider.valueProperty()));
HBox startAngleBox = new HBox(5, startAngleLabel, startAngleSlider, startAngleValue);
startAngleBox.setAlignment(Pos.CENTER_LEFT);

// graphic
FontIcon graphic = new FontIcon();
CheckBox showGraphic = new CheckBox("Show Graphic");
Expand All @@ -61,7 +76,7 @@ public void start(Stage primaryStage) {
indicatorWrapper.getStyleClass().add("indicator-wrapper");
VBox.setVgrow(indicatorWrapper, Priority.ALWAYS);

VBox bottom = new VBox(10, styleComboBox, showGraphic, customConverterBox);
VBox bottom = new VBox(10, showGraphic, customConverterBox, startAngleBox, styleComboBox);
bottom.setAlignment(Pos.CENTER_LEFT);
bottom.setMaxWidth(Region.USE_PREF_SIZE);

Expand All @@ -72,7 +87,7 @@ public void start(Stage primaryStage) {
containerBox.getChildren().addAll(indicatorWrapper, new Separator(), bottom);

Scene scene = new Scene(containerBox, 330, 390);
scene.getStylesheets().add(Objects.requireNonNull(CircleProgressIndicatorApp.class.getResource("circle-progress-indicator-demo.css")).toExternalForm());
scene.getStylesheets().add(Objects.requireNonNull(CircleProgressIndicatorApp.class.getResource("arc-progress-indicator-demo.css")).toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("CircleProgressIndicator Demo");
primaryStage.show();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package com.dlsc.gemsfx.demo;

import com.dlsc.gemsfx.SemiCircleProgressIndicator;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Service;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Separator;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import org.kordamp.ikonli.javafx.FontIcon;

import java.util.Objects;

public class SemiCircleProgressIndicatorApp extends Application {

private StringConverter<Double> customConverter;

@Override
public void start(Stage primaryStage) {
SemiCircleProgressIndicator progressIndicator = new SemiCircleProgressIndicator();
delayAutoUpdateProgress(progressIndicator);

// styles
String[] styles = new String[]{"bold-style", "thin-style", "sector-style", "default-style"};
ComboBox<String> styleComboBox = new ComboBox<>();
styleComboBox.getItems().addAll(styles);
String firstStyle = styles[0];
// add style
progressIndicator.getStyleClass().add(firstStyle);
styleComboBox.setValue(firstStyle);
styleComboBox.valueProperty().addListener(it -> {
progressIndicator.getStyleClass().removeAll(styles);
progressIndicator.getStyleClass().add(styleComboBox.getValue());
});

// graphic
FontIcon graphic = new FontIcon();
CheckBox showGraphic = new CheckBox("Show Graphic");
showGraphic.selectedProperty().addListener((observable, oldValue, newValue) -> {
progressIndicator.setGraphic(newValue ? graphic : null);
});
showGraphic.setSelected(true);

// string converter
StringConverter<Double> defaultConvert = progressIndicator.getConverter();
CheckBox customConverterBox = new CheckBox("Custom Converter");
customConverterBox.selectedProperty().addListener((observable, oldValue, newValue) -> progressIndicator.setConverter(newValue ? getCustomConverter() : defaultConvert));
customConverterBox.setSelected(true);

// layout
StackPane indicatorWrapper = new StackPane(progressIndicator);
indicatorWrapper.getStyleClass().add("indicator-wrapper");
VBox.setVgrow(indicatorWrapper, Priority.ALWAYS);

VBox bottom = new VBox(10, styleComboBox, showGraphic, customConverterBox);
bottom.setAlignment(Pos.CENTER_LEFT);
bottom.setMaxWidth(Region.USE_PREF_SIZE);

VBox containerBox = new VBox(20);
containerBox.getStyleClass().add("container-box");
containerBox.setPadding(new Insets(20));
containerBox.setAlignment(Pos.CENTER);
containerBox.getChildren().addAll(indicatorWrapper, new Separator(), bottom);

Scene scene = new Scene(containerBox, 300, 390);
scene.getStylesheets().add(Objects.requireNonNull(SemiCircleProgressIndicatorApp.class.getResource("arc-progress-indicator-demo.css")).toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("SemiCircleProgressIndicator");
primaryStage.show();
}

private void delayAutoUpdateProgress(SemiCircleProgressIndicator graphicIndicator) {
Service<Void> service = new Service<>() {
@Override
protected javafx.concurrent.Task<Void> createTask() {
return new javafx.concurrent.Task<>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i < 3000; i++) {
Thread.sleep(4500);
for (int j = 0; j <= 100; j++) {
updateProgress(j, 100);
Thread.sleep(50);
}
Thread.sleep(2000);
Platform.runLater(() -> updateProgress(-1, 100));
}
return null;
}
};
}
};
graphicIndicator.progressProperty().bind(service.progressProperty());
service.start();
}

private StringConverter<Double> getCustomConverter() {
if (customConverter == null) {
customConverter = new StringConverter<>() {
@Override
public String toString(Double progress) {
if (progress == null || progress < 0.0) {
return "Connecting";
}
double percentage = progress * 100;
if (progress.intValue() == 1) {
return "Download Complete";
}
return String.format("Downloading %.0f%%", percentage);
}

@Override
public Double fromString(String string) {
return null;
}
};
}
return customConverter;
}

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

}
Original file line number Diff line number Diff line change
@@ -1,57 +1,57 @@
.circle-progress-indicator {
.arc-progress-indicator {
/*-fx-font-family: Monospaced;*/
}

.circle-progress-indicator .progress-label {
.arc-progress-indicator .progress-label {
-fx-font-size: 15px;
}

/** --- icons --- */
.circle-progress-indicator .progress-label .ikonli-font-icon {
.arc-progress-indicator .progress-label .ikonli-font-icon {
-fx-icon-code: mdi-download;
-fx-icon-size: 16px;
}

.circle-progress-indicator:indeterminate .progress-label .ikonli-font-icon {
.arc-progress-indicator:indeterminate .progress-label .ikonli-font-icon {
-fx-icon-code: mdi-access-point-network;
}

.circle-progress-indicator:completed .progress-label .ikonli-font-icon {
.arc-progress-indicator:completed .progress-label .ikonli-font-icon {
-fx-icon-code: mdi-check-circle-outline;
}

/* --- bold style --- */
.circle-progress-indicator.bold-style .track-circle {
.arc-progress-indicator.bold-style .track-circle {
-fx-stroke-width: 10px;
-fx-stroke: #dadada;
}

.circle-progress-indicator.bold-style .progress-arc {
.arc-progress-indicator.bold-style .progress-arc {
-fx-stroke-width: 5px;
-fx-stroke: #67986e;
}

/** --- thin style --- */
.circle-progress-indicator.thin-style .track-circle {
.arc-progress-indicator.thin-style .track-circle {
-fx-stroke-width: 1px;
-fx-stroke: #c9c9c9;
}

.circle-progress-indicator.thin-style .progress-arc {
.arc-progress-indicator.thin-style .progress-arc {
-fx-stroke-width: 1px;
-fx-stroke: #f87328;
}

/** --- sector style --- */
.circle-progress-indicator.sector-style {
-fx-arc-type: ROUND;
.arc-progress-indicator.sector-style {
-fx-progress-arc-type: ROUND;
}

.circle-progress-indicator.sector-style .track-circle {
.arc-progress-indicator.sector-style .track-circle {
-fx-stroke-width: 5px;
}

.circle-progress-indicator.sector-style .progress-arc {
.arc-progress-indicator.sector-style .progress-arc {
-fx-fill: #47bce833;
-fx-stroke-width: 1px;
}
Expand All @@ -64,4 +64,4 @@
/** --- custom style --- */
.container-box {
-fx-background-color: white;
}
}
Loading

0 comments on commit adf3173

Please sign in to comment.