【问题标题】:Jtable update selected rowJtable 更新选中的行
【发布时间】:2013-03-11 09:57:21
【问题描述】:

我有一个带有编辑按钮的 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,其文本字段填充有旧数据,我更新数据并单击以保存按钮。 因此,我的专栏并不确定。 我选择了一整行,而不是一个单元格!

谢谢。

【问题讨论】:

  • 是的..Sajjad,我今天在您的代码中指出了这种行为。您可以创建一个名为updateRow(int index) 的方法,并在其中使用setValueAt(newValue,row,index) 为该行的每个单元格设置新值。并在 TableModel 的重写 setValue 方法中写入 fireTableCellUpdated(row, col)
  • 哦'嗨亲爱的@VishalK,你在审查我的整个项目吗?
  • 嗨@Sajjad:你做得很好..除了一些小错误..这是我发现的。关于您的项目级别..它仍然需要很少的修改,然后就可以了...
  • updateFile()AllUser 类中的代码在哪里?
  • 等等..让我检查一下你的方法..然后我更新我的帖子..

标签: java swing jtable


【解决方案1】:

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

考虑下面给出的代码。查看MyModel 类中的updateRowsetValueAt 方法。并观看((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();
            }
        });
    }
}

更新
您的原始代码一切正常。保持最初的代码。唯一的问题是方法updateButtonActionPerformed 中的userModel = new AllUser(); 行。它正在创建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();
}

并将UserPage类的editUser(int row)方法改成如下:

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

这是您的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) {
    }
}

【讨论】:

  • 我应该在每个 setValueAt() 方法中使用 fireTableCellUpdated() 方法吗?
  • AbstractTableModel 覆盖的类中只定义了一个 setValueAt。只在那个地方写 fireTableCellUpdated 方法。是的,您应该使用 SwingUtilities.invokeLater 对 GUI 进行一些更改。但是,如果您在 EDT 中进行更改,例如 actionPerformed,那么您不需要这个..
  • @Sajjad:首先你创建一个UserInformation 的空白对象,比如obj。在编辑框的textfields 中进行必要的更改后,单击确定,用相应的文本字段值填充obj 的相应字段。然后调用updateRow(index,obj),其中index 是已编辑行的索引号。我希望这会让你明白。
  • @Sajjad- 我在示例代码中发布的所有内容都只是演示。它告诉您如何在进行一些更改时更新 JTable。您不必完全复制它..
  • Admin 只是不能更改选定的行 ID 号,只能更改 fName 和 Lname 以及 Gender 和日期。
【解决方案2】:

要更改 JTable 条目,请使用 TableModel#setValueAt。无需致电fireTableDataChanged。这是在TableModel 本身内部使用的。

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

【讨论】:

  • 我在我的表模型类上使用 setVlaueAt 方法。
  • 这个语句应该用在什么地方?
  • 点击“保存”按钮后?
  • 我认为方法的第三个参数是选择列,好吗?
  • 当我选择一行并单击编辑按钮时,会打开一个新的 jframe,当我编辑文本字段并单击保存按钮时,应更新新数据。
【解决方案3】:

通过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变量中发生变化的单元格的行列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多