2025年3月5日15:27:35
parent
30f5bbbd14
commit
cb3f90eafb
|
|
@ -1,9 +1,16 @@
|
||||||
package com.zhangmeng.online.exam.ui;
|
package com.zhangmeng.online.exam.ui;
|
||||||
import com.zhangmeng.online.exam.ui.admin.LoginPage;
|
import com.zhangmeng.online.exam.ui.admin.LoginPage;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Accordion;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.TitledPane;
|
||||||
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -19,6 +26,8 @@ public class OnlineExamApplication extends Application {
|
||||||
stage.setTitle("在线考试系统");
|
stage.setTitle("在线考试系统");
|
||||||
stage.show();
|
stage.show();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zm
|
* @author zm
|
||||||
* @date 2025/3/5 9:36
|
* @date 2025/3/5 9:36
|
||||||
|
|
@ -19,7 +22,18 @@ public class IndexPage extends BorderPane {
|
||||||
private SideMenu sideMenu = null;
|
private SideMenu sideMenu = null;
|
||||||
|
|
||||||
public IndexPage() {
|
public IndexPage() {
|
||||||
sideMenu = new SideMenu(); // 导航栏容器
|
|
||||||
|
SideMenu.SideMenuItem item1 = new SideMenu.SideMenuItem("试卷管理", new SideMenu.SideMenuData("试卷管理", "/paper/list"));
|
||||||
|
SideMenu.SideMenuItem item2 = new SideMenu.SideMenuItem("题库管理", new SideMenu.SideMenuData("题库管理", "/question/list"));
|
||||||
|
SideMenu.SideMenuItem item3 = new SideMenu.SideMenuItem("用户管理", new SideMenu.SideMenuData("用户管理", "/user/list"));
|
||||||
|
SideMenu.SideMenuItem item4 = new SideMenu.SideMenuItem("系统设置", new SideMenu.SideMenuData("系统设置", "/system/setting"));
|
||||||
|
List<SideMenu.SideMenuItem> menuItems = new ArrayList<>();
|
||||||
|
menuItems.add(item1);
|
||||||
|
menuItems.add(item2);
|
||||||
|
menuItems.add(item3);
|
||||||
|
menuItems.add(item4);
|
||||||
|
|
||||||
|
sideMenu = new SideMenu(menuItems); // 导航栏容器
|
||||||
StackPane contentArea = new StackPane(); // 右侧内容区
|
StackPane contentArea = new StackPane(); // 右侧内容区
|
||||||
contentArea.setStyle("-fx-background-color: #3ce53c;");
|
contentArea.setStyle("-fx-background-color: #3ce53c;");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.zhangmeng.online.exam.ui.components;
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.scene.control.TableColumn;
|
||||||
|
import javafx.scene.control.TableView;
|
||||||
|
import javafx.scene.control.cell.TextFieldTableCell;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态表格
|
||||||
|
*
|
||||||
|
* @author zm
|
||||||
|
* @date 2025/3/5 15:17
|
||||||
|
* @version: 1.0
|
||||||
|
*/
|
||||||
|
public class DynamicTableComponent extends VBox {
|
||||||
|
private final ObservableList<DynamicDataModel> data = FXCollections.observableArrayList();
|
||||||
|
|
||||||
|
// 数据模型定义(使用JavaFX属性):ml-citation{ref="1,3" data="citationList"}
|
||||||
|
public static class DynamicDataModel {
|
||||||
|
private final Map<String, SimpleStringProperty> properties = new HashMap<>();
|
||||||
|
|
||||||
|
public DynamicDataModel(Map<String, String> data) {
|
||||||
|
data.forEach((k, v) ->
|
||||||
|
properties.put(k, new SimpleStringProperty(v))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleStringProperty getProperty(String key) {
|
||||||
|
return properties.get(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicTableComponent() {
|
||||||
|
super();
|
||||||
|
TableView<DynamicDataModel> tableView = new TableView<>();
|
||||||
|
|
||||||
|
// 动态生成列(示例字段):ml-citation{ref="3,4" data="citationList"}
|
||||||
|
List<String> columns = Arrays.asList("姓名", "年龄", "城市");
|
||||||
|
columns.forEach(col -> {
|
||||||
|
TableColumn<DynamicDataModel, String> column =
|
||||||
|
new TableColumn<>(col);
|
||||||
|
|
||||||
|
// 数据绑定:ml-citation{ref="1,3" data="citationList"}
|
||||||
|
column.setCellValueFactory(param ->
|
||||||
|
param.getValue().getProperty(col)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 启用单元格编辑:ml-citation{ref="4,5" data="citationList"}
|
||||||
|
column.setCellFactory(TextFieldTableCell.forTableColumn());
|
||||||
|
column.setOnEditCommit(event -> {
|
||||||
|
DynamicDataModel row = event.getRowValue();
|
||||||
|
row.getProperty(col).set(event.getNewValue());
|
||||||
|
});
|
||||||
|
|
||||||
|
tableView.getColumns().add(column);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 填充示例数据:ml-citation{ref="2,3" data="citationList"}
|
||||||
|
data.add(new DynamicDataModel(Map.of(
|
||||||
|
"姓名", "张三",
|
||||||
|
"年龄", "28",
|
||||||
|
"城市", "北京"
|
||||||
|
)));
|
||||||
|
tableView.setItems(data);
|
||||||
|
this.getChildren().addAll(tableView);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,21 @@
|
||||||
package com.zhangmeng.online.exam.ui.layouts;
|
package com.zhangmeng.online.exam.ui.layouts;
|
||||||
|
|
||||||
|
import com.zhangmeng.online.exam.ui.admin.IndexPage;
|
||||||
|
import com.zhangmeng.online.exam.ui.components.DynamicTableComponent;
|
||||||
|
import com.zhangmeng.online.exam.ui.components.ShortAnswerComponent;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Accordion;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.TitledPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -12,12 +25,129 @@ import javafx.scene.layout.VBox;
|
||||||
*/
|
*/
|
||||||
public class SideMenu extends VBox {
|
public class SideMenu extends VBox {
|
||||||
|
|
||||||
|
public static class SideMenuData{
|
||||||
|
private String text;
|
||||||
|
private String url;
|
||||||
|
|
||||||
public SideMenu() {
|
public SideMenuData(String text, String url) {
|
||||||
|
this.text = text;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SideMenuItem{
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
private SideMenuData sideMenuData;
|
||||||
|
|
||||||
|
public SideMenuItem(String text, SideMenuData sideMenuData) {
|
||||||
|
this.text = text;
|
||||||
|
this.sideMenuData = sideMenuData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SideMenuData getSideMenuData() {
|
||||||
|
return sideMenuData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSideMenuData(SideMenuData sideMenuData) {
|
||||||
|
this.sideMenuData = sideMenuData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SideMenu(List<SideMenuItem> menuItems) {
|
||||||
|
|
||||||
this.setSpacing(10);
|
this.setSpacing(10);
|
||||||
this.setPrefWidth(200);
|
this.setPrefWidth(200);
|
||||||
this.setStyle("-fx-background-color: #2c3e50;");
|
// this.setStyle("-fx-background-color: #2c3e50;");
|
||||||
}
|
|
||||||
|
|
||||||
|
Accordion accordion = new Accordion();
|
||||||
|
|
||||||
|
for (SideMenuItem item : menuItems) {
|
||||||
|
|
||||||
|
TitledPane tp = new TitledPane();
|
||||||
|
tp.setText(item.getText());
|
||||||
|
|
||||||
|
HBox hbox = new HBox();
|
||||||
|
hbox.setPadding(javafx.geometry.Insets.EMPTY);
|
||||||
|
|
||||||
|
hbox.setSpacing(10);
|
||||||
|
hbox.setAlignment(javafx.geometry.Pos.CENTER);
|
||||||
|
Label label = new Label(item.getSideMenuData().getText());
|
||||||
|
hbox.getChildren().add(label);
|
||||||
|
tp.setContent(hbox);
|
||||||
|
|
||||||
|
hbox.hoverProperty().addListener(new ChangeListener<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
|
||||||
|
if (newValue){
|
||||||
|
hbox.setStyle("-fx-background-color: #b3f0ee;");
|
||||||
|
}else {
|
||||||
|
hbox.setStyle("-fx-background-color: white;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
hbox.setOnMouseClicked(event -> {
|
||||||
|
System.out.println("hbox.setOnMouseClicked====>" + item.getSideMenuData().getUrl());
|
||||||
|
// Parent parent = hbox.getParent().getParent().getParent().getParent();
|
||||||
|
// System.out.println(parent.getClass().getName());
|
||||||
|
|
||||||
|
Scene scene = hbox.getScene();
|
||||||
|
IndexPage root = (IndexPage)scene.getRoot();
|
||||||
|
|
||||||
|
|
||||||
|
DynamicTableComponent shortAnswerComponent = new DynamicTableComponent();
|
||||||
|
shortAnswerComponent.setPadding(new Insets(15));
|
||||||
|
root.setCenter(shortAnswerComponent);
|
||||||
|
});
|
||||||
|
|
||||||
|
tp.expandedProperty().addListener(new ChangeListener<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
|
||||||
|
System.out.println("tp.expandedProperty().addListener====>" + newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
accordion.getPanes().add(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getChildren().add(accordion);
|
||||||
|
|
||||||
|
accordion.expandedPaneProperty().addListener(new ChangeListener<TitledPane>() {
|
||||||
|
@Override
|
||||||
|
public void changed(ObservableValue<? extends TitledPane> observable, TitledPane oldValue, TitledPane newValue) {
|
||||||
|
if (newValue == null){
|
||||||
|
System.out.println(oldValue.getText()+ "=====>折叠");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
System.out.println(newValue.getText()+ "=====>展开");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue