JavaFX应用

作者 : admin 本文共6202个字,预计阅读时间需要16分钟 发布时间: 2024-06-17 共1人阅读

JavaFX案例:集成进度条与后台任务

在这个示例中,我们将向JavaFX应用中集成一个进度条,用来展示一个模拟的后台任务的完成进度。这将涉及JavaFX的并发特性,特别是Task类和如何在UI线程安全地更新UI组件。

假设我们想要实现一个简单的场景:用户点击一个按钮开始一个耗时的任务,期间进度条会根据任务完成情况实时更新,任务完成后显示完成信息。

修改后的主类代码
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class JavaFXProgressBarDemo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// UI元素
Button startButton = new Button("开始任务");
ProgressBar progressBar = new ProgressBar(0);
Label statusLabel = new Label("等待任务开始...");
// 设置任务
Task<Void> task = createSimulationTask();
// 绑定进度条到任务
progressBar.progressProperty().bind(task.progressProperty());
// 任务状态监听
task.setOnSucceeded(event -> {
statusLabel.setText("任务完成!");
});
task.setOnFailed(event -> {
statusLabel.setText("任务失败!");
});
// 按钮点击事件处理
startButton.setOnAction(event -> {
progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
});
// 布局
VBox vbox = new VBox(10);
vbox.setAlignment(Pos.CENTER);
vbox.getChildren().addAll(startButton, progressBar, statusLabel);
// 场景
Scene scene = new Scene(vbox, 480, 200);
// 舞台
primaryStage.setTitle("JavaFX 进度条示例");
primaryStage.setScene(scene);
primaryStage.show();
}
private Task<Void> createSimulationTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 0; i <= 100; i++) {
updateProgress(i, 100);
Thread.sleep(50); // 模拟耗时操作,实际应用中应避免使用sleep
}
return null;
}
};
}
}
代码解析
  • 引入了一个ProgressBar和一个Button,以及一个用于显示任务状态的Label
  • 定义了一个createSimulationTask方法,返回一个Task实例。这个任务在后台线程中执行,模拟一个逐步完成的过程,通过调用updateProgress方法更新任务进度。
  • 将进度条的进度属性与任务的进度属性绑定,确保UI可以反映任务的实际完成情况。
  • 在按钮的点击事件处理器中,启动一个新线程来执行任务,并将进度条设置为不确定模式(INDETERMINATE_PROGRESS),直到任务开始报告具体进度。
  • 添加了对任务成功或失败的监听,以便在任务结束后更新状态信息。

通过这个示例,你学习了如何在JavaFX应用中使用进度条展示后台任务的进度,以及如何通过Task类安全地处理并发问题,保持UI的响应性和用户友好性。

JavaFX案例:实现图表展示(使用JavaFX Charts)

在前面的示例中,我们已经探索了JavaFX的基本UI组件、数据绑定、列表选择以及后台任务处理。现在,我们将进一步拓展,通过集成JavaFX Charts来创建一个动态的数据可视化界面。假设我们要展示一个简单的柱状图(Bar Chart),根据用户输入的数据动态更新图表。

准备工作

请注意,JavaFX Charts并非JavaFX核心库的一部分,需要单独引入相关依赖。如果你使用Maven或Gradle构建项目,需添加对应的依赖。

修改后的主类代码
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class JavaFXChartsDemo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// 创建X轴(分类轴)
CategoryAxis xAxis = new CategoryAxis();
xAxis.setLabel("类别");
// 创建Y轴(数值轴)
NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("数量");
// 创建柱状图
BarChart<String, Number> barChart = new BarChart<>(xAxis, yAxis);
// 设置图表标题
barChart.setTitle("数据分布");
// 数据准备
ObservableList<XYChart.Series<String, Number>> data = 
FXCollections.observableArrayList(
new XYChart.Series<>("类别A", FXCollections.observableArrayList(
new XYChart.Data<>("项目1", 20),
new XYChart.Data<>("项目2", 30),
new XYChart.Data<>("项目3", 15)
)),
new XYChart.Series<>("类别B", FXCollections.observableArrayList(
new XYChart.Data<>("项目1", 25),
new XYChart.Data<>("项目2", 35),
new XYChart.Data<>("项目3", 9)
))
);
// 将数据添加到图表
barChart.getData().addAll(data);
// 使用BorderPane作为根容器,并将图表置于其中
BorderPane root = new BorderPane();
root.setCenter(barChart);
// 创建场景
Scene scene = new Scene(root, 800, 600);
// 设置舞台
primaryStage.setTitle("JavaFX 图表示例");
primaryStage.setScene(scene);
primaryStage.show();
}
}
代码解析
  • 引入了BarChartCategoryAxisNumberAxis,这些是JavaFX Charts库中用于创建柱状图的类。
  • 创建了X轴(用于分类)和Y轴(用于数值),并设置了它们的标签。
  • 通过XYChart.SeriesXYChart.Data构建了两组数据,分别代表不同类别的数据分布。
  • 将数据集添加到BarChart中,并设置了图表的标题。
  • 使用BorderPane作为根布局容器,将柱状图放置于中心位置。
  • 最后,像之前一样创建场景并显示舞台。

通过这个示例,你学习了如何在JavaFX应用中集成图表,为用户提供直观的数据可视化功能。尽管这里展示了静态数据的图表展示,但同样的原理可以应用于动态数据更新,以响应用户输入或其他实时数据源。

JavaFX案例:实现拖放功能(Drag and Drop)

在本示例中,我们将为JavaFX应用添加拖放(Drag and Drop)功能,让用户能够直接通过鼠标操作来移动或重新排序UI元素。我们将创建一个简单的界面,其中包含几个可拖动的标签,用户可以将这些标签拖放到一个目标区域。

修改后的主类代码
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class JavaFXDragAndDropDemo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
// 创建可拖动的标签集合
Label label1 = createDraggableLabel("标签1");
Label label2 = createDraggableLabel("标签2");
Label label3 = createDraggableLabel("标签3");
// 创建目标区域
Pane targetArea = new Pane();
targetArea.setStyle("-fx-background-color: #DDDDDD; -fx-border-color: black;");
targetArea.setPrefSize(200, 200);
// 设置目标区域为可接受拖放
targetArea.setOnDragOver(event -> {
Dragboard db = event.getDragboard();
if (db.hasString()) {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
}
event.consume();
});
targetArea.setOnDragDropped(event -> {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString()) {
Label label = (Label) event.getGestureSource();
label.relocate(event.getX() - (label.getWidth() / 2), event.getY() - (label.getHeight() / 2));
targetArea.getChildren().add(label);
success = true;
}
event.setDropCompleted(success);
event.consume();
});
// 布局
VBox vbox = new VBox(10, label1, label2, label3);
HBox hbox = new HBox(10, vbox, targetArea);
// 场景
Scene scene = new Scene(hbox, 600, 400);
// 舞台
primaryStage.setTitle("JavaFX 拖放示例");
primaryStage.setScene(scene);
primaryStage.show();
}
private Label createDraggableLabel(String text) {
Label label = new Label(text);
label.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
Dragboard db = label.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putString(label.getText());
db.setContent(content);
event.consume();
}
});
return label;
}
}
代码解析
  • 通过createDraggableLabel方法创建可拖动的Label,为其添加onDragDetected事件处理器,用于启动拖放操作。
  • 当拖动开始时,我们使用Dragboard存储要传输的数据(这里是标签的文本),并设置允许的传输模式。
  • 目标区域(Pane)设置了onDragOveronDragDropped事件处理器,允许拖放并处理放下事件,将拖动的标签添加到目标区域,并调整位置。
  • 布局使用HBoxVBox来组织可拖动的标签和目标区域。

通过这个示例,你学习了如何在JavaFX应用中实现拖放功能,这增强了用户界面的交互性,让用户能直接参与和控制UI元素的布局或排序。

本站无任何商业行为
个人在线分享 » JavaFX应用
E-->