Jtable更新选定的行

时间:2013-03-21 18:20:54

标签: java swing jtable

我有一个带有编辑按钮的jtable,当我选择一行并单击编辑按钮并编辑字段,然后单击以保存按钮,该行不会更新,并且我必须刷新我的表以更改行!

我的代码:

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

...

我的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();
}
...
}

我的模型类的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) {
    }
}
...
}

当我选择一行并单击编辑按钮时,会打开一个新的jframe,其文本字段将填充旧数据,然后我更新数据并单击以保存按钮。 因此,我的专栏不确定。 我选择整行,而不是单元格!

感谢。

3 个答案:

答案 0 :(得分:6)

要更改JTable条目,请使用TableModel#setValueAt。调用fireTableDataChanged是不必要的。这适用于TableModel内部的内部使用。

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

答案 1 :(得分:4)

您可以在updateRow(int index,String[] values)扩展类中创建一个名为AbstractModel的方法,并在其中使用setValueAt(newValue,row,index)为该行的每个单元格设置新值。并且在setValue的重写TableModel方法中写入fireTableCellUpdated(row,col)。

考虑下面给出的代码。查看updateRow课程中的setValueAtMyModel方法。并观看((MyModel)myModel).updateRow(row,values);//update row课程中的MyMouseAdapter

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

<强>更新
您的原始代码一切都很好。保持最初的代码。唯一的问题是方法userModel = new AllUser();中的行updateButtonActionPerformed。它创建了AllUser的新对象,而不是使用当前的对象。所以你应该从updateButtonActionPerformed中删除这一行。并按如下方式更改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);
}

将您的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();
}

更改类editUser(int row)的{​​{1}}方法,如下所示:

UserPage

这是你的public void editUser(int row) { UserInformation userInf = userModel.getSelectedMember(row); NewUserFrame_Edit edit = new NewUserFrame_Edit(userModel,userInf, row); } 方法:

updateFile

答案 2 :(得分:2)

通过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.
        }
    });

在这里,您可以使用实际事件来获取JTable变量中已更改的单元格的行和列。