0

I'm trying to update a JTable that pulls in data from an ArrayList. I have two frames in my program. The first frame is a JTable (AbstractTableModel) that displays the contents of the ArrayList. I click the "New" button on that frame to bring up the second window, which lets me add to the aforementioned ArrayList. When I click my "Save" button, the second window closes and the first is supposed to refresh with the new row. I don't have any syntactical errors in my code, and it looks conceptually right. I think the first place to start troubleshooting would be in the NoteCntl class. I'm under the impression that getNoteTableUI() should update the view with the new data when it's called, but I'm stumped as to what's going on. I'm new to the concept of Model View Controller, but I'd like to follow that as closely as possible.

Here is the Controller class:

public class NoteCntl {

private NoteTableModel theNoteTableModel = new NoteTableModel();;
private NoteTableUI theNoteTableUI;
private NoteDetailUI theNoteDetailUI;

public NoteCntl(){
    theNoteTableUI = new NoteTableUI(this);
}

public NoteTableModel getNoteTableModel(){
    return theNoteTableModel;
}

public void getNoteDetailUI(Note theNote){
    if (theNoteDetailUI == null || theNote == null){
        theNoteDetailUI = new NoteDetailUI(this,theNote);
    }
    else{
        theNoteDetailUI.setVisible(true);
    }
}

public NoteTableUI getNoteTableUI(){
    theNoteTableModel.fireTableDataChanged();   //why doesn't this do anything?
    theNoteTableUI.setVisible(true);
    return theNoteTableUI;
}

public void deleteNote(int noteToDelete){
    theNoteTableModel.removeRow(noteToDelete);
}

}

The First UI (Table):

public class NoteTableUI extends JFrame{

NoteTableModel noteModel;
NoteCntl theNoteCntl;
JPanel buttonPanel;
JPanel tablePanel;
JTable theNoteTable;
JScrollPane theScrollPane;
JButton backButton;
JButton deleteButton;
JButton editButton;
JButton newButton;


public NoteTableUI(NoteCntl theParentNoteCntl){
    theNoteCntl = theParentNoteCntl;
    this.initComponents();
    this.setSize(400, 500);
    this.setLocationRelativeTo(null);
    this.setTitle("NoteTableUI");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
}

public void initComponents(){
    buttonPanel = new JPanel();
    tablePanel = new JPanel();
    backButton = new JButton("Back");
    newButton = new JButton("New");
    newButton.addActionListener(new newButtonListener());

    editButton = new JButton("Edit");
    deleteButton = new JButton("Delete");
    deleteButton.addActionListener(new deleteButtonListener());
    noteModel = theNoteCntl.getNoteTableModel();
    theNoteTable = new JTable(theNoteCntl.getNoteTableModel());
    theScrollPane = new JScrollPane(theNoteTable);
    theNoteTable.setFillsViewportHeight(true);
    tablePanel.add(theScrollPane);

    buttonPanel.add(backButton);
    buttonPanel.add(deleteButton);
    buttonPanel.add(editButton);
    buttonPanel.add(newButton);

    this.getContentPane().add(buttonPanel, BorderLayout.NORTH);
    this.getContentPane().add(tablePanel, BorderLayout.CENTER);
}

public class deleteButtonListener implements ActionListener{
    public void actionPerformed(ActionEvent event){
        int selectedRow = theNoteTable.getSelectedRow();
        if (selectedRow == -1){
            System.out.println("No row selected");
        }
        else{
            noteModel.removeRow(selectedRow);
        }
        revalidate();
        repaint();
    }
}

public class newButtonListener implements ActionListener{
    public void actionPerformed(ActionEvent event){
        NoteTableUI.this.setVisible(false);
        NoteTableUI.this.theNoteCntl.getNoteDetailUI(null);
        /*
        NoteDetailCntl theNoteDetailCntl = new NoteDetailCntl();
        lastRow++;
        long newRow = lastRow;
        noteModel.addRow(newRow, 0, "", "");
        revalidate();
        repaint();
        */
    }
}

The 2nd UI (Detail editor) public class NoteDetailUI extends JFrame{

private final int FRAME_WIDTH = 700;
private final int FRAME_HEIGHT = 500;
private final int FIELD_WIDTH = 10;

JButton saveButton;
JButton backButton;
JTextField idField;
JTextField dateField;
JTextField nameField;
JTextField descriptionField;
JTextArea noteDetail;
JLabel idLabel;
JLabel dateLabel;
JLabel nameLabel;
JLabel descriptionLabel;
JPanel buttonPanel;
JPanel textFieldPanel;
JPanel textAreaPanel;
JPanel mainPanel;

NoteTableModel theNoteTableModel;
NoteDetailCntl theNoteDetailCntl;

NoteCntl theNoteCntl;
Note theCurrentNote;

public NoteDetailUI(){
    this.initComponents();
    this.setSize(FRAME_WIDTH,FRAME_HEIGHT);
    this.setLocationRelativeTo(null);
    this.setTitle("NoteDetailUI");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
}

public NoteDetailUI(NoteCntl parentNoteCntl, Note theSelectedNote){
    theNoteCntl = parentNoteCntl;
    theCurrentNote = theSelectedNote;
    this.initComponents();
    this.setSize(400,500);
    this.setLocationRelativeTo(null);
    this.setTitle("Note");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
}

public void initComponents(){
    saveButton = new JButton("Save");
    saveButton.addActionListener(new saveButtonListener());        
    backButton = new JButton("Back");
    backButton.addActionListener(new backButtonListener());

    idField = new JTextField(FIELD_WIDTH);

    theNoteTableModel = new NoteTableModel();

    idField.setText("10");
    idField.setEditable(false);
    dateField = new JTextField(FIELD_WIDTH);
    dateField.setText("20131108");
    nameField = new JTextField(FIELD_WIDTH);
    nameField.setText("Untitled");
    descriptionField = new JTextField(FIELD_WIDTH);
    descriptionField.setText("not described");

    idLabel = new JLabel("ID");
    dateLabel = new JLabel("Date");
    nameLabel = new JLabel("Name");
    descriptionLabel = new JLabel("Description");

    noteDetail = new JTextArea(25,60);

    buttonPanel = new JPanel();
    textFieldPanel = new JPanel();
    textAreaPanel = new JPanel();
    mainPanel = new JPanel(new BorderLayout());

    buttonPanel.add(backButton);
    buttonPanel.add(saveButton);
    textFieldPanel.add(idLabel);
    textFieldPanel.add(idField);
    textFieldPanel.add(dateLabel);
    textFieldPanel.add(dateField);
    textFieldPanel.add(nameLabel);
    textFieldPanel.add(nameField);
    textFieldPanel.add(descriptionLabel);
    textFieldPanel.add(descriptionField);
    textAreaPanel.add(noteDetail);
    mainPanel.add(buttonPanel, BorderLayout.SOUTH);
    mainPanel.add(textFieldPanel, BorderLayout.NORTH);
    mainPanel.add(textAreaPanel, BorderLayout.CENTER);

    add(mainPanel);

}

public ArrayList<String> getNoteDetails(){
    ArrayList<String> newData = new ArrayList<String>();
    newData.add(idField.getText());
    newData.add(dateField.getText());
    newData.add(nameField.getText());
    newData.add(descriptionField.getText());
    return newData;
}

public class saveButtonListener implements ActionListener{
    public void actionPerformed(ActionEvent event){
        /*
         * Access the noteTableData array in NoteTableModel
         * Add the newData fields in order
         */
        if(theCurrentNote == null){
            int newNoteNumber = Integer.parseInt(NoteDetailUI.this.idField.getText());
            int newNoteDate = Integer.parseInt(NoteDetailUI.this.dateField.getText());
            String newNoteName = NoteDetailUI.this.nameField.getText();
            String newNoteDescription = NoteDetailUI.this.descriptionField.getText();

            NoteDetailUI.this.theCurrentNote = new EssayNote(newNoteNumber,newNoteDate,newNoteName,newNoteDescription);
            NoteDetailUI.this.setVisible(false);
            NoteDetailUI.this.dispose();
            NoteDetailUI.this.theNoteCntl.getNoteTableUI();
        }
        else{
            //if it's a current Note
        }
        //Refresh the JTable

    }
}

public class backButtonListener implements ActionListener{
    public void actionPerformed(ActionEvent event){

    }
}

Thanks for all the help. I can provide the other classes if you want to just run the program and see what's happening, but I suspect it's either a problem with the fireTableDataChanged() call in the controller class or a problem with updating the contents of the ArrayList in the SaveButtonListener.

Shwheelz
  • 545
  • 3
  • 8
  • 22
  • `I'm new to the concept of Model View Controller, but I'd like to follow that as closely as possible` - You don't do anything special. Swing components are already designed along this concept. The "Model" is the TableModel. The "View and Controller" is the JTable. When you want to change the data you just update the TableModel and it will tell the JTable to repaint itself. – camickr Nov 09 '13 at 04:12
  • 1
    I would suggest you look at the Swing tutorial on [How to Use Lists](http://docs.oracle.com/javase/tutorial/uiswing/components/list.html) for a simple example of how to update a model. The "Hire" and "Fire" buttons show you the simple code. Your design is far too complex, just keep all the code in one class. When you display a new dialog to gather the information from the table you then just take the data from the dialog and invoke the addRow(...) method of your TableModel (assuming you have an addRow() method). – camickr Nov 09 '13 at 04:15
  • I added a line to the Save button to attempt to add it again... theNoteTableModel.addRow(newNoteNumber, newNoteDate, newNoteName, newNoteDescription); I then invoked revalidate() and repaint() in getNoteTableUI() to try to refresh the table, but still nothing. – Shwheelz Nov 09 '13 at 05:08
  • Did you look at the tutorial? Does the tutorial invoke revalidate() and repaint()? No it doesn't so I'm not sure why you are doing it. As I said you design is too complex with all the classes you have defined and I can't follow your logic. I suggest (once again) you read the tutorial and simplify your code. – camickr Nov 09 '13 at 05:59

0 Answers0