简体   繁体   English

Jtable更新选定的行

[英]Jtable update selected row

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! 我有一个jtable有一个编辑按钮,当我选择一行并单击编辑按钮和编辑字段,然后单击保存按钮,该行不更新,我必须刷新我的表以更改该行!

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 : 我的NewUserFrame_Edit类:

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: 我的模型类的setValueAt()和updateFile()方法:

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. 当我选择一行并单击编辑按钮时,会打开一个新的jframe,其文本字段将填充旧数据,然后我更新数据并单击以保存按钮。 Thus, my column is not certain. 因此,我的专栏不确定。 I select a entire row, Not a cell! 我选择整行,而不是单元格!

Thanks. 谢谢。

For changing JTable entries, use TableModel#setValueAt . 要更改JTable条目,请使用TableModel#setValueAt Calling fireTableDataChanged is unnecessary. 不需要调用fireTableDataChanged This is for use internally within TableModel itself. 这是在TableModel本身内部使用的。

if (selectedRow >= 0) {
    ...
    userModel.setValueAt(newValue, selectedRow, 0);
     //        ...   more values for columns    1, 2, 3, etc.
} ...

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). 您可以在AbstractModel扩展类中创建一个名为updateRow(int index,String[] values)的方法updateRow(int index,String[] values)并在其中使用setValueAt(newValue,row,index)为该行的每个单元格设置新值。 And within overridden setValue method of TableModel write fireTableCellUpdated(row, col). 并且在重写的TableModel setValue方法中写入fireTableCellUpdated(row,col)。

Consider the Code Given below. 考虑下面给出的代码。 Look at the updateRow and setValueAt method in MyModel class. 查看MyModel类中的updateRowsetValueAt方法。 And watch ((MyModel)myModel).updateRow(row,values);//update row written in MyMouseAdapter class. 并观察((MyModel)myModel).updateRow(row,values);//update rowMyMouseAdapter类中编写的((MyModel)myModel).updateRow(row,values);//update row

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 UPDATE
Everything was fine with your original code. 您的原始代码一切都很好。 Keep the code as it was initially. 保持最初的代码。 The only problem was line userModel = new AllUser(); 唯一的问题是line userModel = new AllUser(); in method updateButtonActionPerformed . 在方法updateButtonActionPerformed It was creating new object of AllUser instead of using the current one. 它创建了AllUser新对象,而不是使用当前的对象。 So you should remove this line from updateButtonActionPerformed . 所以你应该从updateButtonActionPerformed删除这一行。 and change the NewUserFrame_Edit constructor as follows: 并更改NewUserFrame_Edit构造函数,如下所示:

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: 更改你的updateButtonActionPerformed如下:

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 change editUser(int row) method of class UserPage as follows: 并更改类UserPage editUser(int row)方法如下:

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

Here is your updateFile methd: 这是你的updateFile

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) {
    }
}

Another way to implement changes through JTable is to use the code template below: 通过JTable实现更改的另一种方法是使用下面的代码模板:

    table.getModel().addTableModelListener(new TableModelListener(){

        /**
         * Called when table has been changed.
         */
        @Override
        public void tableChanged(TableModelEvent e) {
            int row = e.getFirstRow();
            int column = e.getColumn();
            TableModel model = (TableModel) e.getSource();

            String newdata = (String) model.getValueAt(row, column);
            model.setValueAt(newdata, row, column);
            // do your update with the newdata variable.
        }
    });

Here you can use the actual event to get the row and column of the cell that has been changed in the JTable variable. 在这里,您可以使用实际事件来获取JTable变量中已更改的单元格的行和列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM