add JavaFX demo application
- Add FxMain as JavaFX application entry with IOC integration - Add FxConfig with @Bean factory methods for DateTimeFormatter - Add MainController with constructor injection - Add UserService and MessageService layers - Add main.fxml view with user management UI - Add javafx-fxml dependency and javafx-maven-plugin - Add demo documentation and run script - Demonstrate @Controller, @Service, @Qualifier, @PostConstruct in JavaFX context Run with: mvn javafx:run or run-javafx-demo.bat Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
30
src/test/java/com/imyeyu/inject/javafxdemo/FxConfig.java
Normal file
30
src/test/java/com/imyeyu/inject/javafxdemo/FxConfig.java
Normal file
@ -0,0 +1,30 @@
|
||||
package com.imyeyu.inject.javafxdemo;
|
||||
|
||||
import com.imyeyu.inject.annotation.Bean;
|
||||
import com.imyeyu.inject.annotation.Configuration;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* JavaFX 应用配置
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Configuration
|
||||
public class FxConfig {
|
||||
|
||||
@Bean
|
||||
public DateTimeFormatter dateTimeFormatter() {
|
||||
return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
@Bean("appTitle")
|
||||
public String appTitle() {
|
||||
return "Timi-Inject JavaFX Demo";
|
||||
}
|
||||
|
||||
@Bean("version")
|
||||
public String version() {
|
||||
return "0.0.2";
|
||||
}
|
||||
}
|
||||
51
src/test/java/com/imyeyu/inject/javafxdemo/FxMain.java
Normal file
51
src/test/java/com/imyeyu/inject/javafxdemo/FxMain.java
Normal file
@ -0,0 +1,51 @@
|
||||
package com.imyeyu.inject.javafxdemo;
|
||||
|
||||
import com.imyeyu.inject.TimiInject;
|
||||
import com.imyeyu.inject.annotation.Import;
|
||||
import com.imyeyu.inject.annotation.TimiInjectApplication;
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* JavaFX 应用入口
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@TimiInjectApplication("com.imyeyu.inject.javafxdemo")
|
||||
@Import(FxConfig.class)
|
||||
public class FxMain extends Application {
|
||||
|
||||
private static TimiInject inject;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 启动 IOC 容器
|
||||
inject = TimiInject.run(FxMain.class);
|
||||
|
||||
// 启动 JavaFX 应用
|
||||
launch(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
// 创建 FXMLLoader 并设置控制器工厂
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/javafxdemo/main.fxml"));
|
||||
loader.setControllerFactory(type -> inject.di(type));
|
||||
|
||||
Parent root = loader.load();
|
||||
|
||||
Scene scene = new Scene(root, 600, 400);
|
||||
primaryStage.setTitle("Timi-Inject JavaFX Demo");
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 IOC 容器实例
|
||||
*/
|
||||
public static TimiInject getInject() {
|
||||
return inject;
|
||||
}
|
||||
}
|
||||
132
src/test/java/com/imyeyu/inject/javafxdemo/MainController.java
Normal file
132
src/test/java/com/imyeyu/inject/javafxdemo/MainController.java
Normal file
@ -0,0 +1,132 @@
|
||||
package com.imyeyu.inject.javafxdemo;
|
||||
|
||||
import com.imyeyu.inject.annotation.Controller;
|
||||
import com.imyeyu.inject.annotation.PostConstruct;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
|
||||
/**
|
||||
* 主界面控制器
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Controller
|
||||
public class MainController {
|
||||
|
||||
@FXML
|
||||
private Label welcomeLabel;
|
||||
|
||||
@FXML
|
||||
private Label timeLabel;
|
||||
|
||||
@FXML
|
||||
private Label countLabel;
|
||||
|
||||
@FXML
|
||||
private TextField usernameField;
|
||||
|
||||
@FXML
|
||||
private ListView<String> userListView;
|
||||
|
||||
@FXML
|
||||
private TextArea logArea;
|
||||
|
||||
private final UserService userService;
|
||||
private final MessageService messageService;
|
||||
private final ObservableList<String> userList = FXCollections.observableArrayList();
|
||||
|
||||
public MainController(UserService userService, MessageService messageService) {
|
||||
this.userService = userService;
|
||||
this.messageService = messageService;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
log("MainController initialized");
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
// 设置欢迎消息
|
||||
welcomeLabel.setText(messageService.getWelcomeMessage());
|
||||
|
||||
// 加载用户列表
|
||||
refreshUserList();
|
||||
|
||||
// 更新时间
|
||||
updateTime();
|
||||
|
||||
log("UI initialized");
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleAddUser() {
|
||||
String username = usernameField.getText().trim();
|
||||
if (username.isEmpty()) {
|
||||
showError("Please enter a username");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
userService.addUser(username);
|
||||
refreshUserList();
|
||||
usernameField.clear();
|
||||
log(messageService.getSuccessMessage("User added"));
|
||||
} catch (Exception e) {
|
||||
showError(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleRemoveUser() {
|
||||
String selectedUser = userListView.getSelectionModel().getSelectedItem();
|
||||
if (selectedUser == null) {
|
||||
showError("Please select a user to remove");
|
||||
return;
|
||||
}
|
||||
|
||||
userService.removeUser(selectedUser);
|
||||
refreshUserList();
|
||||
log(messageService.getSuccessMessage("User removed"));
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleRefresh() {
|
||||
refreshUserList();
|
||||
updateTime();
|
||||
log("Refreshed");
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void handleClearLog() {
|
||||
logArea.clear();
|
||||
log("Log cleared");
|
||||
}
|
||||
|
||||
private void refreshUserList() {
|
||||
userList.clear();
|
||||
userList.addAll(userService.getAllUsers());
|
||||
userListView.setItems(userList);
|
||||
countLabel.setText("Total Users: " + userService.getUserCount());
|
||||
}
|
||||
|
||||
private void updateTime() {
|
||||
timeLabel.setText("Current Time: " + userService.getCurrentTime());
|
||||
}
|
||||
|
||||
private void showError(String message) {
|
||||
log(messageService.getErrorMessage(message));
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("Error");
|
||||
alert.setHeaderText(null);
|
||||
alert.setContentText(message);
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
private void log(String message) {
|
||||
String timestamp = userService.getCurrentTime();
|
||||
logArea.appendText(String.format("[%s] %s%n", timestamp, message));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.imyeyu.inject.javafxdemo;
|
||||
|
||||
import com.imyeyu.inject.annotation.Qualifier;
|
||||
import com.imyeyu.inject.annotation.Service;
|
||||
|
||||
/**
|
||||
* 消息服务
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Service
|
||||
public class MessageService {
|
||||
|
||||
private final String appTitle;
|
||||
private final String version;
|
||||
|
||||
public MessageService(@Qualifier("appTitle") String appTitle,
|
||||
@Qualifier("version") String version) {
|
||||
this.appTitle = appTitle;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getWelcomeMessage() {
|
||||
return String.format("Welcome to %s v%s!", appTitle, version);
|
||||
}
|
||||
|
||||
public String getSuccessMessage(String action) {
|
||||
return action + " successfully!";
|
||||
}
|
||||
|
||||
public String getErrorMessage(String error) {
|
||||
return "Error: " + error;
|
||||
}
|
||||
}
|
||||
59
src/test/java/com/imyeyu/inject/javafxdemo/UserService.java
Normal file
59
src/test/java/com/imyeyu/inject/javafxdemo/UserService.java
Normal file
@ -0,0 +1,59 @@
|
||||
package com.imyeyu.inject.javafxdemo;
|
||||
|
||||
import com.imyeyu.inject.annotation.PostConstruct;
|
||||
import com.imyeyu.inject.annotation.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Service
|
||||
public class UserService {
|
||||
|
||||
private final DateTimeFormatter dateTimeFormatter;
|
||||
private final List<String> users = new ArrayList<>();
|
||||
|
||||
public UserService(DateTimeFormatter dateTimeFormatter) {
|
||||
this.dateTimeFormatter = dateTimeFormatter;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
users.add("Admin");
|
||||
users.add("User1");
|
||||
users.add("User2");
|
||||
System.out.println("UserService initialized with " + users.size() + " users");
|
||||
}
|
||||
|
||||
public List<String> getAllUsers() {
|
||||
return new ArrayList<>(users);
|
||||
}
|
||||
|
||||
public void addUser(String username) {
|
||||
if (username == null || username.isBlank()) {
|
||||
throw new IllegalArgumentException("Username cannot be empty");
|
||||
}
|
||||
if (users.contains(username)) {
|
||||
throw new IllegalArgumentException("User already exists");
|
||||
}
|
||||
users.add(username);
|
||||
}
|
||||
|
||||
public void removeUser(String username) {
|
||||
users.remove(username);
|
||||
}
|
||||
|
||||
public String getCurrentTime() {
|
||||
return LocalDateTime.now().format(dateTimeFormatter);
|
||||
}
|
||||
|
||||
public int getUserCount() {
|
||||
return users.size();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user