Heeiman
Heeiman

Reputation: 269

How to add data to JTable from textField value saved in an ArrayList?

I am currently trying to write a program (using the MVC method) that takes values from textFields, saves these values in an ArrayList and finally shows those values in a JTable by pressing a button.

I recently got pointed in the right direction by @camickr in an earlier question of mine. Well, I've now tried to follow his sage advice and do believe I have made some progress. However, I fail to understand what to do when evil buttons are added to the process.

I've tried this How to add row of data to Jtable from values received from jtextfield and comboboxes but if I try to do that in my View, the add method doesn't work.

Please help me OverflowKenobi, you're my only hope.

My code:

My model according to the MVC-method.

package org.lu.ics.inlämningsuppgifter;

import javax.swing.JTable;
import javax.swing.table.AbstractTableModel; 
import java.util.*; 
import javax.swing.table.DefaultTableModel;

public class PersonTableModel extends AbstractTableModel {

private String[] columnNames = {"Account holder", "Account number"};
private ArrayList<Person> persons;

JTable tbl = new JTable();
DefaultTableModel tableModel = new DefaultTableModel(columnNames, 2);


public PersonTableModel() {
    super();
    persons = new ArrayList<Person>();
}

public PersonTableModel(ArrayList<Person> persons) {
    this.persons = persons;
}

@Override
public int getColumnCount() {
    return columnNames.length;
}

@Override
public String getColumnName(int column) {
    return columnNames[column];
}

@Override
public int getRowCount() {
    return persons.size();
}

@Override
public Class getColumnClass(int column) {
    switch (column) {
    case 2: return ArrayList.class;
    default: return String.class;
    }
}

@Override
public boolean isCellEditable(int row, int column) {
    switch (column) {
    case 2: return true;
    default: return false;
    }
}

@Override
public Object getValueAt(int row, int column) {
    Person person = this.persons.get(row);

    switch (column) {
    case 0: return person.getName();
    case 1: return person.getPNbr();
    case 2: return person.getAccounts();
    default: return null;
    }
}

@Override
public void setValueAt(Object value, int row, int column) {
    Person person = getPerson(row);

    switch (column) {
    case 0: person.setName((String)value); break;
    case 1: person.setPNbr((String)value); break;
    case 2: person.setAccounts((ArrayList)value); break;
    }

    fireTableCellUpdated(row, column);
}

public Person getPerson(int row) {
    return persons.get(row);
}

public void addPerson(Person person) {
    insertPerson(getRowCount (), person);
}

public void insertPerson(int row, Person person) {
    persons.add(row, person);
    fireTableRowsInserted(row, row);
}

public void removePerson(int row) {
    persons.remove(row);
    fireTableRowsDeleted(row, row);
}       

public ArrayList<Person> getPersoner() {
    return persons;
}

public void setPersons(ArrayList<Person> newPersons) {
    persons = newPersons;
}


public Person findPerson(String pNbr) {
    for (Person p : this.persons) {
        if (p.getPNbr().equals(pNbr)) {
            return p;
        }
    }
    return null;
}

public Person removePerson(String pNbr) {
    Person p = findPerson(pNbr);
    if (p != null) {
        persons.remove(p);
    }
    return null;
}
public void setPersonName(String pNbr, String newName) {
    Person p = this.findPerson(pNbr);
    if (p != null) {
        p.setName(newName);
    }
}
}

My Controller

package org.lu.ics.inlämningsuppgifter;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;

public class Controller  {
private PersonTableModel persons;
private JFrame frame;

public Controller (PersonTableModel persons, JFrame frame) {
    this.persons=persons;
    this.frame=frame;
}

public void addPerson (String pNbr, String pName) {
    Person tmpPerson = new Person(pNbr, pName);
    persons.addPerson(tmpPerson);
}

public void addPersonAccount (String pNbr, String pName, String accNbr) {
    Person tmpPerson = new Person(pNbr, pName);
    Account account = new Account(accNbr);
    tmpPerson.addAccount(account);
    account.setOwner(tmpPerson);
    persons.addPerson(tmpPerson);

}

 public void removePerson(String pRemove) {
 persons.removePerson(pRemove);
 }

public String[] findPerson(String pNbrFind) {
     Person p;
     String[] aPerson = null;
     p = persons.findPerson(pNbrFind);
     if (p != null && p.getAccounts() != null) {
     aPerson = new String[4];
     aPerson[0] = p.getPNbr();
     aPerson[1] = p.getName();
     } else if (p != null) {
     aPerson = new String[2];
     aPerson[0] = p.getPNbr();
     aPerson[1] = p.getName();
     }
     return aPerson;
}

 public void updatePersonName(String pNbr, String newPName) {
 persons.setPersonName(pNbr, newPName);
 }


}

My View

package org.lu.ics.inlämningsuppgifter;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import java.awt.Font;
import javax.swing.JPanel;
import javax.swing.table.DefaultTableModel;

public class PersonApplication {

private JFrame frame;
private JTextField textField_Name;
private JTextField textField_pNbr;
private JTable table;
private JTextField textField_AccNbr;
private JTextField textField_3;
private JButton btnAddPerson;
private JButton btnRemovePerson;
private JLabel lblFullName;
private JLabel lblSocialSecurityNumber;
private JButton btnAddAccountTo;
private JSeparator separator;
private JSeparator separator_1;
private JLabel lblAccounts;
private JSeparator separator_2;
private JLabel lblWelcomeToAtm;
private JLabel lblPleaseEnterName;
private JLabel lblAccountNumber;
private JButton btnNewButton;
private JLabel lblAmount;
private JButton btnWithdraw;
private JButton btnCredit;
private JLabel lblIfNoPlease;
private JLabel lblAccountAdded;
private JLabel lblResponse_Person;
private JLabel lblResponse_Balance;
private JButton btnFindPerson;

private Controller controller;
private PersonTableModel personTable;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                PersonApplication window = new PersonApplication();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public PersonApplication() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 776, 561);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    btnAddPerson = new JButton("Add Person");
    btnAddPerson.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            String name = textField_Name.getName();
            //controller.addRow(textField_pNbr.getText());
            }
        }
    );
    btnAddPerson.setBounds(412, 114, 159, 23);
    frame.getContentPane().add(btnAddPerson);
    btnAddPerson = new JButton("Add New Person");


    frame.getContentPane().setLayout(null);
    frame.getContentPane().add(btnAddPerson);


    btnFindPerson = new JButton("Find Person");
    btnFindPerson.setBounds(412, 46, 159, 23);
    frame.getContentPane().add(btnFindPerson);

    btnRemovePerson = new JButton("Remove Person");
    btnRemovePerson.setBounds(412, 80, 159, 23);
    frame.getContentPane().add(btnRemovePerson);

    textField_Name = new JTextField();
    textField_Name.setBounds(179, 69, 142, 20);
    frame.getContentPane().add(textField_Name);
    textField_Name.setColumns(10);

    lblFullName = new JLabel("Full name:");
    lblFullName.setBounds(110, 72, 75, 14);
    frame.getContentPane().add(lblFullName);

    lblSocialSecurityNumber = new JLabel("Personal identity number:");
    lblSocialSecurityNumber.setBounds(21, 97, 149, 14);
    frame.getContentPane().add(lblSocialSecurityNumber);

    textField_pNbr = new JTextField();
    textField_pNbr.setBounds(179, 94, 142, 20);
    frame.getContentPane().add(textField_pNbr);
    textField_pNbr.setColumns(10);

    btnAddAccountTo = new JButton("Add New Account to Person");
    btnAddAccountTo.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
        }
    });
    btnAddAccountTo.setBounds(404, 216, 193, 23);
    frame.getContentPane().add(btnAddAccountTo);

    separator = new JSeparator();
    separator.setBounds(258, 157, 237, 2);
    frame.getContentPane().add(separator);

    separator_1 = new JSeparator();
    separator_1.setOrientation(SwingConstants.VERTICAL);
    separator_1.setBounds(382, 349, 41, 140);
    frame.getContentPane().add(separator_1);

    table = new JTable();
    table.setModel(new DefaultTableModel());
    table.getColumnModel().getColumn(1);

    table.getColumnModel().getColumn(0).setPreferredWidth(105);
    table.getColumnModel().getColumn(1).setPreferredWidth(107);
    table.setBounds(39, 349, 273, 151);
    frame.getContentPane().add(table);

    lblAccounts = new JLabel("ACCOUNT DISPLAY");
    lblAccounts.setFont(new Font("Tahoma", Font.BOLD, 12));
    lblAccounts.setBounds(123, 318, 132, 31);
    frame.getContentPane().add(lblAccounts);

    separator_2 = new JSeparator();
    separator_2.setBounds(258, 322, 237, 2);
    frame.getContentPane().add(separator_2);

    lblWelcomeToAtm = new JLabel("Welcome to ATM!");
    lblWelcomeToAtm.setFont(new Font("Arial", Font.ITALIC, 18));
    lblWelcomeToAtm.setBounds(309, 11, 186, 14);
    frame.getContentPane().add(lblWelcomeToAtm);

    lblPleaseEnterName = new JLabel("Please enter name and personal identity 
    number (obligatory).");
    lblPleaseEnterName.setFont(new Font("Tahoma", Font.ITALIC, 11));
    lblPleaseEnterName.setBounds(39, 44, 335, 14);
    frame.getContentPane().add(lblPleaseEnterName);

    textField_AccNbr = new JTextField();
    textField_AccNbr.setBounds(169, 217, 142, 20);
    frame.getContentPane().add(textField_AccNbr);
    textField_AccNbr.setColumns(10);

    lblAccountNumber = new JLabel("Account number:");
    lblAccountNumber.setBounds(58, 220, 112, 14);
    frame.getContentPane().add(lblAccountNumber);

    btnNewButton = new JButton("Show accounts");
    btnNewButton.setBounds(318, 289, 132, 23);
    frame.getContentPane().add(btnNewButton);

    textField_3 = new JTextField();
    textField_3.setBounds(474, 349, 199, 23);
    frame.getContentPane().add(textField_3);
    textField_3.setColumns(10);

    lblAmount = new JLabel("Amount:");
    lblAmount.setBounds(412, 349, 89, 20);
    frame.getContentPane().add(lblAmount);

    btnWithdraw = new JButton("Withdraw");
    btnWithdraw.setBounds(457, 393, 89, 23);
    frame.getContentPane().add(btnWithdraw);

    btnCredit = new JButton("Credit");
    btnCredit.setBounds(580, 393, 89, 23);
    frame.getContentPane().add(btnCredit);

    lblIfNoPlease = new JLabel("If you wish to make a new account, please 
    enter prefered account number and press \"Add New Account to Person\" to 
    proceed.");
    lblIfNoPlease.setFont(new Font("Tahoma", Font.ITALIC, 11));
    lblIfNoPlease.setBounds(39, 192, 656, 14);
    frame.getContentPane().add(lblIfNoPlease);

    lblAccountAdded = new JLabel("RESPONSE2");
    lblAccountAdded.setFont(new Font("Tahoma", Font.ITALIC, 11));
    lblAccountAdded.setBounds(636, 216, 79, 23);
    frame.getContentPane().add(lblAccountAdded);

    lblResponse_Person = new JLabel("RESPONSE1\r\n");
    lblResponse_Person.setFont(new Font("Tahoma", Font.ITALIC, 11));
    lblResponse_Person.setBounds(636, 84, 79, 19);
    frame.getContentPane().add(lblResponse_Person);

    lblResponse_Balance = new JLabel("RESPONSE3");
    lblResponse_Balance.setFont(new Font("Tahoma", Font.ITALIC, 11));
    lblResponse_Balance.setBounds(523, 439, 94, 25);
    frame.getContentPane().add(lblResponse_Balance);
}
}

My Person Class

package org.lu.ics.inlämningsuppgifter;

import java.util.*;

public class Person {

private String pNbr;
private String name;
private ArrayList<Account> accounts;

public Person(String pNbr, String pName) {
    this.setPNbr(pNbr);
    this.setName(pName);
    accounts = new ArrayList<Account>();
}

public ArrayList<Account> getAccounts() {
    return accounts;
}

public void setPNbr(String newPNbr) {
    pNbr = newPNbr;
}

public String getPNbr() {
    return pNbr;
}

public void setName(String newName) {
    this.name=newName;
}

public String getName() {
    return this.name;
}

public void setAccounts(ArrayList<Account> newAccounts) {
    accounts = newAccounts;
}

public void addAccount(Account anAccount) {
    this.getAccounts().add(anAccount);
}


}

My Account Class

package org.lu.ics.inlämningsuppgifter;

public class Account {

private String nbr;
private double balance; 
private Person owner;

public Person getOwner() {
    return owner;
}

public void setOwner(Person newOwner) {
    owner = newOwner;
}

public void setNbr(String newNbr) {
    nbr = newNbr;
}

public String getNbr() {
    return nbr;
}

public Account (String accNbr) {
    balance = 0.00;
    this.setNbr(accNbr);

}

public void setBalance(double newBalance) {
    balance = newBalance;
    this.setBalance(newBalance);

}

public double getBalance() {
    return balance;
}

public void credit(double amount) {
    balance = balance + amount;
}

public void withdraw(double amount) {
    balance = balance - amount;
}


}

Upvotes: 0

Views: 1948

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

Let's start with...

public class PersonTableModel extends AbstractTableModel {

    private String[] columnNames = {"Account holder", "Account number"};
    private ArrayList<Person> persons;

    JTable tbl = new JTable();
    DefaultTableModel tableModel = new DefaultTableModel(columnNames, 2);

It's pointless and a general violation of the MVC paradigm for the model to contain a view, besides, what's the point of creating yet ANOTHER TableModel inside a TableModel

Next, you never, ever, create an instance of the PersonTableModel anywhere in your code, so nothing's going to be interacting with that.

Based on your current code, there's actually no need for the controller, it's doing nothing of worth, which can't already be done directly through PersonTableModel. Remember, Swing is already a form of MVC, applying another MVC on top of it is just asking for duplication of code and additional work.

At this stage, I'd forget out about it and focus on understanding how to just update the table.

IMHO, your PersonApplication is doing to much. It should be focused on facilitating user functionality, so that the user can see the people (in the JTable) and can interact/manage the data. To me, this means providing some additional buttons which allow the user to add/remove/edit the values in the table, but whose functionality is managed by another class and made available to the user, where required via dialogs

When collecting new data from the user, that should be handled by another class, which returns information to the caller to be further processed (or if the user cancelled the operation, ignored).

I've thrown a very simple example together to show you how it "might" work (or at least will show you how the data is getting added)

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {
        private JTable table;
        private PersonTableModel model;

        public TestPane() {
            setLayout(new BorderLayout());
            model = new PersonTableModel();
            table = new JTable(model);
            add(new JScrollPane(table));

            JButton add = new JButton("Add");
            add.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // This is where you'd use a JDialog
                    // to prompt the user for the details
                    // they want to add.  It could return a new
                    // instance of Person based on the values
                    // the user has entered
                    model.addPerson(new Person("123456", "Banana"));
                }
            });
            add(add, BorderLayout.SOUTH);
        }

    }

    public class PersonTableModel extends AbstractTableModel {

        private String[] columnNames = {"Account holder", "Account number"};
        private ArrayList<Person> persons;

        public PersonTableModel() {
            super();
            persons = new ArrayList<Person>();
        }

        public PersonTableModel(ArrayList<Person> persons) {
            this.persons = persons;
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }

        @Override
        public int getRowCount() {
            return persons.size();
        }

        @Override
        public Class getColumnClass(int column) {
            switch (column) {
                case 2:
                    return ArrayList.class;
                default:
                    return String.class;
            }
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            switch (column) {
                case 2:
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public Object getValueAt(int row, int column) {
            Person person = this.persons.get(row);

            switch (column) {
                case 0:
                    return person.getName();
                case 1:
                    return person.getPNbr();
                case 2:
                    return person.getAccounts();
                default:
                    return null;
            }
        }

        @Override
        public void setValueAt(Object value, int row, int column) {
            Person person = getPerson(row);

            switch (column) {
                case 0:
                    person.setName((String) value);
                    break;
                case 1:
                    person.setPNbr((String) value);
                    break;
                case 2:
                    person.setAccounts((ArrayList) value);
                    break;
            }

            fireTableCellUpdated(row, column);
        }

        public Person getPerson(int row) {
            return persons.get(row);
        }

        public void addPerson(Person person) {
            insertPerson(getRowCount(), person);
        }

        public void insertPerson(int row, Person person) {
            persons.add(row, person);
            fireTableRowsInserted(row, row);
        }

        public void removePerson(int row) {
            persons.remove(row);
            fireTableRowsDeleted(row, row);
        }

        public ArrayList<Person> getPersoner() {
            return persons;
        }

        public void setPersons(ArrayList<Person> newPersons) {
            persons = newPersons;
        }

        public Person findPerson(String pNbr) {
            for (Person p : this.persons) {
                if (p.getPNbr().equals(pNbr)) {
                    return p;
                }
            }
            return null;
        }

        public Person removePerson(String pNbr) {
            Person p = findPerson(pNbr);
            if (p != null) {
                persons.remove(p);
            }
            return null;
        }

        public void setPersonName(String pNbr, String newName) {
            Person p = this.findPerson(pNbr);
            if (p != null) {
                p.setName(newName);
            }
        }
    }

    public class Account {

        private String nbr;
        private double balance;
        private Person owner;

        public Person getOwner() {
            return owner;
        }

        public void setOwner(Person newOwner) {
            owner = newOwner;
        }

        public void setNbr(String newNbr) {
            nbr = newNbr;
        }

        public String getNbr() {
            return nbr;
        }

        public Account(String accNbr) {
            balance = 0.00;
            this.setNbr(accNbr);

        }

        public void setBalance(double newBalance) {
            balance = newBalance;
            this.setBalance(newBalance);

        }

        public double getBalance() {
            return balance;
        }

        public void credit(double amount) {
            balance = balance + amount;
        }

        public void withdraw(double amount) {
            balance = balance - amount;
        }

    }

    public class Person {

        private String pNbr;
        private String name;
        private ArrayList<Account> accounts;

        public Person(String pNbr, String pName) {
            this.setPNbr(pNbr);
            this.setName(pName);
            accounts = new ArrayList<Account>();
        }

        public ArrayList<Account> getAccounts() {
            return accounts;
        }

        public void setPNbr(String newPNbr) {
            pNbr = newPNbr;
        }

        public String getPNbr() {
            return pNbr;
        }

        public void setName(String newName) {
            this.name = newName;
        }

        public String getName() {
            return this.name;
        }

        public void setAccounts(ArrayList<Account> newAccounts) {
            accounts = newAccounts;
        }

        public void addAccount(Account anAccount) {
            this.getAccounts().add(anAccount);
        }

    }
}

But I must use a MVC!

Again, Swing IS a MVC (of forms). Start by coming to grips with the basics, adding a MVC on top of Swing is not an easy task and requires a lot of understanding into how the API already works. You will need to have a better understanding of the delegate and observer patterns, just to name a couple

Upvotes: 3

Related Questions