- 已关闭**。此问题需要超过focused。当前不接受答案。
- 想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。
3小时前关门了。
Improve this question
我试图在Jswing上实现一个GUI员工管理器,其中数据存储在一个文本文件中,我将其视为数据库,并创建了一个GUI界面来与之交互。
打开程序后,我可以使用删除功能,它工作正常,但一旦我点击搜索按钮(表搜索值,只显示我搜索的值),然后当我试图删除一些东西时,它抛出下面的错误。
这是我在搜索时遇到的错误:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 2 >= 2
at java.base/java.util.Vector.elementAt(Vector.java:466)
at java.desktop/javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:660)
at java.desktop/javax.swing.JTable.getValueAt(JTable.java:2763)
at java.desktop/javax.swing.JTable.prepareRenderer(JTable.java:5780)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2210)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2112)
at java.desktop/javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1908)
at java.desktop/javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at java.desktop/javax.swing.JComponent.paintComponent(JComponent.java:842)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1119)
at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5311)
at java.desktop/javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:246)
at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1337)
at java.desktop/javax.swing.JComponent._paintImmediately(JComponent.java:5259)
at java.desktop/javax.swing.JComponent.paintImmediately(JComponent.java:5069)
at
- --------------编辑------------
下面是我的最小可复制代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import javax.swing.JTable;
import java.io.IOException; // Import the IOException class to handle errors
import java.io.File; // Import the File class
import java.io.FileNotFoundException; // Import this class to handle errors
import javax.swing.table.DefaultTableModel;
import java.io.FileWriter;
import javax.swing.event.*;
import javax.swing.table.*;
class UserManager extends JFrame implements ActionListener {
// Initializing class variables
private JTextField firstNameField, lastNameField, salaryField, textField;
private JButton addButton, removeButton, sortButton, button;
private JList<Employee> userList;
private ArrayList<Employee> users;
private JTable j;
private DefaultTableModel model;
private JTextField searchField;
/*****************************************
/*Name: UserManager (constructor)
/*Method Description: Constructor class that runs once upon creation of the object. Creates the frame of the GUI app. Pulls from the database and displays it on the GUI interface.
/*Method Inputs/Outputs: Outputs the GUI frame of the app.
******************************************/
public UserManager() {
setTitle("Employee Manager");
setSize(400, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// Initializing and binding action items
firstNameField = new JTextField(20);
lastNameField = new JTextField(20);
salaryField = new JTextField(20);
searchField = new JTextField(20);
addButton = new JButton("Add");
addButton.addActionListener(this);
removeButton = new JButton("Remove");
removeButton.addActionListener(this);
sortButton = new JButton("Sort Salary");
sortButton.addActionListener(this);
// Pulling data from text file database upon start up
ArrayList<ArrayList<String>> databaseData = ReadFile();
users = new ArrayList<Employee>();
// Adding existing databaseData to users
try {
if (databaseData.size() > 0) {
for (int i = 0; i < databaseData.size(); i++) {
Employee user = new Employee(databaseData.get(i).get(0), databaseData.get(i).get(1), Integer.valueOf(databaseData.get(i).get(2)));
users.add(user);
}
}
}
catch (NumberFormatException nfe) {
nfe.printStackTrace();
JOptionPane.showMessageDialog(this, "Internal System Error", "Error", JOptionPane.ERROR_MESSAGE);
}
// Creating the list of users
userList = new JList<Employee>(users.toArray(new Employee[0]));
// Setting up the JPanels
JPanel firstNamePanel = new JPanel();
firstNamePanel.add(new JLabel("First Name:"));
firstNamePanel.add(firstNameField);
JPanel lastNamePanel = new JPanel();
lastNamePanel.add(new JLabel("Last Name:"));
lastNamePanel.add(lastNameField);
JPanel salaryPanel = new JPanel();
salaryPanel.add(new JLabel("Salary:"));
salaryPanel.add(salaryField);
JPanel buttonPanel = new JPanel();
buttonPanel.add(addButton);
buttonPanel.add(removeButton);
buttonPanel.add(sortButton);
JPanel searchPanel = new JPanel();
// Converting 2D arraylist to normal 2D array for JTable
String[][] data = databaseData.stream().map(u -> u.toArray(new String[0])).toArray(String[][]::new);
// Initializing column names of JTable
String[] columnNames = { "FName", "LName", "Salary" };
// Initialize the JTable and TableModel
model = new DefaultTableModel(data, columnNames);
j = new JTable(model);
j.setBounds(1000, 1000, 900, 900);
// adding it to JScrollPane
JScrollPane table = new JScrollPane(j);
JLabel label = new JLabel("Search: ");
textField = new JTextField(20);
button = new JButton("Go");
searchPanel.add(label);
searchPanel.add(textField);
searchPanel.add(button);
button.addActionListener(this);
// Creating main panel and adding JPanels to it
JPanel mainPanel = new JPanel(new GridLayout(6, 2));
mainPanel.add(firstNamePanel);
mainPanel.add(lastNamePanel);
mainPanel.add(salaryPanel);
mainPanel.add(buttonPanel);
mainPanel.add(searchPanel);
mainPanel.add(table);
add(mainPanel);
}
/*****************************************
/*Method Name: actionPerformed
/*Method Description: Performs functions depending on what action is called. Adds users to the table and db if add button is clicked and removes users from the table and db if remove button is clicked.
/*Method Inputs/Outputs: Refreshes the table and outputs the new array with the updates.
******************************************/
public void actionPerformed(ActionEvent e) {
// "Add" button is clicked
if (e.getSource() == addButton) {
// Initializing and setting variables
String firstName = firstNameField.getText();
String lastName = lastNameField.getText();
int salary = 0;
// Checks to see if salary entered is an integer
try {
salary = Integer.parseInt(salaryField.getText());
}
catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(this, "Please enter a valid salary", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
// Error check to see if full name and age is entered
if (!firstName.equals("") && !lastName.equals("")) {
Employee user = new Employee(firstName, lastName, salary);
// Add the user to the arraylist
users.add(user);
// Creating new array with new information
String[] newEmployeeArr = {firstName, lastName, String.valueOf(salary)};
// Add new user to GUI
model.addRow(newEmployeeArr);
// Update user list
updateList(users);
// Resetting input fields
firstNameField.setText("");
lastNameField.setText("");
salaryField.setText("");
}
else {
JOptionPane.showMessageDialog(this, "Please enter a valid full name", "Error", JOptionPane.ERROR_MESSAGE);
}
}
// "Remove" button is clicked
else if (e.getSource() == removeButton) {
try {
if(j.getSelectedRow() != -1) {
// remove selected row from the model
String value = j.getValueAt(j.getSelectedRow(), 0).toString();
String value1 = j.getValueAt(j.getSelectedRow(), 1).toString();
String value2 = j.getValueAt(j.getSelectedRow(), 2).toString();
System.out.println(j.getSelectedRow() + " " + value + value1 + value2);
// Accounting for if the table was sorted and looking to see where the removed var is in the model
model.removeRow(removeUserFromTable(value, value1));
// finds the index of the user to remove
int selectedIndex = removeUser(value, value1, Integer.valueOf(value2));
// Error checks to see if valid user
if (selectedIndex != -1) {
// Remove the selected employee from the users arraylist
users.remove(selectedIndex);
JOptionPane.showMessageDialog(null, "Selected row deleted successfully");
// Update the list
updateList(users);
// Clear inputs
firstNameField.setText("");
lastNameField.setText("");
salaryField.setText("");
}
}
else {
JOptionPane.showMessageDialog(this, "Employee not selected.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(this, "Select a valid row.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
// "Sort" button is clicked
else if (e.getSource() == sortButton) {
BubbleSort();
}
// "Go" button is clicked to search
else if (e.getSource() == button) {
// Creating a searching tool
TableRowSorter<TableModel> sorter = new TableRowSorter<>(model);
j.setRowSorter(sorter);
String text = textField.getText();
if (text.length() == 0) {
sorter.setRowFilter(null);
} else {
sorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
}
}
}
/*****************************************
/*Method Name: updateList
/*Method Description: Performs the update depending on what operation was made. Updates all lists inside the class and saves the change to the database.
/*Method Inputs/Outputs: The new list with the updated list is inputted and an updated database text file is the output.
******************************************/
private void updateList(ArrayList<Employee> u) {
userList.setListData(u.toArray(new Employee[0]));
// Log update to console
System.out.println("Updating Database");
// Overwriting db.txt file with new information
try {
// Making changes to the existed db.txt file
FileWriter fw = new FileWriter("db.txt", false);
// Loop through each student and write to the text file
for (int i = 0; i < u.size(); i++) {
// Re-writing the database file with the updates list
fw.write(toString(u.get(i).getFirstName(), u.get(i).getLastName(), u.get(i).getSalary()));
}
fw.close();
}
catch (IOException io) {
JOptionPane.showMessageDialog(this, "Internal System Error", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
}
/*****************************************
/*Method Name: removeUser
/*Method Description: Searches for the selected user in the users arraylist and finds the index if the user exists
/*Method Inputs/Outputs: The users arraylist and inputted user information is inputted and then outputs where the user is located in the array.
******************************************/
private int removeUser(String firstName, String lastName, int salary) {
// Loops through users arraylist
for (int i = 0; i < users.size(); i++) {
// If the user exists in the database, remove them
if (users.get(i).getFirstName().equals(firstName) && users.get(i).getLastName().equals(lastName) && users.get(i).getSalary() == salary) {
return i;
}
}
// No user by the name and salary was found
return -1;
}
/*****************************************
/*Method Name: removeUserFromTable
/*Method Description: Searches for the selected user in the table model and finds the index if the user exists
/*Method Inputs/Outputs: The user information is inputted and then outputs where the user is located in the model that controls the GUI table.
******************************************/
private int removeUserFromTable(String firstName, String lastName) {
int ind = 0;
for (int i = 0; i < model.getRowCount(); i++){
if (model.getValueAt(i, 0).toString().equals(firstName) && model.getValueAt(i, 1).toString().equals(lastName)) {
ind = i;
break;
}
}
return ind;
}
/*****************************************
/*Method Name: toString
/*Method Description: Converts three variables into one long string varaible
/*Method Inputs/Outputs: The user information is inputted and the string that contains all three variables is outputted.
******************************************/
public String toString(String firstName, String lastName, int salary) {
return firstName + ", " + lastName + ", " + salary + "\n";
}
/*****************************************
/*Method Name: BubbleSort
/*Method Description: Performs bubble sort on the employees by salary and then updates the jtable
/*Method Inputs/Outputs: No inputs or outputs, the JTable is updated
******************************************/
public void BubbleSort() {
try {
// Array to hold a copy of the users list
ArrayList<Employee> tempUsers = new ArrayList<Employee>();
// Adding all the initial users to the new array to perform bubble sort
for (int i =0; i < users.size(); i++) {
tempUsers.add(users.get(i));
}
// Performing bubble sort
for (int i = 0; i < users.size() - 1; i++) {
// Looping through indexes
for (int j = 0; j < users.size() - 1; j++) {
// Comapare the salaries of each indiviual and see if the previous is bigger than the next
if (users.get(j).getSalary() > users.get(j+1).getSalary()) {
// Initializing a temp employee to hold value before switching
Employee temp = users.get(j);
// Swap the employees
users.set(j, users.get(j+1));
users.set(j+1,temp);
}
}
}
int[] selection = j.getSelectedRows();
System.out.println(Arrays.toString(j.getSelectedRows()));
for (int i = 0; i < selection.length; i++) {
selection[i] = j.convertRowIndexToModel(selection[i]);
System.out.println(selection[i]);
}
// Setting the jtable model to the sorted model
j.setModel(model);
}
catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(this, "Not Enough Users", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
}
/*****************************************
/*Method Name: ReadFile
/*Method Description: Reads the db textfile and stores the values in a 2d arraylist for manipulation.
/*Method Inputs/Outputs: The 2d arraylist with all the db information is outputted
******************************************/
public static ArrayList<ArrayList<String>> ReadFile() {
try {
// Choose db.txt file to look at
File myObj = new File("db.txt");
// Create scanner object
Scanner myReader = new Scanner(myObj);
// Create 2d list array to hold all the single list arrays of single information
ArrayList<ArrayList<String>> combinedArr = new ArrayList<ArrayList<String>>();
// While the file reader is still reading lines in the text
while (myReader.hasNextLine()) {
// Read strings of text in txt file
String data = myReader.nextLine();
// Get user information into an array
ArrayList<String> temp = GetInfo(data);
// Add the person and their salary to the combined array that holds everyones
combinedArr.add(temp);
}
// Close file once there are no more lines to read
myReader.close();
return combinedArr;
}
catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
// Return invalid list string with nothing if error
ArrayList<ArrayList<String>> Invalid = new ArrayList<ArrayList<String>>();
return Invalid;
}
/*****************************************
/*Method Name: GetInfo
/*Method Description: Takes in a string of data and parses the three variables in it which are separated by commas
/*Method Inputs/Outputs: The data string that needs to be parsed is inputted and arraylist containuing the data from the string is outputted.
******************************************/
public static ArrayList<String> GetInfo(String data) {
String first = "";
String last = "";
String sal = "";
// System.out.println(data[0])
for (int i = 0; i < data.length(); i++) {
if (data.charAt(i) == ',') {
// Start from 2 indexes after the first occurance of the comma
for (int j = i+2; j < data.length(); j++) {
if (data.charAt(j) == ',') {
// Start from 2 indexes after the occurance of the comma
for (int n = j+2; n < data.length(); n++) {
sal += data.charAt(n);
}
break;
}
last += data.charAt(j);
}
break;
}
first += data.charAt(i);
}
// Initializing package array to send all values
ArrayList<String> arr = new ArrayList<String>();
arr.add(first);
arr.add(last);
arr.add(sal);
return arr;
}
/*****************************************
/*Method Name: main
/*Method Description: Runs the GUI frame
/*Method Inputs/Outputs: Ouputs the GUI
******************************************/
public static void main(String[] args) {
UserManager frame = new UserManager();
frame.setVisible(true);
}
}
class Employee {
// Initalizing variables
private String firstName;
private String lastName;
private int salary;
public Employee(String firstName, String lastName, int salary) {
this.firstName = firstName;
this.lastName = lastName;
this.salary = salary;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getSalary() {
return salary;
}
}
1条答案
按热度按时间pbwdgjma1#
不要试图将数据和模型视为两个独立的东西,您应该将模型 Package 在数据周围,并允许管理它,例如...
这是定制
TableModel
的一个非常基本的概念,它接受Employee
s的List
,提供TableModel
的核心实现,但也提供了一些帮助方法,如add
和delete
,它们将触发适当的事件以允许JTable
更新自己。你可以很容易地用一个“数据库管理器”来支持它,这样排序/删除/添加/更新操作都可以委托给它,这些更新也可以对值的“数据库”进行,但是我打算让你自己去弄清楚。
现在,我将您的
BubbleSort
分离成它自己的、自包含的和可重用的类...唯一的限制是您需要传入一个
Comparator
,它用于比较两个值,以确定它们是否应该交换。“但是为什么要这样做呢?”我听到您问,因为它是自包含的和可重用的。所以,你想按工资排序吗?你想按升序排序吗...
还是降序
令人惊讶的是,你现在可以同时做这两件事,不需要太多的努力。但是等等,如果你想按名字排序呢?!
还是姓!
看,可重复使用。
你甚至可以把名字和薪水结合起来,当然,可行的,只要写一个新的
Comparator
。想排序其他类型的值,当然,只要你提供一个兼容的Comparator
,没有问题。可运行示例
我没有为您的“数据库”而烦恼,因为它真的不是问题的一部分,相反,我集中精力让表模型和排序一起工作(以及删除,因为您知道为什么不这样做)。