动态选题 2025年3月19日17:32:03

master
qmstyle 2025-03-19 17:32:12 +08:00
parent 114181a823
commit 07d045c305
15 changed files with 462 additions and 8 deletions

View File

@ -31,4 +31,6 @@ public interface DataLoad {
public void updateData(String id, String name, String oldValue, String newValue); public void updateData(String id, String name, String oldValue, String newValue);
List<MenuItem> getContextMenu(); List<MenuItem> getContextMenu();
ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize);
} }

View File

@ -134,4 +134,9 @@ public class AnswerDataLoad implements DataLoad {
public List<MenuItem> getContextMenu() { public List<MenuItem> getContextMenu() {
return null; return null;
} }
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
return null;
}
} }

View File

@ -116,4 +116,9 @@ public class OptionDataLoad implements DataLoad {
public List<MenuItem> getContextMenu() { public List<MenuItem> getContextMenu() {
return null; return null;
} }
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
return null;
}
} }

View File

@ -8,6 +8,8 @@ import com.zhangmeng.online.exam.ui.api.ApiUtils;
import com.zhangmeng.online.exam.ui.api.DataLoad; import com.zhangmeng.online.exam.ui.api.DataLoad;
import com.zhangmeng.online.exam.ui.api.form.UserForm; import com.zhangmeng.online.exam.ui.api.form.UserForm;
import com.zhangmeng.online.exam.ui.components.DynamicTableComponent; import com.zhangmeng.online.exam.ui.components.DynamicTableComponent;
import com.zhangmeng.online.exam.ui.components.PaperViewComponent;
import com.zhangmeng.online.exam.ui.components.callBack.PaperViewComponentCallBackImpl;
import com.zhangmeng.online.exam.ui.utils.AlertUtils; import com.zhangmeng.online.exam.ui.utils.AlertUtils;
import com.zhangmeng.online.exam.ui.utils.HttpUtils; import com.zhangmeng.online.exam.ui.utils.HttpUtils;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@ -136,15 +138,30 @@ public class PaperDataLoad implements DataLoad {
@Override @Override
public List<MenuItem> getContextMenu() { public List<MenuItem> getContextMenu() {
MenuItem group_volumes = new MenuItem("组卷"); MenuItem group_volumes = new MenuItem("组卷");
group_volumes.setOnAction(event -> { group_volumes.setOnAction(event -> {
Map<String, SimpleStringProperty> map = ApiUtils.selectedItem(group_volumes); Map<String, SimpleStringProperty> map = ApiUtils.selectedItem(group_volumes);
String id = map.get("id").getValue(); String id = map.get("id").getValue();
AlertUtils.alert_msg("组卷正在开发中..." + id); // AlertUtils.alert_msg("组卷正在开发中..." + id);
ContextMenu parentPopup = group_volumes.getParentPopup();
IndexPage indexPage = (IndexPage)parentPopup.getStyleableParent();
Stage stage = (Stage) indexPage.getScene().getWindow();
PaperViewComponent paperViewComponent = new PaperViewComponent(new PaperViewComponentCallBackImpl());
paperViewComponent.setPrefWidth(1200);
paperViewComponent.setPrefHeight(649);
AlertUtils.alert("组卷",paperViewComponent,1200,649,stage,true);
}); });
return Arrays.asList(group_volumes); return Arrays.asList(group_volumes);
} }
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
AlertUtils.alert_msg("搜索功能正在开发中..." + JSON.toJSONString(searchText));
return null;
}
} }

View File

@ -79,4 +79,9 @@ public class PermissionDataLoad implements DataLoad {
public List<MenuItem> getContextMenu() { public List<MenuItem> getContextMenu() {
return null; return null;
} }
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
return null;
}
} }

View File

@ -80,4 +80,9 @@ public class QuestionDataLoad implements DataLoad {
public List<MenuItem> getContextMenu() { public List<MenuItem> getContextMenu() {
return null; return null;
} }
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
return null;
}
} }

View File

@ -116,4 +116,9 @@ public class QuestionOptionDataLoad implements DataLoad {
public List<MenuItem> getContextMenu() { public List<MenuItem> getContextMenu() {
return null; return null;
} }
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
return null;
}
} }

View File

@ -80,4 +80,9 @@ public class RoleDataLoad implements DataLoad {
public List<MenuItem> getContextMenu() { public List<MenuItem> getContextMenu() {
return null; return null;
} }
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
return null;
}
} }

View File

@ -115,4 +115,9 @@ public class SubjectDataLoad implements DataLoad {
public List<MenuItem> getContextMenu() { public List<MenuItem> getContextMenu() {
return null; return null;
} }
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
return null;
}
} }

View File

@ -137,6 +137,11 @@ public class UserDataLoad implements DataLoad {
return null;
}
@Override
public ApiUtils.DataView searchData(Map<String, Object> searchText, int pageNum, int pageSize) {
return null; return null;
} }
} }

View File

@ -0,0 +1,53 @@
package com.zhangmeng.online.exam.ui.components;
import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
/**
* @author zm
* @date 2025/3/19 17:03
* @version: 1.0
*/
public class PaperSearchComponent extends HBox {
private Button searchButton;
private SimpleStringProperty questionName = new SimpleStringProperty();
public PaperSearchComponent(double spacing) {
super();
this.setSpacing(spacing);
Label label = new Label("问题名称:");
label.setPadding(new Insets(5, 0, 0, 0));
TextField questionName = new TextField();
questionName.textProperty().bindBidirectional(this.questionName);
searchButton = new Button("搜索");
this.getChildren().add(label);
this.getChildren().add(questionName);
this.getChildren().add(searchButton);
}
public Button getSearchButton() {
return searchButton;
}
public void setSearchButton(Button searchButton) {
this.searchButton = searchButton;
}
public SimpleStringProperty getQuestionName() {
return questionName;
}
public void setQuestionName(SimpleStringProperty questionName) {
this.questionName = questionName;
}
}

View File

@ -1,5 +1,31 @@
package com.zhangmeng.online.exam.ui.components; package com.zhangmeng.online.exam.ui.components;
import com.zhangmeng.online.exam.ui.api.ApiUtils;
import com.zhangmeng.online.exam.ui.api.DataLoad;
import com.zhangmeng.online.exam.ui.components.callBack.PaperViewComponentCallBack;
import com.zhangmeng.online.exam.ui.utils.AlertUtils;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.control.cell.MapValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Paint;
import javafx.util.Callback;
import org.casic.javafx.control.PaginationPicker;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* *
* *
@ -7,9 +33,271 @@ package com.zhangmeng.online.exam.ui.components;
* @date 2025/3/19 12:22 * @date 2025/3/19 12:22
* @version: 1.0 * @version: 1.0
*/ */
public class PaperViewComponent { public class PaperViewComponent extends SplitPane {
private VBox vbox;
private PaperViewComponentCallBack callBack;
private TableView<Map<String, SimpleStringProperty>> questionTable;
private final ObservableList<Map<String, SimpleStringProperty>> questionTable_data = FXCollections.observableArrayList();
private TableView<Map<String, SimpleStringProperty>> chooseTable;
//已选题目列表
private final ObservableList<Map<String, SimpleStringProperty>> chooseTable_data = FXCollections.observableArrayList();
public PaperViewComponent(PaperViewComponentCallBack callBack) {
super();
setCallBack(callBack);
initQuestionTable();
initChooseTable();
this.setOrientation(Orientation.VERTICAL);
this.setDividerPositions(0.5);
this.getItems().add(vbox);
this.getItems().add(chooseTable);
}
private void initQuestionTable() {
vbox = new VBox(5);
vbox.setAlignment(Pos.CENTER_LEFT);
vbox.prefHeightProperty().bind(this.heightProperty().divide(2));
vbox.prefWidthProperty().bind(this.widthProperty());
ApiUtils.DataView dataView = callBack.loadQuestionData(ApiUtils.PAGE_NUM, ApiUtils.PAGE_SIZE);
questionTable = new TableView<>();
questionTable.setItems(questionTable_data);
// questionTable.setEditable(true);
questionTable.prefHeightProperty().bind(vbox.heightProperty());
questionTable.prefWidthProperty().bind(vbox.widthProperty());
List<String> columns = dataView.getKeys().stream().filter(key -> !key.equals("id")).toList();
columns.forEach(col -> {
TableColumn<Map<String, SimpleStringProperty>, String> column = new TableColumn<>(col);
// 数据绑定‌:ml-citation{ref="1,3" data="citationList"}
column.setCellValueFactory(new MapValueFactory(col));
// 启用单元格编辑‌:ml-citation{ref="4,5" data="citationList"}
column.setCellFactory(TextFieldTableCell.forTableColumn());
column.prefWidthProperty().bind(questionTable.widthProperty().divide(columns.size()).subtract(40));
questionTable.getColumns().add(column);
});
//添加按钮
TableColumn<Map<String, SimpleStringProperty>, String> addColumn = new TableColumn<>("操作");
addColumn.setCellFactory(new Callback<>() {
@Override
public TableCell<Map<String, SimpleStringProperty>, String> call(TableColumn<Map<String, SimpleStringProperty>, String> mapStringTableColumn) {
return new TableCell<>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
HBox hBox = new HBox();
// hBox.setPrefHeight(30);
hBox.setAlignment(Pos.CENTER);
// hBox.setStyle("-fx-background-color: #1094e9");
Button button = new Button("添加");
button.setTextFill(Paint.valueOf("#1094e9"));
TableRow<Map<String, SimpleStringProperty>> row = this.getTableRow();
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (row.getItem() != null) {
Platform.runLater(new Runnable() {
@Override
public void run() {
chooseTable_data.add(row.getItem());
questionTable_data.remove(row.getItem());
}
});
}
}
});
hBox.getChildren().addAll(button);
this.setGraphic(hBox);
} else {
this.setGraphic(null);
}
}
};
}
});
addColumn.prefWidthProperty().bind(questionTable.widthProperty().divide(columns.size()+2).subtract(50));
questionTable.getColumns().add(addColumn);
questionTable_data.addAll(dataView.getDataList());
//初始化一个分页
PaginationPicker paginationPicker = new PaginationPicker();
paginationPicker.setTotal(dataView.getTotal());//设置总数据量默认0
paginationPicker.setPageSize(dataView.getPageSize());//设置每页显示条数默认30
paginationPicker.setPageButtonCount(9);//设置页码按钮的数量默认7当总页数超过该值时会折叠大于等于 5 且小于等于 21 的奇数
paginationPicker.setCurrentPage(dataView.getPageNum());//设置当前选择页码默认第一页注意必须放在所有设置条件之后。不小于0 并且 不大于总页数
paginationPicker.setPaginationButtonFontSize(12);//设置分页字体大小默认10(不小于2)
//监听点击动作事件
paginationPicker.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// System.out.println("当前选择页码:"+paginationPicker.getCurrentPage());
questionTable_data.clear();
questionTable_data.addAll(callBack.loadQuestionData(paginationPicker.getCurrentPage(), paginationPicker.getPageSize()).getDataList());
}
});
PaperSearchComponent hBox = new PaperSearchComponent(5);
hBox.getSearchButton().setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
String searchText = hBox.getQuestionName().get();
if (searchText == null || searchText.trim().isEmpty()) {
AlertUtils.alert_msg("搜索内容不能为空!");
return;
}
questionTable_data.clear();
questionTable_data.addAll(callBack.searchQuestionData(searchText, paginationPicker.getCurrentPage(), paginationPicker.getPageSize()).getDataList());
}
});
vbox.setPadding(new Insets(5));
vbox.getChildren().addAll(hBox,questionTable, paginationPicker);
}
private void initChooseTable() {
ApiUtils.DataView dataView = callBack.loadChooseQuestionData(ApiUtils.PAGE_NUM, ApiUtils.PAGE_SIZE);
chooseTable = new TableView<>();
chooseTable.setItems(chooseTable_data);
// chooseTable.setEditable(true);
chooseTable.prefHeightProperty().bind(this.heightProperty().divide(2));
chooseTable.prefWidthProperty().bind(this.widthProperty());
List<String> columns = dataView.getKeys().stream().filter(key -> !key.equals("id")).toList();
columns.forEach(col -> {
TableColumn<Map<String, SimpleStringProperty>, String> column = new TableColumn<>(col);
// 数据绑定‌:ml-citation{ref="1,3" data="citationList"}
column.setCellValueFactory(new MapValueFactory(col));
// 启用单元格编辑‌:ml-citation{ref="4,5" data="citationList"}
column.setCellFactory(TextFieldTableCell.forTableColumn());
column.prefWidthProperty().bind(chooseTable.widthProperty().divide(columns.size()).subtract(40));
chooseTable.getColumns().add(column);
});
//添加按钮
TableColumn<Map<String, SimpleStringProperty>, String> addColumn = new TableColumn<>("操作");
addColumn.setCellFactory(new Callback<>() {
@Override
public TableCell<Map<String, SimpleStringProperty>, String> call(TableColumn<Map<String, SimpleStringProperty>, String> mapStringTableColumn) {
return new TableCell<>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
HBox hBox = new HBox();
// hBox.setPrefHeight(30);
hBox.setAlignment(Pos.CENTER);
// hBox.setStyle("-fx-background-color: #1094e9");
Button button = new Button("删除");
button.setTextFill(Paint.valueOf("#1094e9"));
TableRow<Map<String, SimpleStringProperty>> row = this.getTableRow();
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (row.getItem() != null) {
Platform.runLater(new Runnable() {
@Override
public void run() {
questionTable_data.add(row.getItem());
chooseTable_data.remove(row.getItem());
}
});
}
}
});
hBox.getChildren().addAll(button);
this.setGraphic(hBox);
} else {
this.setGraphic(null);
}
}
};
}
});
addColumn.prefWidthProperty().bind(chooseTable.widthProperty().divide(columns.size()+2).subtract(50));
chooseTable.getColumns().add(addColumn);
//初始化一个分页
PaginationPicker paginationPicker = new PaginationPicker();
paginationPicker.setTotal(dataView.getTotal());//设置总数据量默认0
paginationPicker.setPageSize(dataView.getPageSize());//设置每页显示条数默认30
paginationPicker.setPageButtonCount(9);//设置页码按钮的数量默认7当总页数超过该值时会折叠大于等于 5 且小于等于 21 的奇数
paginationPicker.setCurrentPage(dataView.getPageNum());//设置当前选择页码默认第一页注意必须放在所有设置条件之后。不小于0 并且 不大于总页数
paginationPicker.setPaginationButtonFontSize(12);//设置分页字体大小默认10(不小于2)
//监听点击动作事件
paginationPicker.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// System.out.println("当前选择页码:"+paginationPicker.getCurrentPage());
chooseTable_data.clear();
chooseTable_data.addAll(callBack.loadQuestionData(paginationPicker.getCurrentPage(), paginationPicker.getPageSize()).getDataList());
}
});
} }
public TableView<Map<String, SimpleStringProperty>> getQuestionTable() {
return questionTable;
}
public void setQuestionTable(TableView<Map<String, SimpleStringProperty>> questionTable) {
this.questionTable = questionTable;
}
public TableView<Map<String, SimpleStringProperty>> getChooseTable() {
return chooseTable;
}
public void setChooseTable(TableView<Map<String, SimpleStringProperty>> chooseTable) {
this.chooseTable = chooseTable;
}
public ObservableList<Map<String, SimpleStringProperty>> getQuestionTable_data() {
return questionTable_data;
}
public PaperViewComponentCallBack getCallBack() {
return callBack;
}
public void setCallBack(PaperViewComponentCallBack callBack) {
this.callBack = callBack;
}
public ObservableList<Map<String, SimpleStringProperty>> getChooseTable_data() {
return chooseTable_data;
}
public VBox getVbox() {
return vbox;
}
public void setVbox(VBox vbox) {
this.vbox = vbox;
}
}

View File

@ -0,0 +1,20 @@
package com.zhangmeng.online.exam.ui.components.callBack;
import com.zhangmeng.online.exam.ui.api.ApiUtils;
import javafx.beans.property.SimpleStringProperty;
import java.util.List;
import java.util.Map;
/**
* @author zm
* @date 2025/3/19 14:26
* @version: 1.0
*/
public interface PaperViewComponentCallBack {
ApiUtils.DataView loadQuestionData(int pageNum, int pageSize);
ApiUtils.DataView loadChooseQuestionData(int pageNum, int pageSize);
ApiUtils.DataView searchQuestionData(String searchText, int pageNum, int pageSize);
}

View File

@ -0,0 +1,35 @@
package com.zhangmeng.online.exam.ui.components.callBack;
import com.zhangmeng.online.exam.ui.api.ApiUtils;
import com.zhangmeng.online.exam.ui.api.DataLoad;
import com.zhangmeng.online.exam.ui.api.model.PaperDataLoad;
import com.zhangmeng.online.exam.ui.api.model.QuestionDataLoad;
import javafx.beans.property.SimpleStringProperty;
import java.util.List;
import java.util.Map;
/**
* @author zm
* @date 2025/3/19 14:31
* @version: 1.0
*/
public class PaperViewComponentCallBackImpl implements PaperViewComponentCallBack {
@Override
public ApiUtils.DataView loadQuestionData(int pageNum, int pageSize) {
DataLoad dataLoad = new QuestionDataLoad();
return dataLoad.loadData(pageNum, pageSize);
}
@Override
public ApiUtils.DataView loadChooseQuestionData(int pageNum, int pageSize) {
DataLoad dataLoad = new QuestionDataLoad();
return dataLoad.loadData(pageNum, pageSize);
}
@Override
public ApiUtils.DataView searchQuestionData(String searchText, int pageNum, int pageSize) {
DataLoad dataLoad = new PaperDataLoad();
return dataLoad.searchData(Map.of("searchText", searchText), pageNum, pageSize);
}
}

View File

@ -65,12 +65,11 @@ public class AlertUtils {
} }
public static void alert(String title, Parent node, Stage primaryStage) { public static void alert(String title, Parent node, Stage primaryStage) {
alert(title, node, 600, 400, primaryStage); alert(title, node, 600, 400, primaryStage,false);
} }
public static void alert(String title, Parent node, int width, int height, Stage primaryStage) { public static void alert(String title, Parent node, int width, int height, Stage primaryStage,boolean isResizable) {
Scene scene = new Scene(node);
Scene scene = new Scene(new Group(node));
Stage stage = new Stage(); Stage stage = new Stage();
stage.setScene(scene); stage.setScene(scene);
stage.setTitle(title); stage.setTitle(title);
@ -79,7 +78,7 @@ public class AlertUtils {
stage.initStyle(StageStyle.UTILITY); stage.initStyle(StageStyle.UTILITY);
stage.initOwner(primaryStage); stage.initOwner(primaryStage);
stage.initModality(Modality.APPLICATION_MODAL); stage.initModality(Modality.APPLICATION_MODAL);
stage.setResizable(false); stage.setResizable(isResizable);
stage.show(); stage.show();
stage.setOnCloseRequest(e -> { stage.setOnCloseRequest(e -> {
stage.close(); stage.close();