From 3a6c6d1f1deff92b27be7aaea41c62662a986f12 Mon Sep 17 00:00:00 2001 From: qmstyle Date: Fri, 21 Mar 2025 17:37:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=89=E9=92=AE=E4=B8=8E=E8=AF=95=E9=A2=98?= =?UTF-8?q?=E7=BB=91=E5=AE=9A,=E5=8A=A8=E6=80=81=E7=94=9F=E6=95=88=202025?= =?UTF-8?q?=E5=B9=B43=E6=9C=8821=E6=97=A517:37:36?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/components/ExamButtonComponent.java | 31 ++++++++++++-- .../exam/ui/components/ExamComponent.java | 39 ++++++++++++----- .../ui/components/FillBlankComponent.java | 10 +++++ .../ui/components/MultiChoiceComponent.java | 5 +++ .../ui/components/ShortAnswerComponent.java | 39 +++++++++++++++++ .../ui/components/SingleChoiceComponent.java | 42 ++++++++++++++++++- .../ui/components/TrueFalseComponent.java | 15 +++++++ src/main/resources/css/button.css | 20 +++++++++ 8 files changed, 186 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/css/button.css diff --git a/src/main/java/com/zhangmeng/online/exam/ui/components/ExamButtonComponent.java b/src/main/java/com/zhangmeng/online/exam/ui/components/ExamButtonComponent.java index 964b675..896c987 100644 --- a/src/main/java/com/zhangmeng/online/exam/ui/components/ExamButtonComponent.java +++ b/src/main/java/com/zhangmeng/online/exam/ui/components/ExamButtonComponent.java @@ -3,6 +3,7 @@ package com.zhangmeng.online.exam.ui.components; import javafx.beans.property.SimpleIntegerProperty; import javafx.geometry.Insets; import javafx.geometry.Pos; +import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.layout.FlowPane; @@ -11,6 +12,7 @@ import java.util.Map; /** * 考试按钮组件 + * * @author zm * @date 2025/3/21 13:59 * @version: 1.0 @@ -23,7 +25,10 @@ public class ExamButtonComponent extends FlowPane { private final Map buttonMap = new HashMap<>(); - public ExamButtonComponent(int count,ExamComponent examComponent) { + + public ExamButtonComponent(int count, ExamComponent examComponent) { + + this.getStylesheets().add(getClass().getResource("/css/button.css").toExternalForm()); this.examComponent = examComponent; this.countButton.set(count); this.setHgap(10); @@ -33,15 +38,33 @@ public class ExamButtonComponent extends FlowPane { Button button = new Button(String.valueOf(i)); button.setPrefWidth(45); button.setOnAction(event -> { - //滚动到指定题目 int currentIndex = buttonMap.get(button); examComponent.scrollToIndex(currentIndex); - }); - buttonMap.put(button,i); + buttonMap.put(button, i); + Node node = examComponent.getNode(i); + + if (node instanceof SingleChoiceComponent singleChoiceComponent) { + singleChoiceComponent.setIndexButton(button); + } + if (node instanceof MultiChoiceComponent multiChoiceComponent) { + multiChoiceComponent.setIndexButton(button); + } + if (node instanceof TrueFalseComponent judgementComponent) { + judgementComponent.setIndexButton(button); + } + if (node instanceof FillBlankComponent fillBlankComponent) { + fillBlankComponent.setIndexButton(button); + } + if (node instanceof ShortAnswerComponent shortAnswerComponent) { + shortAnswerComponent.setIndexButton(button); + } + this.getChildren().add(button); } + + } diff --git a/src/main/java/com/zhangmeng/online/exam/ui/components/ExamComponent.java b/src/main/java/com/zhangmeng/online/exam/ui/components/ExamComponent.java index 1627122..ce0e8ec 100644 --- a/src/main/java/com/zhangmeng/online/exam/ui/components/ExamComponent.java +++ b/src/main/java/com/zhangmeng/online/exam/ui/components/ExamComponent.java @@ -54,6 +54,7 @@ public class ExamComponent extends ScrollPane { private final ObservableList shortAnswerComponents = FXCollections.observableArrayList(); private final SimpleIntegerProperty totalCount = new SimpleIntegerProperty(0); + private final SimpleIntegerProperty totalIndex = new SimpleIntegerProperty(1); private VBox vBox; @@ -72,22 +73,35 @@ public class ExamComponent extends ScrollPane { int total = jsonObject.getIntValue("total"); int index = 1; + List singleChoice_list = new ArrayList<>(); + List multiChoice_list = new ArrayList<>(); + List judgment_list = new ArrayList<>(); + List numerical_list = new ArrayList<>(); + List fillInBlank_list = new ArrayList<>(); + List shortAnswer_list = new ArrayList<>(); for (Object datum : data) { JSONObject question = (JSONObject) datum; String type = question.getString("type"); switch (type) { - case "单选题" -> singleChoice(question); - case "多选题" -> multiChoice(question); - case "判断题" -> judgment(question); - case "计算题" -> numerical(question); - case "填空题" -> fillInBlank(question); - case "简答题" -> shortAnswer(question); + case "单选题" -> singleChoice_list.add(question); + case "多选题" -> multiChoice_list.add(question); + case "判断题" -> judgment_list.add(question); + case "计算题" -> numerical_list.add(question); + case "填空题" -> fillInBlank_list.add(question); + case "简答题" -> shortAnswer_list.add(question); default -> throw new IllegalStateException("Unexpected value: " + type); } } + singleChoice_list.forEach(this::singleChoice); + multiChoice_list.forEach(this::multiChoice); + judgment_list.forEach(this::judgment); + numerical_list.forEach(this::numerical); + fillInBlank_list.forEach(this::fillInBlank); + shortAnswer_list.forEach(this::shortAnswer); + int count = singleChoiceComponents.size() + multiChoiceComponents.size() + judgmentComponents.size() + numericalComponents.size() + fillInBlankComponents.size() + shortAnswerComponents.size(); totalCount.set(count); @@ -96,7 +110,6 @@ public class ExamComponent extends ScrollPane { // label.setFont(new Font("黑体", 18)); // this.vBox.getChildren().add(label); - this.vBox.getChildren().addAll(singleChoiceComponents); this.vBox.getChildren().addAll(multiChoiceComponents); this.vBox.getChildren().addAll(judgmentComponents); @@ -132,6 +145,7 @@ public class ExamComponent extends ScrollPane { //简答题 private void shortAnswer(JSONObject question) { + SHORT_ANSWER_COUNT.set(totalIndex.get()); String list = question.getString("options"); List maps = JSONArray.parseArray(list, Map.class); List> optionList = new ArrayList<>(); @@ -152,6 +166,7 @@ public class ExamComponent extends ScrollPane { shortAnswerComponent.setContext(context); shortAnswerComponents.add(shortAnswerComponent); SHORT_ANSWER_COUNT.set(SHORT_ANSWER_COUNT.get() + 1); + totalIndex.set(totalIndex.get() + 1); } //填空题 @@ -164,7 +179,7 @@ public class ExamComponent extends ScrollPane { //判断题 private void judgment(JSONObject question) { - + JUDGMENT_COUNT.set(totalIndex.get()); String list = question.getString("options"); List maps = JSONArray.parseArray(list, Map.class); String correctAnswer = null; @@ -186,6 +201,7 @@ public class ExamComponent extends ScrollPane { trueFalseComponent.setContext(context); judgmentComponents.add(trueFalseComponent); JUDGMENT_COUNT.set(JUDGMENT_COUNT.get() + 1); + totalIndex.set(totalIndex.get() + 1); } @@ -210,7 +226,7 @@ public class ExamComponent extends ScrollPane { option.put("content", map.get("content").toString()); optionList.add(option); } - SingleChoiceComponent singleChoiceComponent = new SingleChoiceComponent(SINGLE_CHOICE_COUNT.get() + "." + question.getString("name"), optionList); + SingleChoiceComponent singleChoiceComponent = new SingleChoiceComponent(SINGLE_CHOICE_COUNT.get() + "." + question.getString("name"), optionList,SINGLE_CHOICE_COUNT.get()); singleChoiceComponent.setCorrectAnswer(correctAnswer); Map context = new HashMap<>(); context.put("question_id", question.getString("id")); @@ -218,6 +234,7 @@ public class ExamComponent extends ScrollPane { singleChoiceComponent.setContext(context); singleChoiceComponents.add(singleChoiceComponent); SINGLE_CHOICE_COUNT.set(SINGLE_CHOICE_COUNT.get() + 1); + totalIndex.set(totalIndex.get() + 1); } public int getTotalCount() { @@ -232,5 +249,7 @@ public class ExamComponent extends ScrollPane { this.vBox = vBox; } - + public Node getNode(int index){ + return this.vBox.getChildren().get(index-1); + } } diff --git a/src/main/java/com/zhangmeng/online/exam/ui/components/FillBlankComponent.java b/src/main/java/com/zhangmeng/online/exam/ui/components/FillBlankComponent.java index 3ca8fbe..1223584 100644 --- a/src/main/java/com/zhangmeng/online/exam/ui/components/FillBlankComponent.java +++ b/src/main/java/com/zhangmeng/online/exam/ui/components/FillBlankComponent.java @@ -18,6 +18,8 @@ import java.util.List; */ public class FillBlankComponent extends VBox { + private Button indexButton; + // 题目数据模型 private static class Question { String content; // 如 "Java中多线程可通过实现__1__接口或继承__2__类" @@ -92,4 +94,12 @@ public class FillBlankComponent extends VBox { this.setPadding(new Insets(20)); this.getChildren().addAll(questionBox, submitBtn, resultLabel); } + + public Button getIndexButton() { + return indexButton; + } + + public void setIndexButton(Button indexButton) { + this.indexButton = indexButton; + } } diff --git a/src/main/java/com/zhangmeng/online/exam/ui/components/MultiChoiceComponent.java b/src/main/java/com/zhangmeng/online/exam/ui/components/MultiChoiceComponent.java index 842b931..e1313f3 100644 --- a/src/main/java/com/zhangmeng/online/exam/ui/components/MultiChoiceComponent.java +++ b/src/main/java/com/zhangmeng/online/exam/ui/components/MultiChoiceComponent.java @@ -86,4 +86,9 @@ public class MultiChoiceComponent extends VBox { cb.setStyle("-fx-font-size: 14px; -fx-text-fill: #444;"); return cb; } + + public void setIndexButton(Button button) { + + + } } diff --git a/src/main/java/com/zhangmeng/online/exam/ui/components/ShortAnswerComponent.java b/src/main/java/com/zhangmeng/online/exam/ui/components/ShortAnswerComponent.java index 3efa852..3909a65 100644 --- a/src/main/java/com/zhangmeng/online/exam/ui/components/ShortAnswerComponent.java +++ b/src/main/java/com/zhangmeng/online/exam/ui/components/ShortAnswerComponent.java @@ -7,8 +7,12 @@ import javafx.geometry.Insets; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TextArea; +import javafx.scene.layout.Background; +import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; import java.util.*; @@ -20,6 +24,8 @@ import java.util.*; */ public class ShortAnswerComponent extends VBox { + private Button indexButton; + private Map context = new HashMap<>(); public Map getContext() { @@ -44,6 +50,20 @@ public class ShortAnswerComponent extends VBox { private List keywords = new ArrayList<>(); // 参考答案关键词(如 ["封装","继承","多态"]) + private static final String DEFAULT_STYLE_CLASS = "button"; + + public void setBackground() { + indexButton.getStyleClass().remove("custom-button-cancel"); + indexButton.getStyleClass().add("custom-button-click"); + } + + //取消 + public void cancelBackground() { + indexButton.getStyleClass().remove("custom-button-click"); + indexButton.getStyleClass().add("custom-button-cancel"); + } + + public ShortAnswerComponent(String question, List> options) { this.setStyle("-fx-background-color: white; -fx-border-color: #eadcdc;" + @@ -68,6 +88,17 @@ public class ShortAnswerComponent extends VBox { answerArea.setWrapText(true); // 自动换行‌:ml-citation{ref="1" data="citationList"} this.getChildren().add(answerArea); + answerArea.textProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, String oldValue, String newValue) { + if (newValue.length() > 0) { + setBackground(); + }else { + cancelBackground(); + } + } + }); + // 功能组件 Button submitBtn = new Button("提交答案"); @@ -117,4 +148,12 @@ public class ShortAnswerComponent extends VBox { this.hBox.getChildren().add(1,resultLabel); } + + public Button getIndexButton() { + return indexButton; + } + + public void setIndexButton(Button indexButton) { + this.indexButton = indexButton; + } } diff --git a/src/main/java/com/zhangmeng/online/exam/ui/components/SingleChoiceComponent.java b/src/main/java/com/zhangmeng/online/exam/ui/components/SingleChoiceComponent.java index e2ca2ac..c9cbe4c 100644 --- a/src/main/java/com/zhangmeng/online/exam/ui/components/SingleChoiceComponent.java +++ b/src/main/java/com/zhangmeng/online/exam/ui/components/SingleChoiceComponent.java @@ -27,6 +27,12 @@ import java.util.Map; */ public class SingleChoiceComponent extends VBox { + private String TYPE = "single_choice"; + + private Button indexButton; + + private int index;//该组件索引 + private Map context = new HashMap<>(); public Map getContext() { @@ -47,8 +53,12 @@ public class SingleChoiceComponent extends VBox { private Label questionLabel; - public SingleChoiceComponent(String question, List> options) { + public void setBackground() { + this.indexButton.setStyle("-fx-background-color: #4698ed;"); + } + public SingleChoiceComponent(String question, List> options,int index) { + this.index = index; this.setStyle("-fx-background-color: white; -fx-border-color: #eadcdc;" + "-fx-border-radius: 10px; -fx-border-width: 1px; -fx-border-style: solid;-fx-background-radius: 10px;"); @@ -120,6 +130,11 @@ public class SingleChoiceComponent extends VBox { result_answer.set(option.get("id").toString()); //提交数据 ApiUtils.submitAnswer(context); + + //改变颜色 + setBackground(); + + resultLabel.setText("你的选择:"+ option.get("option")); resultLabel.setStyle("-fx-text-fill: #2ecc71;"); @@ -151,4 +166,29 @@ public class SingleChoiceComponent extends VBox { public void setCorrectAnswer(String correctAnswer) { this.correctAnswer = correctAnswer; } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + + public String getTYPE() { + return TYPE; + } + + public void setTYPE(String TYPE) { + this.TYPE = TYPE; + } + + public Button getIndexButton() { + return indexButton; + } + + public void setIndexButton(Button indexButton) { + this.indexButton = indexButton; + } } diff --git a/src/main/java/com/zhangmeng/online/exam/ui/components/TrueFalseComponent.java b/src/main/java/com/zhangmeng/online/exam/ui/components/TrueFalseComponent.java index 6c390f2..fffc6ea 100644 --- a/src/main/java/com/zhangmeng/online/exam/ui/components/TrueFalseComponent.java +++ b/src/main/java/com/zhangmeng/online/exam/ui/components/TrueFalseComponent.java @@ -23,6 +23,8 @@ import java.util.Map; */ public class TrueFalseComponent extends VBox { + private Button indexButton; + private static final String TRUE_TEXT = "✔ 正确"; private static final String FALSE_TEXT = "✘ 错误"; @@ -47,6 +49,10 @@ public class TrueFalseComponent extends VBox { private Label questionLabel; + public void setBackground() { + this.indexButton.setStyle("-fx-background-color: #4698ed;"); + } + public TrueFalseComponent(String question, List> options) { this.setStyle("-fx-background-color: white; -fx-border-color: #eadcdc;" + "-fx-border-radius: 10px; -fx-border-width: 1px; -fx-border-style: solid;-fx-background-radius: 10px;"); @@ -112,6 +118,7 @@ public class TrueFalseComponent extends VBox { resultLabel.setText("你的选择:"+ FALSE_TEXT); } resultLabel.setStyle("-fx-text-fill: #2ecc71;"); + setBackground(); } else { resultLabel.setText("⚠ 请先选择答案"); } @@ -131,4 +138,12 @@ public class TrueFalseComponent extends VBox { rb.setUserData(option); return rb; } + + public Button getIndexButton() { + return indexButton; + } + + public void setIndexButton(Button indexButton) { + this.indexButton = indexButton; + } } diff --git a/src/main/resources/css/button.css b/src/main/resources/css/button.css new file mode 100644 index 0000000..04ba132 --- /dev/null +++ b/src/main/resources/css/button.css @@ -0,0 +1,20 @@ +.custom-button-click { + -fx-background-color: #4698ed; +} + +.custom-button-cancel { + -fx-background-color: #dadada43; /* 默认背景色 */ + -fx-border-color: #7e7676; + -fx-border-width: 0.5px; /* 默认边框颜色 */ + -fx-border-radius: 3px; /* 默认边框圆角 */ +} + +.custom-button-cancel:focused { + -fx-background-color: derive(#e6e6e6, 20%); /* 焦点时略微变亮 */ + -fx-border-color: #0096C9; + -fx-border-width: 1.5px; /* 默认边框颜色 */ +} + +.custom-button-cancel:hover { + -fx-background-color: derive(#dadada, 20%); /* 鼠标悬停时略微变亮 */ +}