First of all i'm new with Java. I make an Gui with 4 pannels (MainProgram).
In centerPanel is JTable which shows data from database.
In topPanel i put button that open new class / window - (ADD CUSTUMER) with some input fields. After click save button data is saved into database, and dispose()
. The data is saved correctly into database. The question is how to refresh table in MainProgram after saving? Thanks in advance.
There is some code:
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 btnAddCustumer = new JButton(new ImageIcon(buttonIcon));
btnAddCustumer.setText("ADD");
// btnAddCustumer.setBorder(null);
btnAddCustumer.setContentAreaFilled(false);
btnAddCustumer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
AddCustumer addCustumer;
try {
addCustumer = new AddCustumer();
addCustumer.setVisible(true);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
topPanel.add(btnAddCustumer);
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);
}
}
AddCustumer.java
public class AddCustumer 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 AddCustumer() throws IOException {
setResizable(false);
setType(Type.POPUP);
setTitle("ADD CUSTUMER");
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);
}
}
CodePudding user response:
There are a number of ways you might achieve this, but they all basically boil down to the same thing, a modal dialog. See How to Make Dialogs for more details.
You should avoid extending from top level containers like JFrame
(and JDialog
). You're not adding any new functionality to the class and are locking yourself into a single use case.
The following examples are intended to show how you ask users for input by using modal dialogs. Through same "black magic", when you show a modal dialog, the code execution will stop while the dialog is visible and resume when it's closed (don't ask, I don't care, it just works).
This means you can present a dialog and then wait till it's closed and then carry on making what ever decisions you need to.
You could...
Make use JOptionPane
, which is neat and handy API for making, well, dialogs.
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));
}
}
}
You could...
If you need something more flexible or want to more detailed validation, you could roll your own dialog (and validation workflows), but you should have a look at Disable ok button on JOptionPane.dialog until user gives an input, which demonstrates a means by which you could control the enabled
state of the buttons and still make use of a 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));
}
}
}