功能介绍:输入问题后随机抽取人来回答。
可以加载json文件导入问题,也可以手动单个添加问题。运行完后历史数据会自动保存在项目的根目录下且会对其命名为data.json。
整个项目的目录构造:
运行流程:
首先创建maven项目
然后导入相关依赖——在pom.xml添加一下代码:
<dependencies>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
创建运行代码 RandomPickerApp.java :
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.List;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class RandomPickerApp extends JFrame {
private JTextField questionsEntry;
private JTextArea inputQuestionsText;
private JTextArea resultsText;
private JTextArea remainingNamesText;
private JTextArea allNamesText;
private JSpinner selectCountSpinbox;
private JButton addQuestionButton;
private JButton loadQuestionsButton;
private JButton resetInputQuestionsButton;
private JButton submitButton;
private JButton resetButton;
private List<String> names = Arrays.asList("张三", "李四", "王五", "赵六", "田七");
private Set<String> usedNames = new HashSet<>();
private List<String> results = new ArrayList<>();
private List<String> questions = new ArrayList<>();
private Set<String> answeredQuestions = new HashSet<>();
private String dataFilePath = "data.json";
public RandomPickerApp() {
setTitle("随机抽取人名");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
createComponents();
layoutComponents();
addListeners();
setVisible(true);
}
private void createComponents() {
questionsEntry = new JTextField(30);
inputQuestionsText = new JTextArea(10, 30);
inputQuestionsText.setEditable(false);
JScrollPane inputQuestionsScrollPane = new JScrollPane(inputQuestionsText);
resultsText = new JTextArea(15, 30);
resultsText.setEditable(false);
JScrollPane resultsScrollPane = new JScrollPane(resultsText);
remainingNamesText = new JTextArea(3, 70);
remainingNamesText.setEditable(false);
JScrollPane remainingNamesScrollPane = new JScrollPane(remainingNamesText);
allNamesText = new JTextArea(2, 70);
allNamesText.setEditable(false);
JScrollPane allNamesScrollPane = new JScrollPane(allNamesText);
selectCountSpinbox = new JSpinner(new SpinnerNumberModel(1, 1, names.size(), 1));
addQuestionButton = new JButton("添加问题");
loadQuestionsButton = new JButton("加载问题");
resetInputQuestionsButton = new JButton("重置已输入问题");
submitButton = new JButton("开始抽取");
resetButton = new JButton("重置");
updateAllNamesDisplay();
}
private void layoutComponents() {
GridBagLayout gridBagLayout = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
setLayout(gridBagLayout);
// Questions Entry and Buttons Panel
JPanel questionPanel = new JPanel();
questionPanel.setLayout(new BoxLayout(questionPanel, BoxLayout.Y_AXIS));
questionPanel.add(new JLabel("请输入问题:"));
questionPanel.add(questionsEntry);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(addQuestionButton);
buttonPanel.add(loadQuestionsButton);
buttonPanel.add(resetInputQuestionsButton);
questionPanel.add(buttonPanel);
questionPanel.add(new JLabel("已输入的问题:"));
questionPanel.add(new JScrollPane(inputQuestionsText));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 0.3;
gbc.insets = new Insets(10, 10, 10, 10);
add(questionPanel, gbc);
// Results Panel
JPanel resultsPanel = new JPanel();
resultsPanel.setLayout(new BorderLayout());
resultsPanel.add(new JLabel("抽取结果:"), BorderLayout.NORTH);
resultsPanel.add(new JScrollPane(resultsText), BorderLayout.CENTER);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 0.4;
add(resultsPanel, gbc);
// Select Count Spinbox and Submit Button Panel
JPanel spinboxAndSubmitPanel = new JPanel();
spinboxAndSubmitPanel.setLayout(new FlowLayout());
spinboxAndSubmitPanel.add(new JLabel("选择要抽取的人数:"));
spinboxAndSubmitPanel.add(selectCountSpinbox);
spinboxAndSubmitPanel.add(submitButton);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
add(spinboxAndSubmitPanel, gbc);
// Remaining Names and All Names Panel
JPanel remainingAndAllNamesPanel = new JPanel();
remainingAndAllNamesPanel.setLayout(new GridLayout(2, 1));
JPanel remainingNamesPanel = new JPanel();
remainingNamesPanel.setLayout(new BorderLayout());
remainingNamesPanel.add(new JLabel("剩余未抽到的人名:"), BorderLayout.NORTH);
remainingNamesPanel.add(new JScrollPane(remainingNamesText), BorderLayout.CENTER);
remainingAndAllNamesPanel.add(remainingNamesPanel);
JPanel allNamesPanel = new JPanel();
allNamesPanel.setLayout(new BorderLayout());
allNamesPanel.add(new JLabel("所有人名:"), BorderLayout.NORTH);
allNamesPanel.add(new JScrollPane(allNamesText), BorderLayout.CENTER);
remainingAndAllNamesPanel.add(allNamesPanel);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 0.2;
add(remainingAndAllNamesPanel, gbc);
// Reset Button Panel
JPanel resetButtonPanel = new JPanel();
resetButtonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
resetButtonPanel.add(resetButton);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
add(resetButtonPanel, gbc);
}
private void addListeners() {
addQuestionButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addQuestion();
}
});
loadQuestionsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loadQuestions();
}
});
resetInputQuestionsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resetInputQuestions();
}
});
submitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
pickRandomNames();
}
});
resetButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
reset();
}
});
}
private void addQuestion() {
String question = questionsEntry.getText().trim();
if (question.isEmpty()) {
JOptionPane.showMessageDialog(this, "请输入一个问题", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (questions.contains(question)) {
JOptionPane.showMessageDialog(this, "该问题已存在,请输入不同的问题", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
questions.add(question);
updateInputQuestionsDisplay();
questionsEntry.setText("");
JOptionPane.showMessageDialog(this, "已添加问题: " + question, "成功", JOptionPane.INFORMATION_MESSAGE);
}
private void loadQuestions() {
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showOpenDialog(this);
if (result != JFileChooser.APPROVE_OPTION) {
return;
}
File selectedFile = fileChooser.getSelectedFile();
JSONParser parser = new JSONParser();
try (FileReader reader = new FileReader(selectedFile.getAbsolutePath())) {
JSONObject jsonObject = (JSONObject) parser.parse(reader);
JSONArray loadedQuestionsArray = (JSONArray) jsonObject.get("questions");
for (Object obj : loadedQuestionsArray) {
String question = (String) obj;
if (!questions.contains(question)) {
questions.add(question);
}
}
updateInputQuestionsDisplay();
JOptionPane.showMessageDialog(this, "已加载 " + loadedQuestionsArray.size() + " 个问题", "成功", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException | ParseException e) {
JOptionPane.showMessageDialog(this, "加载问题失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
private void resetInputQuestions() {
questions.clear();
updateInputQuestionsDisplay();
JOptionPane.showMessageDialog(this, "已清空已输入的问题", "成功", JOptionPane.INFORMATION_MESSAGE);
}
private void updateInputQuestionsDisplay() {
inputQuestionsText.setText(String.join("\n", questions));
}
private void pickRandomNames() {
int numToPick = (Integer) selectCountSpinbox.getValue();
if (questions.isEmpty()) {
JOptionPane.showMessageDialog(this, "请先添加一些问题", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
List<String> availableQuestions = new ArrayList<>(questions);
availableQuestions.removeAll(answeredQuestions);
if (availableQuestions.isEmpty()) {
JOptionPane.showMessageDialog(this, "所有问题已被回答,请重置或添加新的问题", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (usedNames.size() >= names.size()) {
JOptionPane.showMessageDialog(this, "所有人名已被使用,请重置", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (numToPick > availableQuestions.size()) {
JOptionPane.showMessageDialog(this, "选择的人数超过可用问题的数量", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (numToPick > names.size() - usedNames.size()) {
JOptionPane.showMessageDialog(this, "选择的人数超过剩余可用的人数", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
Collections.shuffle(availableQuestions);
List<String> selectedQuestions = availableQuestions.subList(0, numToPick);
List<String> availableNames = new ArrayList<>(names);
availableNames.removeAll(usedNames);
Collections.shuffle(availableNames);
List<String> selectedNames = availableNames.subList(0, numToPick);
for (int i = 0; i < numToPick; i++) {
String question = selectedQuestions.get(i);
String name = selectedNames.get(i);
String result = name + " 来回答 " + question;
results.add(result);
usedNames.add(name);
answeredQuestions.add(question);
}
updateResultsDisplay();
updateRemainingNamesDisplay();
saveData();
}
private void updateResultsDisplay() {
resultsText.setText(String.join("\n", results));
}
private void updateRemainingNamesDisplay() {
List<String> remainingNames = new ArrayList<>(names);
remainingNames.removeAll(usedNames);
remainingNamesText.setText(String.join(", ", remainingNames));
}
private void updateAllNamesDisplay() {
allNamesText.setText( String.join(" , ", names));
}
private void saveData() {
JSONObject data = new JSONObject();
data.put("questions", listToJsonArray(questions));
data.put("answered_questions", listToJsonArray(new ArrayList<>(answeredQuestions)));
data.put("used_names", listToJsonArray(new ArrayList<>(usedNames)));
data.put("results", listToJsonArray(results));
try {
System.out.println("Saving data to: " + new File(dataFilePath).getAbsolutePath()); // Debugging line
// Convert JSONObject to pretty-printed string using Gson
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String prettyJsonString = gson.toJson(data);
FileWriter writer = new FileWriter(dataFilePath);
writer.write(prettyJsonString);
writer.close();
JOptionPane.showMessageDialog(this, "数据已保存到 " + dataFilePath, "成功", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "保存数据失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
}
}
private JSONArray listToJsonArray(List<String> list) {
JSONArray jsonArray = new JSONArray();
for (String item : list) {
jsonArray.add(item);
}
return jsonArray;
}
private void reset() {
usedNames.clear();
results.clear();
questions.clear();
answeredQuestions.clear();
updateResultsDisplay();
updateRemainingNamesDisplay();
updateInputQuestionsDisplay();
updateAllNamesDisplay();
questionsEntry.setText("");
((SpinnerNumberModel) selectCountSpinbox.getModel()).setValue(1);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new RandomPickerApp();
}
});
}
}
人名更改的话——修改以下代码:
private List<String> names = Arrays.asList("张三", "李四", "王五", "赵六", "田七");
最后运行RandomPickerApp.java 即可