无法动态刷新 JTable



首先我是Java新手。我做了一个4面板的Gui (MainProgram)。

形象在centerPanel中是JTable,显示来自数据库的数据。

topPanel我把按钮打开新的类/窗口-(添加客户)与一些输入字段。点击保存按钮后,数据保存到数据库中,dispose()。数据已正确保存到数据库中。问题是如何刷新表在MainProgram保存后?提前谢谢。

有一些代码:

MainProgram.java

public class MainProgram extends JFrame {
Connection connection = MysqlConnect.dbConnector();
private static final long serialVersionUID = 1L;
public JPanel contentPane;
public String selectedRowIndex;

Object[][] data;
String columns[];
public JPanel centerPanel;
public JScrollPane  pane;
private JTable table;

public MainProgram() throws IOException {
setTitle("Main Program");
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
setBounds(100, 100, 1086, 501);
setLocationRelativeTo(null);
// setExtendedState(getExtendedState() | JFrame.MAXIMIZED_BOTH);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
addWindowListener((WindowListener) new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
String ObjButtons[] = { "Yes", "No" };
int PromptResult = JOptionPane.showOptionDialog(null, "Are you sure you want to exit?", "SkladModule",
JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, ObjButtons, ObjButtons[1]);
if (PromptResult == 0) {
System.exit(0);
}
}
});
// left panel
JPanel leftPanel = new JPanel();
contentPane.add(leftPanel, BorderLayout.WEST);
// center panel
centerPanel = new JPanel(new GridLayout());
centerPanel.setBorder(new TitledBorder(
new EtchedBorder(EtchedBorder.LOWERED, new Color(255, 255, 255), new Color(160, 160, 160)), "INFO",
TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
contentPane.add(centerPanel, BorderLayout.CENTER);
try {
int count = 0;
String query = "SELECT * FROM vehicles";
String queryRow = "select count(*) from vehicles";
Statement stm = connection.createStatement();
ResultSet rows = stm.executeQuery(queryRow);
if (rows.next()) {
count = rows.getInt(1);
rows.close();
}
ResultSet res = stm.executeQuery(query);
// client_id, plate, make, model, year, engine_cc, color, vehicle_owner,
// vehicle_owner_contact, mechanic, in_garage, service_start, service_end,
// service_cost, parts_cost, service_paid, notes
columns = new String[] { "ID", "Plate", "Make", "Model", "Year", "Engine", "Color", "Owner", "Owner Tel.",
"In Garage", "Service Paid", "Notes" };
data = new Object[count][12];
int i = 0;
while (res.next()) {
int id = res.getInt("client_id");
data[i][0] = id + "";
data[i][1] = res.getString("plate");
data[i][2] = res.getString("make");
data[i][3] = res.getString("model");
data[i][4] = res.getString("year");
data[i][5] = res.getString("engine_cc");
data[i][6] = res.getString("color");
data[i][7] = res.getString("vehicle_owner");
data[i][8] = res.getString("vehicle_owner_contact");
data[i][9] = res.getString("in_garage");
data[i][10] = res.getString("service_paid");
data[i][11] = res.getString("notes");
i++;
}
table = new JTable();
TableModel model = new DefaultTableModel(data, columns);
table.setModel(model);
// JTable table = new JTable(data, columns);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
final TableColumnModel columnModel = table.getColumnModel();
for (int column = 0; column < table.getColumnCount(); column++) {
int width = 15; // Min width
for (int row = 0; row < table.getRowCount(); row++) {
TableCellRenderer renderer = table.getCellRenderer(row, column);
Component comp = table.prepareRenderer(renderer, row, column);
width = Math.max(comp.getPreferredSize().width + 10, width);
}
width = Math.max(width, table.getColumnModel().getColumn(column).getPreferredWidth());
if (width > 300)
width = 300;
columnModel.getColumn(column).setPreferredWidth(width);
}
table.setFocusable(false);
table.setRowSelectionAllowed(true);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setDefaultEditor(Object.class, null);
table.setShowGrid(true);
table.setShowVerticalLines(true);
pane = new JScrollPane(table);
centerPanel.add(pane);
table.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
selectedRowIndex = table.getModel().getValueAt(table.getSelectedRow(), 0).toString();
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
});
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (selectedRowIndex != null) {
int rowID = Integer.parseInt(selectedRowIndex);
System.out.println(rowID);
} else {
JOptionPane.showMessageDialog(null, "Please select row!", "No selected vehicle",
JOptionPane.INFORMATION_MESSAGE);
}
}
});
leftPanel.add(btnNewButton);
} catch (SQLException e) {
e.printStackTrace();
}
// bottom panel
// create the status bar panel and shove it down the bottom of the frame
JPanel statusPanel = new JPanel();
statusPanel.setBorder((Border) new BevelBorder(BevelBorder.LOWERED));
contentPane.add(statusPanel, BorderLayout.SOUTH);
statusPanel.setPreferredSize(new Dimension(contentPane.getWidth(), 20));
statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS));
JLabel statusLabel = new JLabel("");
statusLabel.setHorizontalAlignment(SwingConstants.LEFT);
statusPanel.add(statusLabel);
contentPane.setVisible(true);
// add username from login to statusbar
String username = Login.uname;
statusLabel.setText("Logged user: " + username);
JPanel topPanel = new JPanel();
contentPane.add(topPanel, BorderLayout.NORTH);
BufferedImage buttonIcon = ImageIO
.read(new File("C:\Users\User\eclipse-workspace\SkladModule\images\plus.png"));
JButton btnAddCustomer = new JButton(new ImageIcon(buttonIcon));
btnAddCustomer.setText("ADD");
// btnAddCustomer.setBorder(null);
btnAddCustomer.setContentAreaFilled(false);
btnAddCustomer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
AddCustomer addCustomer;
try {
addCustomer = new AddCustomer();
addCustomer.setVisible(true);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
topPanel.add(btnAddCustomer);
JButton btnNewButton_1 = new JButton("New button");
topPanel.add(btnNewButton_1);
}
public void refresh() {
TableModel model =new DefaultTableModel(data, columns);
model.insertRow(res.getRow() - 1, row);
model.addRow(row);
}


}

AddCustomer.java:

public class AddCustomer extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField plateField;
private JTextField makeField;
private JTextField modelField;
private JTextField yearField;
private JTextField engineField;
private JTextField colorField;
private JTextField ownerField;
private JTextField ownerPhoneField;
Connection connection = null;
public AddCustomer() throws IOException {
setResizable(false);
setType(Type.POPUP);
setTitle("ADD CUSTOMER");
setBounds(100, 100, 700, 300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
getContentPane().setLayout(new BorderLayout(0, 0));
addWindowListener((WindowListener) new WindowAdapter() {
@Override
public void windowClosing(WindowEvent we) {
String ObjButtons[] = { "Yes", "No" };
int PromptResult = JOptionPane.showOptionDialog(null, "Are you sure you want to exit?", "SkladModule",
JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, ObjButtons, ObjButtons[1]);
if (PromptResult == 0) {
dispose();
}
}
});
JPanel leftPanel = new JPanel();
leftPanel.setBorder(BorderFactory.createTitledBorder(" CAR INFO "));
getContentPane().add(leftPanel, BorderLayout.WEST);
leftPanel.setLayout(new MigLayout("", "[left][][grow,left]", "[][][][][][][][][]"));
JLabel lblPlate = new JLabel("Plate: *");
leftPanel.add(lblPlate, "cell 0 1,alignx trailing");
plateField = new JTextField();
leftPanel.add(plateField, "cell 2 1,growx");
plateField.setColumns(10);
JLabel lblMake = new JLabel("Make: *");
leftPanel.add(lblMake, "cell 0 2,alignx trailing");
makeField = new JTextField();
leftPanel.add(makeField, "cell 2 2,growx");
makeField.setColumns(10);
JLabel lblModel = new JLabel("Model: *");
leftPanel.add(lblModel, "cell 0 3,alignx trailing");
modelField = new JTextField();
leftPanel.add(modelField, "cell 2 3,growx");
modelField.setColumns(10);
JLabel lblYear = new JLabel("Year: *");
leftPanel.add(lblYear, "cell 0 4,alignx trailing");
yearField = new JTextField();
leftPanel.add(yearField, "cell 2 4,growx");
yearField.setColumns(10);
JLabel lblEngCC = new JLabel("Engine size (cc): *");
leftPanel.add(lblEngCC, "cell 0 5,alignx trailing");
engineField = new JTextField();
leftPanel.add(engineField, "cell 2 5,growx");
engineField.setColumns(10);
JLabel lblColor = new JLabel("Color: *");
leftPanel.add(lblColor, "cell 0 6,alignx trailing");
colorField = new JTextField();
leftPanel.add(colorField, "cell 2 6,growx");
colorField.setColumns(10);
JLabel lblNewLabel = new JLabel("*  Required fields");
leftPanel.add(lblNewLabel, "cell 2 8");
JPanel rightPanel = new JPanel();
rightPanel.setBorder(BorderFactory.createTitledBorder(" CLIENT INFO "));
getContentPane().add(rightPanel, BorderLayout.CENTER);
rightPanel.setLayout(new MigLayout("", "[100px:n,trailing][250px:300px:500,trailing]", "[][][][][grow]"));
JLabel lblOwnerName = new JLabel("Car owner names: *");
rightPanel.add(lblOwnerName, "cell 0 1,alignx trailing");
ownerField = new JTextField();
rightPanel.add(ownerField, "cell 1 1,growx");
ownerField.setColumns(10);
JLabel lblOwnerPhone = new JLabel("Car owner telephone: *");
rightPanel.add(lblOwnerPhone, "cell 0 2,alignx trailing");
ownerPhoneField = new JTextField();
rightPanel.add(ownerPhoneField, "cell 1 2,growx");
ownerPhoneField.setColumns(10);
JLabel lblNotes = new JLabel("Notes: ");
rightPanel.add(lblNotes, "cell 0 3,alignx trailing,aligny top");
JTextArea notesField = new JTextArea(16, 58);
notesField.setWrapStyleWord(true);
notesField.setLineWrap(true);
notesField.setBorder(BorderFactory.createLineBorder(Color.lightGray));
JScrollPane scrollNotes = new JScrollPane(notesField);
scrollNotes.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
rightPanel.add(scrollNotes, "cell 1 3,grow");
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(bottomPanel, BorderLayout.SOUTH);
BufferedImage saveButtonIcon = ImageIO
.read(new File("C:\Users\User\eclipse-workspace\SkladModule\images\accept.png"));
JButton save_btn = new JButton(new ImageIcon(saveButtonIcon));
save_btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
/*
* if (plateField.getText().isBlank() || makeField.getText().isBlank() ||
* modelField.getText().isBlank() || yearField.getText().isBlank() ||
* engineField.getText().isBlank() || colorField.getText().isBlank() ||
* ownerField.getText().isBlank() || ownerPhoneField.getText().isBlank()) {
* 
* JOptionPane.showMessageDialog(null, "* required fields incomplete. Please
* review and resubmit", "Incomplete data", JOptionPane.WARNING_MESSAGE);
* 
* } else {
*/
connection = MysqlConnect.dbConnector();
try {
String query = "INSERT INTO vehicles (plate, make, model, year, engine_cc, color, vehicle_owner, vehicle_owner_contact, notes) VALUES ('"
+ plateField.getText() + "','" + makeField.getText() + "','" + modelField.getText() + "','"
+ yearField.getText() + "','" + engineField.getText() + "','" + colorField.getText() + "','"
+ ownerField.getText() + "','" + ownerPhoneField.getText() + "','" + notesField.getText()
+ "')";
PreparedStatement pst = connection.prepareStatement(query);
pst.executeUpdate(query);
MainProgram main = new MainProgram();
main.refresh();
JOptionPane.showMessageDialog(null, "Data was saved", "SUCCESS", JOptionPane.INFORMATION_MESSAGE);
dispose();

} catch (Exception e1) {
JOptionPane.showMessageDialog(null, "SQLException: " + e1.getMessage(), "ERROR",
JOptionPane.ERROR_MESSAGE);
}
/* } */
}
});
save_btn.setText("SAVE");
save_btn.setBorder(null);
save_btn.setContentAreaFilled(true);
save_btn.setToolTipText("SAVE");
bottomPanel.add(save_btn);
Component horizontalStrut = Box.createHorizontalStrut(25);
bottomPanel.add(horizontalStrut);
BufferedImage cancelButtonIcon = ImageIO
.read(new File("C:\Users\User\eclipse-workspace\SkladModule\images\remove.png"));
JButton cancel_btn = new JButton(new ImageIcon(cancelButtonIcon));
cancel_btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
cancel_btn.setText("CANCEL");
cancel_btn.setBorder(null);
cancel_btn.setContentAreaFilled(false);
cancel_btn.setToolTipText("CANCEL");
cancel_btn.setHorizontalAlignment(SwingConstants.RIGHT);
bottomPanel.add(cancel_btn);
Component horizontalStrut_1 = Box.createHorizontalStrut(20);
bottomPanel.add(horizontalStrut_1);
}
}

有很多方法可以实现这一点,但它们基本上都归结为同一件事,一个模态对话框。有关更多详细信息,请参见如何创建对话框。

你应该避免从像JFrame(和JDialog)这样的顶级容器扩展。您没有向类中添加任何新功能,而是将自己锁定在单个用例中。

下面的示例旨在展示如何通过使用模态对话框请求用户输入。通过同样的"黑色魔法",当你显示一个模态对话框时,代码执行将在对话框可见时停止,并在对话框关闭时继续执行(不要问,我不在乎,它只是工作)。

这意味着你可以呈现一个对话框,然后等待它关闭,然后继续做你需要做的决定。

<标题>

你可以…使用JOptionPane,这是一个简洁方便的API,用于制作对话框。

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class Person {
private long id;
private String firstName;
private String lastName;
public Person(long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@Override
public int hashCode() {
int hash = 7;
hash = 37 * hash + (int) (this.id ^ (this.id >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if (this.id != other.id) {
return false;
}
return true;
}
}
public class PersonPane extends JPanel {
private Person person;
private JTextField firstName;
private JTextField lastName;
public PersonPane(Person person) {
this();
this.person = person;
if (person == null) {
return;
}
firstName.setText(person.getFirstName());
lastName.setText(person.getLastName());
}
public PersonPane() {
firstName = new JTextField(10);
lastName = new JTextField(10);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_END;
gbc.insets = new Insets(4, 4, 4, 4);
add(new JLabel("First name: "), gbc);
gbc.gridy++;
add(new JLabel("Last name: "), gbc);
gbc.gridx++;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_START;
add(firstName, gbc);
gbc.gridy++;
add(lastName, gbc);
}
public Person save() {
if (person == null) {
return new Person(System.currentTimeMillis(), firstName.getText(), lastName.getText());
}
long id = person.getId();
return new Person(id, firstName.getText(), lastName.getText());
}
}
public class PersonTableModel extends AbstractTableModel {
private List<Person> people = new ArrayList<>();
private List<String> columNames = new ArrayList<>(Arrays.asList(new String[]{"First name", "Last name"}));
public PersonTableModel() {
}
@Override
public int getRowCount() {
return people.size();
}
@Override
public int getColumnCount() {
return columNames.size();
}
@Override
public String getColumnName(int column) {
return columNames.get(column);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Person person = people.get(rowIndex);
switch (columnIndex) {
case 0:
return person.getFirstName();
case 1:
return person.getLastName();
}
return null;
}
public void addOrUpdate(Person person) {
int index = people.indexOf(person);
if (index >= 0) {
people.set(index, person);
fireTableRowsUpdated(index, index);
} else {
int lastIndex = people.size();
people.add(person);
fireTableRowsInserted(lastIndex, lastIndex);
}
}
public Person getPersonAtRow(int row) {
return people.get(row);
}
}
public class MainPane extends JPanel {
private PersonTableModel model = new PersonTableModel();
public MainPane() {
setLayout(new BorderLayout());
JButton newPersonButton = new JButton("New");
newPersonButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
PersonPane personPane = new PersonPane();
int option = JOptionPane.showConfirmDialog(MainPane.this, personPane, "New Person", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (option == JOptionPane.OK_OPTION) {
Person person = personPane.save();
if (person != null) {
model.addOrUpdate(person);
}
}
}
});
JToolBar toolBar = new JToolBar();
toolBar.add(newPersonButton);
JTable table = new JTable(model);
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int rowIndex = table.convertRowIndexToModel(table.getSelectedRow());
Person person = model.getPersonAtRow(rowIndex);
PersonPane personPane = new PersonPane(person);
int option = JOptionPane.showConfirmDialog(MainPane.this, personPane, "Edit Person", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (option == JOptionPane.OK_OPTION) {
person = personPane.save();
if (person != null) {
model.addOrUpdate(person);
}
}
}
}
});
add(toolBar, BorderLayout.NORTH);
add(new JScrollPane(table));
}
}
}
<标题>

你可以…如果你需要更灵活的东西或者想要更详细的验证,你可以滚动你自己的对话框(和验证工作流),但是你应该看看JOptionPane上的Disable ok按钮。对话框,直到用户给出一个输入,这演示了一种方法,你可以控制按钮的enabled状态,仍然使用JOptionPane

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class Person {
private long id;
private String firstName;
private String lastName;
public Person(long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@Override
public int hashCode() {
int hash = 7;
hash = 37 * hash + (int) (this.id ^ (this.id >>> 32));
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if (this.id != other.id) {
return false;
}
return true;
}
}
public static class PersonPane extends JPanel {
public interface ValidationObserver {
public void validStateDidChange(PersonPane source, boolean isValid);
}
private Person person;
private JTextField firstName;
private JTextField lastName;
private List<ValidationObserver> validationObservers = new ArrayList<>(8);
public PersonPane(Person person) {
this();
this.person = person;
if (person == null) {
return;
}
firstName.setText(person.getFirstName());
lastName.setText(person.getLastName());
}
public PersonPane() {
firstName = new JTextField(10);
lastName = new JTextField(10);
DocumentListener documentListener = new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
validateForm();
}
@Override
public void removeUpdate(DocumentEvent e) {
validateForm();
}
@Override
public void changedUpdate(DocumentEvent e) {
validateForm();
}
};
firstName.getDocument().addDocumentListener(documentListener);
lastName.getDocument().addDocumentListener(documentListener);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_END;
gbc.insets = new Insets(4, 4, 4, 4);
add(new JLabel("First name: "), gbc);
gbc.gridy++;
add(new JLabel("Last name: "), gbc);
gbc.gridx++;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_START;
add(firstName, gbc);
gbc.gridy++;
add(lastName, gbc);
}
public void addValidationObserver(ValidationObserver observer) {
validationObservers.add(observer);
}
public void removeValidationObserver(ValidationObserver observer) {
validationObservers.remove(observer);
}
protected void fireValidateStateDidChange(boolean isValid) {
for (ValidationObserver observer : validationObservers) {
observer.validStateDidChange(this, isValid);
}
}
protected void validateForm() {
boolean isValid = !firstName.getText().isBlank() && !lastName.getText().isBlank();
fireValidateStateDidChange(isValid);
}
public Person save() {
if (person == null) {
return new Person(System.currentTimeMillis(), firstName.getText(), lastName.getText());
}
long id = person.getId();
return new Person(id, firstName.getText(), lastName.getText());
}
public static Person createPerson(Component parent) {
return editPerson(parent, null);
}
public static Person editPerson(Component parent, Person person) {
enum State {
OKAY, CANCEL
}
JPanel actionPane = new JPanel(new GridBagLayout());
JButton okayButton = new JButton("Okay");
okayButton.setEnabled(false);
JButton cancelButton = new JButton("Cancel");
actionPane.add(okayButton);
actionPane.add(cancelButton);
PersonPane personPane = new PersonPane(person);
personPane.addValidationObserver(new ValidationObserver() {
@Override
public void validStateDidChange(PersonPane source, boolean isValid) {
okayButton.setEnabled(isValid);
}
});
JDialog dialog = new JDialog(SwingUtilities.windowForComponent(parent));
dialog.setModal(true);
dialog.add(personPane);
dialog.add(actionPane, BorderLayout.SOUTH);
okayButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
personPane.putClientProperty("state", State.OKAY);
dialog.dispose();
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
personPane.putClientProperty("state", State.CANCEL);
dialog.dispose();
}
});
dialog.pack();
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);
Object stateValue = personPane.getClientProperty("state");
if (stateValue instanceof State) {
State state = (State) stateValue;
if (state == State.OKAY) {
return personPane.save();
}
}
return null;
}
}
public class PersonTableModel extends AbstractTableModel {
private List<Person> people = new ArrayList<>();
private List<String> columNames = new ArrayList<>(Arrays.asList(new String[]{"First name", "Last name"}));
public PersonTableModel() {
}
@Override
public int getRowCount() {
return people.size();
}
@Override
public int getColumnCount() {
return columNames.size();
}
@Override
public String getColumnName(int column) {
return columNames.get(column);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Person person = people.get(rowIndex);
switch (columnIndex) {
case 0:
return person.getFirstName();
case 1:
return person.getLastName();
}
return null;
}
public void addOrUpdate(Person person) {
int index = people.indexOf(person);
if (index >= 0) {
people.set(index, person);
fireTableRowsUpdated(index, index);
} else {
int lastIndex = people.size();
people.add(person);
fireTableRowsInserted(lastIndex, lastIndex);
}
}
public Person getPersonAtRow(int row) {
return people.get(row);
}
}
public class MainPane extends JPanel {
private PersonTableModel model = new PersonTableModel();
public MainPane() {
setLayout(new BorderLayout());
JButton newPersonButton = new JButton("New");
newPersonButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Person person = PersonPane.createPerson(MainPane.this);
if (person != null) {
model.addOrUpdate(person);
}
}
});
JToolBar toolBar = new JToolBar();
toolBar.add(newPersonButton);
JTable table = new JTable(model);
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int rowIndex = table.convertRowIndexToModel(table.getSelectedRow());
Person person = model.getPersonAtRow(rowIndex);
person = PersonPane.editPerson(MainPane.this, person);
if (person != null) {
model.addOrUpdate(person);
}
}
}
});
add(toolBar, BorderLayout.NORTH);
add(new JScrollPane(table));
}
}
}

最新更新