Search code examples
javaswingjtablemouseeventabstracttablemodel

Edit User information by jtable


I have a jtable that show a text file contain on own. Each line in text file is a user record. I add a edit button to edit each selected row on table. I use this code, But i don't understand how to do this:

public class AllUser extends AbstractTableModel {

UserInformation uiS = new UserInformation();
String[] col = {"ID", "Fname", "Lname", "Gender", "Date"};
List<UserInformation> Udata = new ArrayList<UserInformation>();

public AllUser() {
BufferedReader br = null;
    try {
        FileReader fr = new FileReader("xxx.txt");
        br = new BufferedReader(fr);
        String line;
        while ((line = br.readLine()) != null) {
            if (line.trim().length() == 0) {
                continue;
            }
            Udata.add(initializeUserInfos(line));
        }
    } catch (IOException e) {
    } finally {
        if (br != null) {
            try {
                br.close();
            } catch (IOException ioe) {
            }
        }
    }
}

private UserInformation initializeUserInfos(String str) {
    UserInformation Uinit = new UserInformation();
    String[] CellArray = str.split("     ");
    Uinit.setID(CellArray[0]);
    Uinit.setFname(CellArray[1]);
    Uinit.setLname(CellArray[2]);
    Uinit.setGender(CellArray[3]);
    Uinit.setDate(CellArray[4]);
    return Uinit;
}
@Override
public String getColumnName(int colu) {
    return col[colu];
}

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

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

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    UserInformation uinfoS = Udata.get(rowIndex);
    Object value = null;
    switch (columnIndex) {
        case 0:
            value = uinfoS.getID();
            break;
        case 1:
            value = uinfoS.getFname();
            break;
        case 2:
            value = uinfoS.getLname();
            break;
        case 3:
            value = uinfoS.getGender();
            break;
        case 4:
            value = uinfoS.getDate();
            break;
        default:
            value = "...";
    }
    return value;
}

@Override
public void setValueAt(Object value, int rowIndex, int columnIndex) {
    UserInformation userInfo = new UserInformation();

    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;
    }

}

public Object getSelectedMember(int row){
    UserInformation userInf=new UserInformation();

    Object fname=userInf.getFname();
    Object lname=userInf.getLname();
    Object gender=userInf.getGender();
    Object date=userInf.getDate();
    return // ?

}
}

I add This getSelectedMember(int row) method to do this, But incorrect!

public class UserPage extends JFrame implements ActionListener {

private AllUser userModel;
private JTable uTable;
private JButton editButton;

public UserPage() {
    userModel = new AllUser();
    uTable = new JTable(userModel);
    add(new JScrollPane(uTable), BorderLayout.CENTER);
    add(buttonPanels(), BorderLayout.PAGE_START);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(800, 600);
}
public final JPanel buttonPanels() {
    JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    editButton=new JButton("Edit");
    editButton.addActionListener(this);
    buttonsPanel.add(editButton);
    return buttonsPanel;
}
@Override
public void actionPerformed(ActionEvent e) {
        if(e.getSource()== editButton){
        int selectedRow=uTable.getSelectedRow();
        if(selectedRow>0){
            editUser(selectedRow);
        }
        else{
            JOptionPane.showMessageDialog(null, "Select a user");
        }

    }
}
    public void editUser(int row){
    userModel.getSelectedMember(row);
    new NewUserFrame_Edit().setVisible(true);  
}
}

UserInformation Class:

public class UserInformation {

private String Fname;
private String Lname;
private String ID;
private String Gender;
private String Date;

public String getFname() {
    return Fname;
}

public void setFname(String fname) {
    this.Fname = fname;
}

public String getLname() {
    return Lname;
}

public void setLname(String lname) {
    this.Lname = lname;
}

public String getID() {
    return ID;
}

public void setID(String i_d) {
    this.ID = i_d;
}

public String getGender() {
    return Gender;
}

public void setGender(String gndr) {
    this.Gender = gndr;
}

public String getDate() {
    return Date;
}

public void setDate(String date) {
    this.Date = date;
}

@Override
public String toString() {
    return ID + "     " + Fname + "     "
            + Lname + "     " + Gender + "     " + Date + "\n";
}
}

Sorry for long code.


Solution

  • Create an extra column in table and fill the cell value with Edit. Then render the Edit cell with appropriate TableCellRenderer . Add MouseListener to table. Get the row and column number of the cell clicked on table. If the cell clicked contains value Edit , retrieve value at each column of that row and display it in a Panel containing JTextFields . Show that Panel using JOptionpane or in a JDialog. Here is the brief code demo for achieving this task:

    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import java.awt.Component;
    import java.awt.Color;
    import java.awt.Point;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseAdapter;
    import java.awt.Cursor;
    import javax.swing.BorderFactory;
    import javax.swing.border.BevelBorder;
    import javax.swing.JFrame;
    import javax.swing.JTable;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.JButton;
    import javax.swing.JScrollPane;
    import javax.swing.JOptionPane;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
    import javax.swing.event.TableModelListener;
    import javax.swing.event.TableModelEvent;
    import javax.swing.table.TableModel;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableColumn;
    import javax.swing.table.DefaultTableCellRenderer;
    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);
                    //Write here the code to save changed values to file and update to JTable also.
                }
            }
        }
        private class MyModel extends AbstractTableModel 
        {
            String[] columns = {
                                "Roll No.",
                                "Name",
                                "Action"
                                };
            String[][] inData = {
                                    {"1","Huge Jackman","Edit"},
                                    {"2","Thomas Andrews","Edit"},
                                    {"3","Shiney","Edit"}
                                };
            @Override
            public void setValueAt(Object value, int row, int col)
            {
                inData[row][col] = (String)value;
            }
            @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];
            }
        }
        public static void main(String st[])
        {
            SwingUtilities.invokeLater( new Runnable()
            {
                @Override
                public void run()
                {
                    TableRowEdit td = new TableRowEdit();
                    td.prepareAndShowGUI();
                }
            });
        }
    }