【问题标题】:isCellEditable and Database doesn't work togetherisCellEditable 和数据库不能一起工作
【发布时间】:2013-08-21 01:26:06
【问题描述】:

我的JTable 在更改单元格值后不会刷新。我可以双击一个单元格并更改它的值,但是当我按 OK 或单击单元格外时,值会重置为前一个值,它不会更新表格。这是我的自定义表模型的代码,我不知道如何更新数据库,因为当我更改单元格的值时,表是从数据库中获取的。

package adisys.server.strumenti;

import java.sql.*;
import java.util.Formatter;

import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

import adisys.server.boundary.EditorPatologie;
import adisys.server.data.Database;
import adisys.server.data.Patologie;
import adisys.server.entity.Patologia;


/**
 * @author Francesco
 *
 */
public class ADISysTableModel extends AbstractTableModel implements TableModel {


    ResultSet dati;

    public ADISysTableModel(ResultSet nuoviDati)
    {
        dati=nuoviDati;

        try {
            //Trace
            System.out.println("- Creazione modello tabella: \""+ dati.getMetaData().getTableName(1) +"\"");
        } catch (SQLException e1) {
            e1.printStackTrace();
        }

    }

    @Override
    public int getColumnCount() {

        try {
            return dati.getMetaData().getColumnCount();
        } 
        catch (SQLException e) {
            e.printStackTrace();
            System.out.println("ERRORE: Calcolo del numero di colonne errato.");
            return 0;
        }
    }

    @Override
    public int getRowCount() {

        try {
            //Seleziona l'ultimo elemento
            dati.last();
            //Restituisce l'indice dell'elemento
            return (dati.getRow());


        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("ERRORE: Calcolo del numero di righe errato. (metodo getRowCount() )");
            return 0;
        }
    }

    @Override
    public Object getValueAt(int riga, int colonna) {

        try {
            //Sposta il cursore alla riga desiderata (con sfasamento di 1)
            dati.absolute(riga+1);

            //Estrae il valore nella colonna specificata e lo restituisce (con sfasamento di 1)
            return dati.getObject(colonna+1);

        } catch (SQLException e) {
            // In caso di errore restituisce un oggetto vuoto
            e.printStackTrace();

            //Trace
            System.out.println("ERRORE: Valore dell'elemento della tabella non valido.");
            return null;
        }
    }

    @Override
    public boolean isCellEditable(int rIndex, int cIndex)
    {
        return true;
    }


    @Override
    public String getColumnName(int col) {
        try {
            return dati.getMetaData().getColumnName(col+1);
        } catch (SQLException e) {
            // Eccezione
            e.printStackTrace();
            return "?";
        }
    }

    public Integer getID(int riga)
    {
        //Ricerca colonna ID
        for(int i=0; i<=getColumnCount(); i++)
            if(getColumnName(i).equals("ID"))
                return i;
        return null;
    }


    /**
     * Restituisce l'indice della colonna a partire dal nome della colonna ricercata
     * <b>N.B. L'indice della prima colonna è 0, l'ultimo è numeroColonne-1.</b>
     * @param Nome - Stringa con il nome della colonna
     * @return -1 se la colonna non e' stata trovata, altrimenti l'indice della colonna
     */
    public int getColumnIndex(String Nome)
    {
        for (int i=0; i<getColumnCount();i++)
            if( getColumnName(i)==Nome) return i;
        return -1;
    }


}

如果您需要其他内容,例如数据库或表格编辑器的代码,请告诉我 ;) 感谢您的帮助 :)

--编辑-- 好吧,我已经实现了 setValueAt 方法,但是当我单击单元格时,它会给我这样的错误

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at adisys.server.strumenti.ADISysTableModel.setValueAt(ADISysTableModel.java:149)
    at javax.swing.JTable.setValueAt(Unknown Source)
    at javax.swing.JTable.editingStopped(Unknown Source)
    at javax.swing.AbstractCellEditor.fireEditingStopped(Unknown Source)
    at javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(Unknown Source)
    at javax.swing.DefaultCellEditor.stopCellEditing(Unknown Source)
    at javax.swing.JTable$GenericEditor.stopCellEditing(Unknown Source)
    at javax.swing.DefaultCellEditor$EditorDelegate.actionPerformed(Unknown Source)
    at javax.swing.JTextField.fireActionPerformed(Unknown Source)
    at javax.swing.JTextField.postActionEvent(Unknown Source)
    at javax.swing.JTextField$NotifyAction.actionPerformed(Unknown Source)
    at javax.swing.SwingUtilities.notifyAction(Unknown Source)
    at javax.swing.JComponent.processKeyBinding(Unknown Source)
    at javax.swing.JComponent.processKeyBindings(Unknown Source)
    at javax.swing.JComponent.processKeyEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

我的 setValueAt 方法是这样的:

Vector<Paziente> content;

    @Override
    public void setValueAt(Object value, int rowIndex, int columnIndex)
    {
        Paziente row = this.content.elementAt(rowIndex);
        String strValue = (String)value;
        int IDValue = (int)value;
        if(columnIndex == 0)
        {
            row.setID(IDValue);
        }
        else if(columnIndex == 1)
        {
            row.setNome(strValue);
        }
        else if(columnIndex == 2)
        {
            row.setCognome(strValue);
        }
        fireTableCellUpdated(rowIndex, columnIndex);
    }

你能再帮我一次吗? :) 我对这个功能越来越疯狂,我知道这对很多人来说并不难,但对我来说是......谢谢你的回答,祝你有美好的一天! :D

更新:我已经用这段代码解决了这个问题: [代码] @覆盖 公共无效 setValueAt(对象值,int rowIndex,int columnIndex) {String aValue = (String)value; String formatoIstruzione = "更新 PAZIENTI SET NOME = " + "'" + aValue + "'" + " WHERE ID = " + rowIndex + ";"; Database.esegui(formatoIstruzione.toUpperCase()); Pianificatore.aggiornaTabelle(); } } [/代码]

换句话说,我启动 sql 指令来更新表,然后我刷新它的视图,所以它几乎显示了新值。谢谢大家的帮助和你给我的灵感,我们终于明白了!! *_*

【问题讨论】:

    标签: java swing jtable


    【解决方案1】:

    我在您的TableModel 中没有看到任何setValueAt() 的实现。没有它,你怎么能期望这些事情发生呢?尝试实施该方法,看看是否做得更好。

    更新:

    您在 ADISysTableModel 的第 149 行有一个空引用:

    at adisys.server.strumenti.ADISysTableModel.setValueAt(ADISysTableModel.java:149)
    

    打开文本编辑器,转到该行号,然后检查对象引用。在调试器中运行以查看哪个为空。这很容易解决。

    看到这条线了吗?

    Vector<Paziente> content;
    

    这会将引用设置为 null,因为您没有调用 new 将其设置为新引用。

    把它改成这个,NPE就消失了:

    Vector<Paziente> content = new Vector<Paziente>();
    

    这可能不是你想要的,但它不会为空。

    我认为您应该处理基础表模型,而不是这个随机向量。你知道你的代码,但我认为这也不会让你开心。

    我强烈建议您在尝试真正的问题之前简化事情并阅读 JTable 教程:

    http://docs.oracle.com/javase/tutorial/uiswing/components/table.html

    【讨论】:

    • +1 AbstractTableModel 中的实现为空;另请参阅相关的example
    • 编辑:我已经实现了 setValueAt 方法,检查一下! ;)
    • 我在这里看不到更新数据库的代码。如果您期望这种行为,则必须对其进行编码。
    • 你的老师不是混蛋。你需要成为一个更好的学生。花一些时间学习教程并弄清楚。 docs.oracle.com/javase/tutorial/uiswing/components/table.html
    • 也许他希望学生们填空。我总是怀疑学生说老师的坏话。很多时候,问题出在学生身上。我从个人经验中知道。我畏缩地回忆起我对我的一位特定教练所说的话。问题是我,不是他。
    猜你喜欢
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2019-08-17
    • 2016-11-23
    • 2019-02-18
    相关资源
    最近更新 更多