Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jtable update selected row

Tags:

java

swing

jtable

I have a jtable that has a edit button, when i select a row and clicked to edit button and edit fields, and click to save button, that row doesn't update, And i have to refresh my table to Change that row!

My code:

        if (e.getSource() == editButton) {
        selectedRow = uTable.getSelectedRow();
        if (selectedRow >= 0) {
            editUser(selectedRow);
        } else {
            JOptionPane.showMessageDialog(null, "Select a row");
        }
    }

    public void editUser(int row) {
    UserInformation userInf = userModel.getSelectedMember(row);
    NewUserFrame_Edit edit = new NewUserFrame_Edit(userInf, row);
}

...

My NewUserFrame_Edit Class :

public class NewUserFrame_Edit extends javax.swing.JFrame {

private AllUser userModel;
private int selectedrow;
private String gender;

public NewUserFrame_Edit(AllUser userModel,UserInformation userinf, int row) {
...
this.userModel = userModel;
    jTextField1.setText(userinf.getFname().toString().trim());
    jTextField2.setText(userinf.getLname().toString().trim());

    if (userinf.getGender().equals("Male")) {
        jRadioButton1.setSelected(true);
    } else {
        jRadioButton2.setSelected(true);
    }

    jTextField3.setText(userinf.getDate());
    selectedrow = row;
    setVisible(true);
}

private void updateButtonActionPerformed(java.awt.event.ActionEvent evt) {     
    userinf = new UserInformation();

    userinf.setFname(jTextField1.getText());
    userinf.setLname(jTextField2.getText());
    userinf.setGender(gender);
    userinf.setDate(jTextField3.getText());

    userModel.setValueAt(userinf.getFname() , selectedrow, 1);
    userModel.setValueAt(userinf.getLname() , selectedrow, 2);
    userModel.setValueAt(userinf.getGender(), selectedrow , 3);
    userModel.setValueAt(userinf.getDate() , selectedrow, 4);
    userModel.updateFile(userModel.Udata);

    NewUserFrame_Edit.this.dispose();
}
...
}

My setValueAt() and updateFile() methods of my model Class:

public class AllUser extends AbstractTableModel {
...
    @Override
public void setValueAt(Object value, int rowIndex, int columnIndex) {
    UserInformation userInfo = Udata.get(rowIndex);
    switch (columnIndex) {
        case 0:
            userInfo.setID((String) value);
            break;
        case 1:
            userInfo.setFname((String) value);
            break;
        case 2:
            userInfo.setLname((String) value);
            break;
        case 3:
            userInfo.setGender((String) value);
            break;
        case 4:
            userInfo.setDate((String) value);
            break;
    }
    fireTableCellUpdated(rowIndex, columnIndex);
}

    public void updateFile(ArrayList<UserInformation> data) {
    PrintWriter pw;
    try {
        pw = new PrintWriter(new FileWriter("AllUserRecords.txt"));
        for (UserInformation userinf : data) {
            String line = userinf.getID()
                    + "     " + userinf.getFname()
                    + "     " + userinf.getLname()
                    + "     " + userinf.getGender()
                    + "     " + userinf.getDate();

            pw.println(line);
        }
        pw.close();
    } catch (IOException ioe) {
    }
}
...
}

When i select a row and click to edit button, a new jframe is open that its text field is fill with older data, and i update data and click to save button. Thus, my column is not certain. I select a entire row, Not a cell!

Thanks.

like image 778
Sajad Avatar asked Mar 21 '13 18:03

Sajad


People also ask

How can I tell if a row is selected in JTable?

So you can call table. getSelectionModel(). isSelectionEmpty() to find out if any row is selected.


2 Answers

For changing JTable entries, use TableModel#setValueAt. Calling fireTableDataChanged is unnecessary. This is for use internally within TableModel itself.

if (selectedRow >= 0) {
    ...
    userModel.setValueAt(newValue, selectedRow, 0);
     //        ...   more values for columns    1, 2, 3, etc.
} ...
like image 138
Reimeus Avatar answered Oct 14 '22 07:10

Reimeus


You can create a method called updateRow(int index,String[] values) within your AbstractModel extending class and within it set new Value for each cell for that row using setValueAt(newValue,row,index). And within overridden setValue method of TableModel write fireTableCellUpdated(row, col).

Consider the Code Given below. Look at the updateRow and setValueAt method in MyModel class. And watch ((MyModel)myModel).updateRow(row,values);//update row written in MyMouseAdapter class.

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.table.*;

class TableRowEdit extends JFrame  
{
    private JTable table;
    private JScrollPane jsPane;
    private TableModel myModel;
    private JPanel dialogPanel;
    private JTextField tf[];
    private JLabel     lbl[];
    public void prepareAndShowGUI()
    {
        myModel = new MyModel();
        table = new JTable(myModel);
        jsPane = new JScrollPane(table);
        table.getColumnModel().getColumn(2).setCellRenderer(new LabelCellRenderer());
        table.addMouseListener(new MyMouseAdapter());
        getContentPane().add(jsPane);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        prepareDialogPanel();
        pack();
        setVisible(true);

    }
    private void prepareDialogPanel()
    {
        dialogPanel = new JPanel();
        int col = table.getColumnCount() - 1;
        dialogPanel.setLayout(new GridLayout(col,2));
        tf = new JTextField[col];
        lbl = new JLabel[col];
        for (int i = 0; i < col; i++)
        {
            lbl[i] = new JLabel(table.getColumnName(i));
            tf[i] = new JTextField(10);
            dialogPanel.add(lbl[i]);
            dialogPanel.add(tf[i]);
        }
    }
    private void populateTextField(String[] s)
    {
        for (int i = 0 ; i < s.length ; i++ )
        {
            tf[i].setText(s[i]);
        }
    }
    public class LabelCellRenderer extends DefaultTableCellRenderer 
    {
        public Component getTableCellRendererComponent(JTable table,Object oValue, boolean isSelected, boolean hasFocus, int row, int column) 
        {
            Component c = super.getTableCellRendererComponent(table, oValue,isSelected, hasFocus,row, column);
            String value = (String)oValue;
            JLabel label =(JLabel)c;
            label.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
            label.setBackground(Color.lightGray);
            label.setHorizontalTextPosition(SwingUtilities.CENTER);
            label.setHorizontalAlignment(SwingUtilities.CENTER);
            label.setText(value);
            return label;
        }
    }

    private class MyMouseAdapter extends MouseAdapter
    {
        @Override
        public void mousePressed(MouseEvent evt)
        {
            int x = evt.getX();
            int y = evt.getY();
            int row = table.rowAtPoint(new Point(x,y));
            int col = table.columnAtPoint(new Point(x,y));
            if (col == 2)
            {
                String arr[] = new String[table.getColumnCount() - 1];
                for (int i = 0 ; i < arr.length ; i++)
                {
                    arr[i] = (String)table.getValueAt(row,i);
                }
                populateTextField(arr);
                JOptionPane.showMessageDialog(TableRowEdit.this,dialogPanel,"Information",JOptionPane.INFORMATION_MESSAGE);
                String[] values = new String[tf.length];
                for (int i = 0 ; i < tf.length ; i++)
                {
                    values[i] = tf[i].getText();
                }
                ((MyModel)myModel).updateRow(row,values);//update row 
            }
        }
    }
    private class MyModel extends AbstractTableModel 
    {
        String[] columns = {
                            "Roll No.",
                            "Name",
                            "Action"
                            };
        String[][] inData = {
                                {"1","Anthony Hopkins","Edit"},
                                {"2","James William","Edit"},
                                {"3","Mc. Donald","Edit"}
                            };
        @Override
        public void setValueAt(Object value, int row, int col)
        {
            inData[row][col] = (String)value;
            fireTableCellUpdated(row,col);
        }
        @Override
        public Object getValueAt(int row, int col)
        {
            return inData[row][col];
        }
        @Override
        public int getColumnCount()
        {
            return columns.length;
        }
        @Override 
        public int getRowCount()
        {
            return inData.length;
        }
        @Override
        public String getColumnName(int col)
        {
            return columns[col];
        }
        @Override
        public boolean isCellEditable(int row ,int col)
        {
            return true;
        }
        //This method updates the Row of table
        public void updateRow(int index,String[] values)
        {
            for (int i = 0 ; i < values.length ; i++)
            {
                setValueAt(values[i],index,i);
            }
        }
    }
    public static void main(String st[])
    {
        SwingUtilities.invokeLater( new Runnable()
        {
            @Override
            public void run()
            {
                TableRowEdit td = new TableRowEdit();
                td.prepareAndShowGUI();
            }
        });
    }
}

UPDATE
Everything was fine with your original code. Keep the code as it was initially. The only problem was line userModel = new AllUser(); in method updateButtonActionPerformed. It was creating new object of AllUser instead of using the current one. So you should remove this line from updateButtonActionPerformed . and change the NewUserFrame_Edit constructor as follows:

public NewUserFrame_Edit(AllUser userModel/*Add this parameter*/,UserInformation userinf, int row) {
...
    this.userModel = userModel;
    jTextField1.setText(userinf.getFname().toString().trim());
    jTextField2.setText(userinf.getLname().toString().trim());

    if (userinf.getGender().equals("Male")) {
        jRadioButton1.setSelected(true);
    } else {
        jRadioButton2.setSelected(true);
    }

    jTextField3.setText(userinf.getDate());
    selectedrow = row;
    setVisible(true);
}

change your as updateButtonActionPerformed follows:

private void updateButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
    //userModel = new AllUser();//Comment it.
    userinf = new UserInformation();

    userinf.setFname(jTextField1.getText());
    userinf.setLname(jTextField2.getText());
    userinf.setGender(gender);
    userinf.setDate(jTextField3.getText());

    userModel.setValueAt(userinf.getFname() , selectedrow, 1);
    userModel.setValueAt(userinf.getLname() , selectedrow, 2);
    userModel.setValueAt(userinf.getGender(), selectedrow , 3);
    userModel.setValueAt(userinf.getDate() , selectedrow, 4);
    userModel.updateFile(userModel.Udata);

    NewUserFrame_Edit.this.dispose();
}

And changeeditUser(int row) method of class UserPage as follows:

public void editUser(int row)
{
    UserInformation userInf = userModel.getSelectedMember(row);
    NewUserFrame_Edit edit = new NewUserFrame_Edit(userModel,userInf, row);
}

Here is your updateFile methd:

public void updateFile(ArrayList<UserInformation> data) {
    PrintWriter pw;
    try {
        pw = new PrintWriter(new FileWriter("AllUserRecords.txt"));
        for (UserInformation userinf : data) {
            String line = userinf.getID()
                    + "     " + userinf.getFname()
                    + "     " + userinf.getLname()
                    + "     " + userinf.getGender()
                    + "     " + userinf.getDate();

            pw.println(line);
        }
        pw.close();
    } catch (IOException ioe) {
    }
}
like image 43
Vishal K Avatar answered Oct 14 '22 06:10

Vishal K