I am new to java swing. I am creating application for patient registration using Swing. There is a button called Clear, that button should clear the input data from the text fields.When button is InputPanel.clear() set the values correctly.But it is not updating.
My classes are below.
MainWindow class create and show the GUI.
public class MainWindow extends JFrame implements ActionListener {
private static final long serialVersionUID = 1905122041950251207L;
transient TableRowSorter<PatientTableModel> sorter;
private PatientListView patientListViewPanel = new PatientListView();
private InputPanel inputPanel = new InputPanel();
private SearchCriteriaPanel searhCriteriaPanel = new SearchCriteriaPanel(this);
public void createAndShowGUI() {
ButtonPanel btnPanel = new ButtonPanel(new MainWindow());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 600);
sorter = new TableRowSorter<>(patientListViewPanel.getTableModel());
GridBagLayout gbl = new GridBagLayout();
this.setLayout(gbl);
GridBagConstraints gcon = new GridBagConstraints();
gcon.weightx = 1;
gcon.weighty = 5;
gcon.fill = GridBagConstraints.BOTH;
gcon.gridx = 0;
gcon.gridy = 0;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(inputPanel, gcon);
this.add(inputPanel);
gcon.gridx = 4;
gcon.gridy = 10;
gcon.gridwidth = 11;
gcon.gridheight = 5;
gbl.setConstraints(btnPanel, gcon);
this.add(btnPanel);
gcon.gridx = 0;
gcon.gridy = 22;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(searhCriteriaPanel, gcon);
this.add(searhCriteriaPanel);
gcon.gridx = 0;
gcon.gridy = 33;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(patientListViewPanel, gcon);
this.add(patientListViewPanel);
this.setVisible(true);
inputPanel.getNameText().addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (inputPanel.getNameText().getText().length() > 0)
btnPanel.getSaveBtn().setEnabled(true);
}
});
patientListViewPanel.getTable().addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
getSelectedData();
}
});
}
public MainWindow() {
super("Patient Registration");
}
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
switch (button.getText()) {
case "Save":
patientListViewPanel.getTableModel()
.addData(inputPanel.getData(patientListViewPanel.getTable().getRowCount()));
button.setEnabled(false);
break;
case "Clear":
inputPanel.clear();
break;
case "Search":
SearchCriteria s = new SearchCriteria(searhCriteriaPanel.getSearchNameText().getText(),
searhCriteriaPanel.getBirthYearText().getText(), searhCriteriaPanel.getMaleChkBx().isSelected(),
searhCriteriaPanel.getFemaleChkBx().isSelected());
patientListViewPanel.filter(s);
break;
default:
}
}
}
InputPanel is handle the fields and methods related to input data
public class InputPanel extends JPanel implements PropertyChangeListener {
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(" ");
phnText.setText("0");
datePickerObj.jDatePicker.getJFormattedTextField().setText("");
maleBtn.setSelected(true);
femaleBtn.setSelected(false);
adrsTxt.setText("");
statusList.setSelectedIndex(4);
}
public InputPanel() {
// fiels will be set to panel
addDataChangedListner();
isDataValid(phnText);
}
public void addDataChangedListner() {
PatientData model = new PatientData();
model.addPropertyChangeListener(this);
nameText.getDocument().addDocumentListener(new DataChangedListener(model, "name"));
phnText.getDocument().addDocumentListener(new DataChangedListener(model, "phnNumber"));
adrsTxt.getDocument().addDocumentListener(new DataChangedListener(model, "address"));
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
String property = evt.getPropertyName();
String newValue = (String) evt.getNewValue();
switch (property) {
case "name":
updatedName = newValue;
break;
case "phnNumber":
updatedPhoneNumber = newValue;
break;
case "address":
updatedAddress = newValue;
break;
default:
}
}
}
Can someone help me to resolve this?
The basic functionality that you are having difficulty with is demonstrated in the following mre: (1)
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MainWindow extends JFrame{
private InputPanel inputPanel;
private JButton saveBtn;
public void createAndShowGUI() {
inputPanel = new InputPanel();
saveBtn = new JButton("Save");
saveBtn.setEnabled(false);
add(saveBtn, BorderLayout.SOUTH);
JButton clearButton = new JButton("Clear");
clearButton.addActionListener(e->clearInput());
add(clearButton, BorderLayout.CENTER);
add(inputPanel, BorderLayout.NORTH);
inputPanel.getNameText().addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (inputPanel.getNameText().getText().length() > 0) {
saveBtn.setEnabled(true);
}
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
private void clearInput(){
inputPanel.clear();
saveBtn.setEnabled(false);
}
public MainWindow() {
createAndShowGUI();
}
public static void main(String[] args) {
new MainWindow();
}
}
class InputPanel extends JPanel {
JTextField nameText;
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(""); //use "" and not " " so text length = 0
}
public InputPanel() {
nameText = new JTextField(5);
add(nameText);
}
public JTextField getNameText() {
return nameText;
}
}
However, a better approach is to use the model to implement the change of data :
public class MainWindow extends JFrame implements PropertyChangeListener{
private InputPanel inputPanel;
private JButton saveBtn;
private final PatientData model;
public void createAndShowGUI() {
inputPanel = new InputPanel(model);
saveBtn = new JButton("Save");
saveBtn.setEnabled(false);
add(saveBtn, BorderLayout.SOUTH);
JButton clearButton = new JButton("Clear");
clearButton.addActionListener(e->clearInput());
add(clearButton, BorderLayout.CENTER);
add(inputPanel, BorderLayout.NORTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
private void clearInput(){
inputPanel.clear();
}
public MainWindow() {
model = new PatientData();
model.setPropertyChangeListener(this);
createAndShowGUI();
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
updateGui();
}
private void updateGui() {
if(model.getName().trim().isEmpty()){
saveBtn.setEnabled(false);
}else{
saveBtn.setEnabled(true);
}
}
public static void main(String[] args) {
new MainWindow();
}
}
class InputPanel extends JPanel implements DocumentListener{
private final JTextField nameText;
private final PatientData model;
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(""); //use "" and not " " so text length = 0
updateModel();
}
public InputPanel(PatientData model) {
this.model = model;
nameText = new JTextField("",5);
nameText.getDocument().addDocumentListener(this);
add(nameText);
}
#Override
public void changedUpdate(DocumentEvent e) {
updateModel();
}
#Override
public void removeUpdate(DocumentEvent e) {
updateModel();
}
#Override
public void insertUpdate(DocumentEvent e) {
updateModel();
}
private void updateModel() {
model.setName(nameText.getText());
}
}
class PatientData{
private String name ="";
private PropertyChangeListener listener;
public String getName() {
return name;
}
public void setPropertyChangeListener(PropertyChangeListener listener) {
this.listener = listener;
}
public void setName(String name) {
String oldName = this.name;
this.name = name;
if(listener != null) {
listener.propertyChange(new PropertyChangeEvent(this,"name", oldName, name));
}
}
}
(Test is online here)
(1) Always consider an mre when posting a question or answer.
I am working on a school project using BlueJay and I have created two classes in package Logic which are the Game class, and the VectorGames class.
In my package GUI, I created a class called AddGame and ViewGame class.
The issue that I have encountered is that, when I click the Save Button on Addgame, it saves the file only once. When I try to save it doesn't do or say anything it just stays there returning nothing. Another issue encountered is that on ViewGame, the gameType column is remaining empty ( this is from combo type box )
AddGame code :
package GUI;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import Logic.*;
public class AddGame extends JFrame implements ActionListener{
private JPanel north, south, east, west, center;
private JLabel titleLabel, westLabel, eastLabel;
private JTextField gameNameFld, gameKeyFld;
private JComboBox gameTypeCombo;
private JButton saveButton, clearButton;
private VectorGames vg;
public AddGame(){
super("Adding a Game");
this.setLayout(new BorderLayout());
vg = new VectorGames();
vg.readFromFile();
//north panel
north = new JPanel();
this.add(north,BorderLayout.NORTH);
titleLabel = new JLabel("Add a game below");
titleLabel.setFont(new Font("Verdana",Font.BOLD,20));
titleLabel.setForeground(Color.black);
north.add(titleLabel);
//west and east panels
west = new JPanel();
east = new JPanel();
this.add(west, BorderLayout.WEST);
this.add(east, BorderLayout.EAST);
westLabel = new JLabel(" ");
eastLabel = new JLabel(" ");
west.add(westLabel);
east.add(eastLabel);
//center panel
center = new JPanel();
this.add(center, BorderLayout.CENTER);
center.setLayout(new GridLayout(4,2,0,20));
gameNameFld = new JTextField();
gameKeyFld = new JTextField();
gameTypeCombo = new JComboBox();
gameTypeCombo.setModel(new DefaultComboBoxModel(new String[]
{"<--Select-->", "Arcade", "Puzzle", "Adventure", "Shooter", "Roleplay"}));
center.add(createLabel("Game Name"));
center.add(gameNameFld);
center.add(createLabel("Game Key"));
center.add(gameKeyFld);
center.add(createLabel("Game Type"));
center.add(gameTypeCombo);
//south panel
south = new JPanel();
south.setLayout(new FlowLayout());
this.add(south, BorderLayout.SOUTH);
clearButton = new JButton("Clear");
south.add(clearButton);
clearButton.addActionListener(this);
saveButton = new JButton("Save");
south.add(saveButton);
saveButton.addActionListener(this);
this.setSize(300,400);
this.setLocation(50,50);
this.setVisible(true);
}
private JLabel createLabel(String title){
return new JLabel(title);
}
private void clearFields(){
gameNameFld.setText("");
gameKeyFld.setText("");
gameTypeCombo.setSelectedIndex(0);
}
private boolean validateForm(){
boolean flag = false;
if(gameNameFld.getText().equals("")||gameKeyFld.getText().equals("")||
gameTypeCombo.getSelectedIndex()==0){
flag = true;
}
return flag;
}
public void actionPerformed(ActionEvent event){
if (event.getSource() == clearButton){
clearFields();
}
if(event.getSource() == saveButton){
if(validateForm() == true){
JOptionPane.showMessageDialog(null,"You have empty fields",
"Empty Fields", JOptionPane.ERROR_MESSAGE);
} else if(vg.checkGamebyGameKey(gameKeyFld.getText()) == true){
JOptionPane.showMessageDialog(null,"Game Key already exists!",
"Game Key Check", JOptionPane.ERROR_MESSAGE);
} else {
Game tempGame = new Game(gameNameFld.getText(),gameKeyFld.getText(),
(String)gameTypeCombo.getSelectedItem());
vg.addGame(tempGame);
vg.saveToFile();
JOptionPane.showMessageDialog(null, "Game added successfully!", "Adding a Game",
JOptionPane.INFORMATION_MESSAGE);
clearFields();
}
}
}
}
ViewGame code:
package GUI;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import Logic.*;
public class ViewGame extends JFrame {
private JTable table;
private VectorGames vg;
public ViewGame(){
super("Viewing Games by Name");
this.setLayout(new BorderLayout());
vg = new VectorGames();
vg.readFromFile();
vg.sortGamesByName();
int numOfGames = vg.getVectorSize();
int count = 0;
Game tempGame = new Game();
String[] tableHeader = {"Game Name", "Game Type", "Game Key"};
Object [][] tableContent = new Object[numOfGames][3];
for(int i = 0; i < numOfGames; i++){
tempGame = vg.getGamesByIndex(count);
tableContent[i][0] = tempGame.getGameName();
tableContent[i][2] = tempGame.getGameType();
tableContent[i][1] = tempGame.getGameKey();
}
table = new JTable (tableContent, tableHeader);
JScrollPane scrollPane = new JScrollPane(table);
table.setPreferredScrollableViewportSize(new Dimension(500, 400));
this.add(table.getTableHeader(), BorderLayout.NORTH);
this.add(table, BorderLayout.CENTER);
this.setSize(500,600);
this.setLocation(100,50);
this.setVisible(true);
}
}
Game code:
package Logic;
import java.io.*;
public class Game implements Serializable{ // Using serializable to allow easy save and read access
//Initializing variables related to Game
private String gameName, gameKey, gameType;
//Creating a constructor with the parameters for class Games
public Game(String gameName, String gamekey, String gameType){
setGameName(gameName);
setGameKey(gameKey);
setGameType(gameType);
}
//Setting up a parameterless constructor for class Games
public Game(){
}
public String getGameName(){//Get Method for gameName
return gameName;
}
public String getGameKey(){//Get Method for gameKey
return gameKey;
}
public String getGameType(){//Get Method for gameType
return gameType;
}
public void setGameName(String gameName){//Set Method for gameName
this.gameName = gameName;
}
public void setGameKey(String gameKey){//Set Method for gameKey
this.gameKey = gameKey;
}
public void setGameType(String gameType){//Set Method for gameType
this.gameType = gameType;
}
public String toString(){
return "Game Name : " + gameName + "\nGame Key : "
+ gameKey + "\nGame Type ; " + gameType;
}
}
VectorGames code:
package Logic;
import java.util.*;
import java.io.*;
import java.lang.*;
public class VectorGames extends IOException{
/* Add a Game, Remove a Game, getVectorGame Size, print allGamesAvailable,
* saveToFile , searchGame and return boolean literal, searchGame and return
* client object, sort games, readFromFile.
*
*/
private Vector<Game> games;
public VectorGames(){
games = new Vector<Game>();
}
//Adding a Game
public void addGame(Game game){
games.add(game);
}
public void deleteGame(Game game){
games.remove(game);
}
public int getVectorSize(){
return games.size();
}
public void clearVector(){
games.clear();
}
public void printGames(){
for(Game tempGame : games){
System.out.println(tempGame.toString());
System.out.println("");
}
}
public Game getGamesByIndex(int i){
Game tempGame = new Game();
if (i < getVectorSize()){
tempGame = games.get(i);
}
return tempGame;
}
public void sortGamesByName(){
Game currentGame = new Game();
Game nextGame = new Game();
Game tempGame = new Game();
for(int i = 0; i < getVectorSize(); i++){
for(int j = 0; j < getVectorSize()-i-1; j++){
currentGame = games.elementAt(j);
nextGame = games.elementAt(j+1);
if(currentGame.getGameName().compareTo(nextGame.getGameName())>0){
tempGame = currentGame;
games.setElementAt(nextGame, j);
games.setElementAt(tempGame, j+1);
}
}
}
}
public boolean checkGamebyGameKey(String gameKey){
boolean flag = false;
for(Game tempGames : games){
if(tempGames .getGameKey().equals(gameKey)){
flag = true;
}
}
return flag;
}
public Game accessGameByGameName(String gameName){
Game foundGameName = new Game();
for(Game tempGames: games){
if(tempGames.getGameName().equals(gameName)){
foundGameName = tempGames;
}
}
return foundGameName;
}
public void saveToFile(){
try{
File f = new File("C:/Users/Denis/Desktop/GameStore/Databases","gameList.obj");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(games);
oos.flush();
oos.close();
}catch (IOException ioe){
System.err.println("Cannot write to file!");
}
}
public void readFromFile(){
try{
File f = new File("C:/Users/Denis/Desktop/GameStore/Databases","gameList.obj");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
games = (Vector<Game>) ois.readObject();
ois.close();
} catch (FileNotFoundException fnfe){
System.err.println("Cannot find file!");
}catch (IOException ioe){
System.err.println("Cannot read from file!");
}catch(ClassNotFoundException cnfe){
System.err.println("Client class cannot be found!");
}
}
}
Main class: GameCenter
public class GameCenter extends JFrame {
public static void main(String... args) {
SwingUtilities.invokeLater(() -> new GameCenter().setVisible(true));
}
public GameCenter() {
super("Game Center");
init();
}
private void init() {
setLayout(new BorderLayout(5, 5));
Model model = new Model();
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.add("Add", new AddTabPanel(model));
tabbedPane.add("View", new ViewTabPanel(model));
add(tabbedPane, BorderLayout.CENTER);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(400, 500);
setMinimumSize(new Dimension(400, 500));
setResizable(false);
}
}
Game entity:
final class Game {
private static final Pattern RECORD = Pattern.compile("(?<key>.+)\\|(?<name>.+)\\|(?<type>.+)");
private final String name;
private final String key;
private final String type;
public static Game createFromRecord(String str) {
Matcher matcher = RECORD.matcher(str);
return matcher.matches() ? new Game(matcher.group("name"), matcher.group("key"), matcher.group("type")) : null;
}
public Game(String name, String key, String type) {
this.name = name;
this.key = key;
this.type = type;
}
public String getName() {
return name;
}
public String getKey() {
return key;
}
public String getType() {
return type;
}
public String serialize() {
return String.format("%s|%s|%s", key, name, type);
}
}
Table model:
final class Model extends AbstractTableModel {
private static final long serialVersionUID = 1858846855164475327L;
private final Map<String, Game> keyGame = new TreeMap<>();
private final List<Game> data = new ArrayList<>();
private File file;
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public void add(String name, String key, String type) {
keyGame.put(key, new Game(name, key, type));
fireTableDataChanged();
}
public void remove(int rowIndex) {
keyGame.remove(data.get(rowIndex).getKey());
fireTableDataChanged();
}
public void save() throws IOException {
if (file == null)
return;
try (FileWriter out = new FileWriter(file, false)) {
for (Game game : keyGame.values())
out.write(game.serialize() + '\n');
}
}
public void read() throws IOException {
if (file == null)
return;
keyGame.clear();
for (String record : Files.readAllLines(file.toPath())) {
Game game = Game.createFromRecord(record);
if (game != null)
keyGame.put(game.getKey(), game);
}
fireTableDataChanged();
}
private enum Column {
NAME("Game Name", Game::getName),
KEY("Game Key", Game::getKey),
TYPE("Game Type", Game::getType);
private final String title;
private final Function<Game, Object> get;
Column(String title, Function<Game, Object> get) {
this.title = title;
this.get = get;
}
public Object getValue(Game game) {
return get.apply(game);
}
}
// ========== AbstractTableModel ==========
#Override
public void fireTableDataChanged() {
data.clear();
data.addAll(keyGame.values());
super.fireTableDataChanged();
}
// ========== TableModel ==========
#Override
public int getRowCount() {
return data.size();
}
#Override
public int getColumnCount() {
return Column.values().length;
}
#Override
public String getColumnName(int columnIndex) {
return Column.values()[columnIndex].title;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return Column.values()[columnIndex].getValue(data.get(rowIndex));
}
}
AddGame tab panel:
final class AddTabPanel extends JPanel implements ActionListener, DocumentListener {
private final Model model;
private final JTextField nameField = new JTextField();
private final JTextField keyField = new JTextField();
private final JLabel nameLabel = new JLabel("Game Name");
private final JLabel keyLabel = new JLabel("Game Key");
private final JLabel typeLabel = new JLabel("Game Type");
private final JComboBox<String> typeCombo = createGameTypeCombo();
private final JButton openButton = new JButton("Open");
private final JButton saveButton = new JButton("Save");
private final JButton clearButton = new JButton("Clear");
public AddTabPanel(Model model) {
this.model = model;
init();
addListeners();
}
private void init() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = createConstraints();
add(createTitlePanel(), gbc);
add(createMainPanel(), gbc);
add(createButtonPanel(), gbc);
gbc.weighty = 1;
add(Box.createVerticalGlue(), gbc);
onNameFieldChanged();
onKeyFieldChanged();
onTypeComboChanged();
}
private static JPanel createTitlePanel() {
JLabel label = new JLabel("Add a game below");
label.setFont(new Font("Verdana", Font.BOLD, 20));
JPanel panel = new JPanel();
panel.add(label);
return panel;
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridLayout(3, 2, 5, 5));
panel.add(nameLabel);
panel.add(nameField);
panel.add(keyLabel);
panel.add(keyField);
panel.add(typeLabel);
panel.add(typeCombo);
return panel;
}
private static GridBagConstraints createConstraints() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
return gbc;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel();
panel.add(clearButton);
panel.add(saveButton);
panel.add(openButton);
return panel;
}
private static JComboBox<String> createGameTypeCombo() {
JComboBox<String> combo = new JComboBox<>();
combo.setModel(new DefaultComboBoxModel<>(new String[] { "<--Select-->", "Arcade", "Puzzle", "Adventure", "Shooter", "Roleplay" }));
return combo;
}
private void addListeners() {
clearButton.addActionListener(this);
saveButton.addActionListener(this);
openButton.addActionListener(this);
nameField.getDocument().addDocumentListener(this);
keyField.getDocument().addDocumentListener(this);
typeCombo.addActionListener(this);
}
private void validateFields() {
String name = nameField.getText().trim();
String key = keyField.getText().trim();
int type = typeCombo.getSelectedIndex();
saveButton.setEnabled(!name.isEmpty() && !key.isEmpty() && type != 0);
}
private void onNameFieldChanged() {
nameLabel.setForeground(nameField.getText().trim().isEmpty() ? Color.RED : Color.BLACK);
validateFields();
}
private void onKeyFieldChanged() {
keyLabel.setForeground(keyField.getText().trim().isEmpty() ? Color.RED : Color.BLACK);
validateFields();
}
private void onTypeComboChanged() {
typeLabel.setForeground(typeCombo.getSelectedIndex() == 0 ? Color.RED : Color.BLACK);
validateFields();
}
private void onCleanButton() {
nameField.setText(null);
keyField.setText(null);
typeCombo.setSelectedIndex(0);
validateFields();
}
private void onSaveButton() {
String name = nameField.getText().trim();
String key = keyField.getText().trim();
String type = (String)typeCombo.getSelectedItem();
model.add(name, key, type);
if (model.getFile() == null) {
JFileChooser fileChooser = new JFileChooser();
int res = fileChooser.showSaveDialog(this);
model.setFile(res == JFileChooser.APPROVE_OPTION ? fileChooser.getSelectedFile() : null);
}
try {
model.save();
} catch(Exception e) {
JOptionPane.showMessageDialog(this, "Cannot save file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
}
}
private void onOpenButton() {
JFileChooser fileChooser = new JFileChooser();
int res = fileChooser.showOpenDialog(null);
model.setFile(res == JFileChooser.APPROVE_OPTION ? fileChooser.getSelectedFile() : null);
try {
model.read();
} catch(Exception e) {
JOptionPane.showMessageDialog(this, "Cannot read file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
}
}
// ========== ActionListener ==========
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == typeCombo)
onTypeComboChanged();
else if (e.getSource() == clearButton)
onCleanButton();
else if (e.getSource() == saveButton)
onSaveButton();
else if (e.getSource() == openButton)
onOpenButton();
}
// ========== DocumentListener ==========
#Override
public void insertUpdate(DocumentEvent e) {
if (e.getDocument() == nameField.getDocument())
onNameFieldChanged();
else if (e.getDocument() == keyField.getDocument())
onKeyFieldChanged();
}
#Override
public void removeUpdate(DocumentEvent e) {
if (e.getDocument() == nameField.getDocument())
onNameFieldChanged();
else if (e.getDocument() == keyField.getDocument())
onKeyFieldChanged();
}
#Override
public void changedUpdate(DocumentEvent e) {
}
}
ViewGame tab panel:
final class ViewTabPanel extends JPanel implements ActionListener, PopupMenuListener {
private final Model model;
private final JTable table = new JTable();
private final JPopupMenu popupMenu = new JPopupMenu();
private final JMenuItem deleteItem = new JMenuItem("Delete");
public ViewTabPanel(Model model) {
this.model = model;
init();
addListeners();
}
private void init() {
setLayout(new GridLayout(1, 1));
add(new JScrollPane(table));
popupMenu.add(deleteItem);
table.setComponentPopupMenu(popupMenu);
table.setAutoCreateRowSorter(true);
table.setModel(model);
table.updateUI();
}
private void addListeners() {
popupMenu.addPopupMenuListener(this);
deleteItem.addActionListener(this);
}
// ========== ActionListener ==========
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == deleteItem) {
model.remove(table.getSelectedRow());
try {
model.save();
} catch(Exception e) {
JOptionPane.showMessageDialog(this, "Cannot save file", e.getMessage(), JOptionPane.ERROR_MESSAGE);
}
}
}
// ========== PopupMenuListener ==========
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent event) {
if (event.getSource() == popupMenu) {
SwingUtilities.invokeLater(() -> {
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
if (rowAtPoint > -1)
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
});
}
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent event) {
}
#Override
public void popupMenuCanceled(PopupMenuEvent event) {
}
}
I am new to Java and programming in general and also new to Stack overflow. Im taking a course in object orientation and i am stuck at one assignment. Hope i can get some tips or feedback here.
I have written a fictive Banking program and now i am supposed to write an user interface.
The class SubMenuWindow have graphic components to draw a window in whitch i want to show all my Customers names and ID-numbers.
The Classes CustomerSubWindow and CreditAccountSubWindow inherits from SubMenuWindow since i want both of them to display the customers names and ID numbers.
When i create customer objects everthing works as its supossed to in the frame created from CustomerSubWindow, but the Frame created from CreditAccountWindow wont display the names and ID-numbers. Both inherit from the same parentclass, why dont they have the same behaviour?
I have tried to rewrite the code in different ways but the error persists. Can someone see what might be wrong?
I am aware that there are a bunch of formal convention errors (indentation, varabel names etc)
Here are the three classes:
First is the parent class:
public abstract class SubMenuWindow extends JFrame {
protected BankLogic bank = new BankLogic();
private JPanel customersDisplayPanel;
private JLabel customersDisplayLabel;
JTextArea customersDisplayText;
private GridBagLayout gridBag;
private GridBagConstraints customGrid;
private FlowLayout layout;
private JScrollPane scrollBarDisplayText;
private static final int TEXT_LENGTH = 30;
private static final int ROWS = 20;
private static final int COLUMNS = 50;
private static final int FRAME_HEIGHT = 900;
private static final int FRAME_WIDTH = 1600;
public SubMenuWindow(String title) {
super(title);
createComponents();
FlowLayout layout = new FlowLayout();
this.setSize(FRAME_WIDTH, FRAME_HEIGHT);
this.setVisible(false);
this.setDefaultCloseOperation(HIDE_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setResizable(false);
this.setLayout(layout);//
this.add(customersDisplayPanel);
}
private void createComponents(){
gridBag = new GridBagLayout();
customGrid = new GridBagConstraints();
customersDisplayPanel = new JPanel(gridBag);
customersDisplayLabel = new JLabel("Within this frame you can find all
the Customers in the bank");
setCustomersDisplayText(new JTextArea(ROWS,COLUMNS));
scrollBarDisplayText = new JScrollPane(getCustomersDisplayText());
customGrid.gridx = 0;
customGrid.gridy = 1;
customersDisplayPanel.add(customersDisplayLabel, customGrid);
customGrid.gridx = 0;
customGrid.gridy = 2;
customersDisplayPanel.add(scrollBarDisplayText,customGrid);
}
public void createBankLogicCustomer(String firstNameString, String
surNameString, String pnumString ){
bank.createCustomer(firstNameString, surNameString, pnumString);
updateCustomersTextArea();
}
public void updateCustomersTextArea(){
customersDisplayText.setText("");
for(String customer : bank.getAllCustomers()){
customersDisplayText.append(customer + "\n");
}
}
public BankLogic getBank(){
return bank;
}
public static int getTextLength() {
return TEXT_LENGTH;
}
public JTextArea getCustomersDisplayText() {
return customersDisplayText;
}
public void setCustomersDisplayText(JTextArea customersDisplayText) {
this.customersDisplayText = customersDisplayText;
}
}
Second class
public class CustomerSubWindow extends SubMenuWindow {
private JPanel nameInputPanel;
private JTextField firstNameTextField;
private JTextField surNameTextField;
private JTextField pNumTextField;
private JLabel firstNameLabel;
private JLabel surNameLabel;
private JLabel pNumLabel;
private JButton finishButton;
private ActionListener createCustomerButtonPressed;
public CustomerSubWindow(String title) {
super(title);
createComponents();
this.add(nameInputPanel);
}
public void createComponents(){
nameInputPanel = new JPanel();
firstNameTextField = new JTextField(super.getTextLength());
surNameTextField= new JTextField(super.getTextLength());
pNumTextField= new JTextField(super.getTextLength());
firstNameLabel= new JLabel("First name: ");
surNameLabel= new JLabel("Surname: ");
pNumLabel= new JLabel("Person number: ");
finishButton = new JButton("Create customer");
createCustomerButtonPressed = new CustomerButtonListener();
finishButton.addActionListener(createCustomerButtonPressed);
nameInputPanel.add(firstNameLabel);
nameInputPanel.add(firstNameTextField);
nameInputPanel.add(surNameLabel);
nameInputPanel.add(surNameTextField);
nameInputPanel.add(pNumLabel);
nameInputPanel.add(pNumTextField);
nameInputPanel.add(finishButton);
}
private class CustomerButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent custButtonPressed){
if (custButtonPressed.getSource()==finishButton){
String firstNameString = firstNameTextField.getText();
String surNameString = surNameTextField.getText();
String pnumString = pNumTextField.getText();
createBankLogicCustomer(firstNameString, surNameString,
pnumString);
updateCustomersTextArea();
}
}
}
}
And finally the third Class
public class CreditAccountSubWindow extends SubMenuWindow {
private JPanel pNoInputPanel;
private JTextField pNoTextField;
private JLabel pNoLabel;
private JButton pNoButton;
private ActionListener createCreditAccountButtonPressed;
public CreditAccountSubWindow(String title)
super(title);
createComponents();
this.add(pNoInputPanel);
}
public void createComponents(){
pNoInputPanel = new JPanel();
pNoTextField = new JTextField(super.getTextLength());
pNoLabel = new JLabel("Input client ID number");
pNoButton = new JButton("Create Account");
createCreditAccountButtonPressed = new CreditAccButtonListener();
pNoButton.addActionListener(createCreditAccountButtonPressed);
pNoInputPanel.add(pNoLabel);
pNoInputPanel.add(pNoTextField);
pNoInputPanel.add(pNoButton);
}
private class CreditAccButtonListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent creditAccButtonPressed){
if (creditAccButtonPressed.getSource()==pNoButton){
String pNo = pNoTextField.getText();
getBank().createCreditAccount(pNo);
System.out.println(getBank().createCreditAccount(pNo));
}
}
}
}
This project requires that a user inputs data into text fields on a dialog box accessed from a menu bar and places the data from the text fields into a JTable. The problem is that once the user clicks okay on the dialog box after putting the information into the text field, the dialog box is no longer visible, but nothing appears in the JTable. The JTable headers are there, but the info just submitted is not.
It is a camping registration program, and all of the classes compile okay. I am only working on taking information from an RV reservation first, but will eventually do the same for a tent reservation. Here are the classes that correspond to an RV check in. There is an RV constructor that has parameters (String (name), String (check in day), int (days staying), String (leave day), int (site number), int (power needed)).
First the dialog box class:
package campingPrj;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogCheckInRv extends javax.swing.JDialog implements ActionListener {
private static final long serialVersionUID = 1L;
private javax.swing.JTextField nameTxt;
private javax.swing.JTextField dateIn;
private javax.swing.JTextField stayingTxt;
private javax.swing.JTextField siteNumberTxt;
private javax.swing.JTextField checkOutDate;
private javax.swing.JTextField powerTxt;
private javax.swing.JButton okButton;
private javax.swing.JButton cancelButton;
private boolean cancel;
private boolean okay;
public DialogCheckInRv(java.awt.Frame parent) {
super(parent, true);
setupDialog();
setTitle("RV Check In");
}
private void setupDialog() {
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
nameTxt = new javax.swing.JTextField(27);
dateIn = new javax.swing.JTextField(25);
stayingTxt = new javax.swing.JTextField(25);
siteNumberTxt = new javax.swing.JTextField(27);
powerTxt = new javax.swing.JTextField(27);
okButton = new javax.swing.JButton("Ok");
okButton.addActionListener(this);
cancelButton = new javax.swing.JButton("Cancel");
cancelButton.addActionListener(this);
setLayout(new GridLayout(6, 1));
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.add(new JLabel("Name Reserving:"));
panel.add(nameTxt);
add(panel);
panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.add(new JLabel("Start Date (mm/dd/yy) :"));
panel.add(dateIn);
add(panel);
panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.add(new JLabel("Days Planning on Staying:"));
panel.add(stayingTxt);
add(panel);
panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.add(new JLabel("Requested Site Number:"));
panel.add(siteNumberTxt);
add(panel);
panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.add(new JLabel("Power Needed (in AMPs):"));
panel.add(powerTxt);
add(panel);
panel = new JPanel();
panel.add(okButton);
panel.add(cancelButton);
add(panel);
pack();
setLocationRelativeTo(null);
}
public void actionPerformed(java.awt.event.ActionEvent event) {
if (event.getSource() == okButton) {
okay = true;
cancel = false;
setVisible(false);
}
if (event.getSource() == cancelButton) {
okay = false;
cancel = true;
setVisible(false);
}
}
public boolean isOk() {
return okay;
}
public boolean isCancel() {
return cancel;
}
public String getName() {
return nameTxt.getText();
}
public String getDateIn() {
return dateIn.getText();
}
public String getDaysStaying() {
return stayingTxt.getText();
}
public String getCheckOutDate() {
return checkOutDate.getText();
}
public String getPower() {
return powerTxt.getText();
}
public String getSiteNumber() {
return siteNumberTxt.getText();
}
public void clear() {
nameTxt.setText(null);
dateIn.setText(null);
stayingTxt.setText(null);
dateIn.setText(null);
powerTxt.setText(null);
siteNumberTxt.setText(null);
}
}
The GUI with the table (where I'm guessing the problem is in the actionPerformed method):
package campingPrj;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class GUICampingReg extends javax.swing.JFrame implements ActionListener {
private JMenuItem openSerialFileItem = new JMenuItem("Open Serialized File");
private JMenuItem openTextFileItem = new JMenuItem("Open Text File");
private JMenuItem saveSerialFileItem = new JMenuItem("Save Serialized File");
private JMenuItem saveTextFileItem = new JMenuItem("Save Text File");
private JMenuItem exitItem = new JMenuItem("Exit");
private JMenuItem checkInTentItem = new JMenuItem("Check in tent");
private JMenuItem checkInRVItem = new JMenuItem("Check in RV");
private JMenuItem checkOutItem = new JMenuItem("Date Leaving");
private JTextField nameReservingTxt;
private JTextField dateInTxt;
private JTextField daysStayingTxt;
private JTextField checkOutOnTxt;
private JTextField siteNumberTxt;
private JTextField powerTxt;
private JFrame frame;
private JTable table;
private SiteModel model;
private JScrollPane scrollPane;
private DialogCheckInRv newRv;
public GUICampingReg() {
setupFrame();
newRv = new DialogCheckInRv(this);
model = new SiteModel();
table.setModel(model);
}
private void setupFrame() {
frame = new JFrame();
frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
frame.setTitle("Camping Registration Program");
scrollPane = new JScrollPane();
table = new JTable();
JMenuBar menubar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.add(openSerialFileItem);
fileMenu.add(openTextFileItem);
fileMenu.add(saveSerialFileItem);
fileMenu.add(saveTextFileItem);
fileMenu.add(exitItem);
JMenu checkInMenu = new JMenu("Check In");
checkInMenu.add(checkInRVItem);
checkInMenu.add(checkInTentItem);
JMenu checkOutMenu = new JMenu("Check Out");
checkOutMenu.add(checkOutItem);
menubar.add(fileMenu);
menubar.add(checkInMenu);
menubar.add(checkOutMenu);
openSerialFileItem.addActionListener(this);
openTextFileItem.addActionListener(this);
saveSerialFileItem.addActionListener(this);
saveTextFileItem.addActionListener(this);
exitItem.addActionListener(this);
checkInTentItem.addActionListener(this);
checkInRVItem.addActionListener(this);
checkOutItem.addActionListener(this);
frame.setJMenuBar(menubar);
scrollPane
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
table.setToolTipText("");
table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
table.getTableHeader().setReorderingAllowed(false);
table.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
tableMouseClicked();
}
});
scrollPane.setViewportView(table);
frame.add(scrollPane, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void tableMouseClicked() {
// TODO Auto-generated method stub
}
public void actionPerformed(ActionEvent evt) {
Object pressed = evt.getSource();
if (pressed == exitItem) {
System.exit(0);
}
if (pressed == openSerialFileItem) {
}
if (pressed == openTextFileItem) {
}
if (pressed == saveSerialFileItem) {
}
if (pressed == saveTextFileItem) {
}
if (pressed == checkInTentItem) {
}
if (pressed == checkInRVItem) {
newRv.clear();
newRv.setVisible(true);
if (newRv.isOk()) {
String nameReserving = nameReservingTxt.getText();
String checkIn = dateInTxt.getText();
int daysStaying = Integer.parseInt(daysStayingTxt.getText());
String checkOutOn = checkOutOnTxt.getText();
int siteNumber = Integer.parseInt(siteNumberTxt.getText());
int power = Integer.parseInt(powerTxt.getText());
RV rv = new RV (nameReserving, checkIn, daysStaying, checkOutOn, siteNumber, power);
model.add(rv);
}
}
if (pressed == checkOutItem) {
}
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GUICampingReg();
}
});
}
}
The site model class:
package campingPrj;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
public class SiteModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private ArrayList<Site> listSites;
private String[] columnNames = { "Name Reserving", "Checked in Date",
"Days Staying", "Site #", "Tenters/RV Power Needed" };
public SiteModel() {
listSites = new ArrayList<Site>();
}
public String getColumnName(int col) {
return columnNames[col];
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return listSites.size();
}
public Object getValueAt(int row, int col) {
Object val = null;
switch (col) {
case 0:
val = listSites.get(row).getNameReserving();
break;
case 1:
val = listSites.get(row).getCheckIn();
break;
case 2:
val = listSites.get(row).getDaysStaying();
break;
case 3:
val = listSites.get(row).getSiteNumber();
break;
case 4:
val = listSites.get(row).getCheckOutOn();
break;
}
return val;
}
public Site get(int index) {
return listSites.get(index);
}
public int indexOf(Site s) {
return listSites.indexOf(s);
}
public void add(Site s) {
if (s != null) {
listSites.add(s);
fireTableRowsInserted(listSites.size() - 1, listSites.size() - 1);
}
}
public void add(int index, Site s) {
if (s != null) {
listSites.add(index, s);
fireTableRowsInserted(index, index);
}
}
public void remove(int index) {
listSites.remove(index);
fireTableRowsDeleted(index, index);
return;
}
public void remove(Site s) {
remove(indexOf(s));
}
public void saveAsSerialized(String filename) throws IOException {
FileOutputStream fos = new FileOutputStream(filename);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(listSites);
os.close();
}
#SuppressWarnings("unchecked")
public void loadFromSerialized(String filename) throws IOException,
ClassNotFoundException {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream is = new ObjectInputStream(fis);
listSites = (ArrayList<Site>) is.readObject();
is.close();
}
}
So, how do I get the information to show up in JTable?
Maybe I'm misinterpreting your code, but I don't see where you areextracting the information that the user enters into the dialog. For example here:
if (newRv.isOk()) {
String nameReserving = nameReservingTxt.getText();
String checkIn = dateInTxt.getText();
int daysStaying = Integer.parseInt(daysStayingTxt.getText());
String checkOutOn = checkOutOnTxt.getText();
int siteNumber = Integer.parseInt(siteNumberTxt.getText());
int power = Integer.parseInt(powerTxt.getText());
RV rv = new RV (nameReserving, checkIn, daysStaying, checkOutOn, siteNumber, power);
model.add(rv);
}
You appear to be extracting information from the fields held by the GUICampingReg, not by the newRv object. Shouldn't you be calling methods of newRv to extract the data needed to create your RV object?
for example,
if (newRv.isOk()) {
String nameReserving = newRv.getName();
String checkIn = newRv.getDateIn();
// .... etc
RV rv = new RV (nameReserving, checkIn, daysStaying, checkOutOn, siteNumber, power);
model.add(rv);
}
I just wanted to double check my implementation for using a SwingWorker thread is done the correct and clean way. Also, just need verification my implementation of the model-view-controller pattern is correct and clean as well. Everything seems to be working as it should and it seems a nice simple implementation to me.
The Model class.
package Model;
public class Model
{
private int counter;
private boolean go = true;
public Void go()
{
counter = 0;
while(go)
{
counter++;
System.out.println(counter);
}
return null;
}
public int getCounter()
{
return counter;
}
public String getCounterToString()
{
return Integer.toString(counter);
}
public void setGo(boolean value)
{
this.go = value;
}
}
The View class.
package View;
import java.awt.*;
import javax.swing.*;
public class View extends JFrame
{
private JPanel topPanel, bottomPanel;
private JTextArea messageArea;
private JButton startButton, cancelButton;
private JLabel messageLabel;
private JScrollPane scrollPane;
public View()
{
setSize(250, 220);
setTitle("View");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
topPanel = new JPanel();
bottomPanel = new JPanel();
messageArea = new JTextArea(8, 20);
messageArea.setEditable(true);
scrollPane = new JScrollPane(messageArea);
messageLabel = new JLabel("Message Area");
topPanel.setLayout(new BorderLayout());
topPanel.add(messageLabel, "North");
topPanel.add(scrollPane, "South");
startButton = new JButton("START");
cancelButton = new JButton("CANCEL");
bottomPanel.setLayout(new GridLayout(1, 2));
bottomPanel.add(startButton);
bottomPanel.add(cancelButton);
Container cp = getContentPane();
cp.add(topPanel, BorderLayout.NORTH);
cp.add(bottomPanel, BorderLayout.SOUTH);
}
public JButton getStartButton()
{
return startButton;
}
public JButton getCancelButton()
{
return cancelButton;
}
public void setMessageArea(String message)
{
messageArea.append(message + "\n");
}
}
The Controller class.
package Controller;
import java.awt.event.*;
import javax.swing.SwingWorker;
import Model.*;
import View.*;
public class Controller implements ActionListener
{
private Model theModel;
private View theView;
private SwingWorker<Void, Void> worker;
public Controller(Model model, View view)
{
this.theModel = model;
this.theView = view;
view.getStartButton().addActionListener(this);
view.getCancelButton().addActionListener(this);
}
public void actionPerformed(ActionEvent ae)
{
Object buttonClicked = ae.getSource();
if(buttonClicked.equals(theView.getStartButton()))
{
theModel.setGo(true);
worker = new SwingWorker<Void, Void>()
{
#Override
protected Void doInBackground()
{
//theView.setMessageArea(theModel.getCounterToString());
return theModel.go();
}
#Override
protected void done()
{
//theView.setMessageArea(theModel.getCounterToString());
}
};
worker.execute();
}
else if(buttonClicked.equals(theView.getCancelButton()))
{
theModel.setGo(false);
}
}
}
The Main class.
package swinginfiniteloop;
import Model.*;
import View.*;
import Controller.*;
public class Main
{
public static void main(String[] args)
{
Model model = new Model();
View view = new View();
Controller controller = new Controller(model, view);
view.setVisible(true);
}
}