2

すでに初期化されている JTable に行を追加したいと考えています。他の要素とは別に、次の(関連する)コードがあります。

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

class sscce extends JFrame {

private static final long serialVersionUID = 1L;    // Serial ID...

// Interface-Elemente erzeugen
Container content = getContentPane();

DefaultTableModel myAbstractTableModel = new DefaultTableModel () {
    private static final long serialVersionUID = 1L;    // whatever
    public String[] columnNames = {"AuftragNr", "Datum & Uhrzeit", "Von", "Nach", "erledigt?"};
    public Object[][] data = {{"156", "31.12.2012 - 10:39:31", "5/5", "205/39", new Boolean(false)}};

    public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
        return data.length;
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
        return data[row][col];
    }

    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    public boolean isCellEditable(int row, int col) {
        if (col != 4) {
            return false;
        } else {
            return true;
        }
    }

    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }
};

JTable auftragTable = new JTable(myAbstractTableModel);
JScrollPane tableScrollPane = new JScrollPane(auftragTable);
JButton auftragAenderungSpeichern = new JButton("speichern");

public sscce() {
    setTitle("Auftragsverwaltung");
    setSize(700, 500);
    setLocation(500, 200);
    setLayout(null);
    setResizable(false);
    tableScrollPane.setBounds(50, 50, 500, 200);

    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });
}

public void actionPerformed(ActionEvent e) {

}

@SuppressWarnings("deprecation")
public static void main(String[] args) {
    JFrame f = new sscce();
    f.show();
}
}

プログラムを実行しようとすると、常にNullPointerExceptionが発生します

at javax.swing.table.DefaultTableModel.setDataVector(Unknown Source)
at javax.swing.table.DefaultTableModel.<init>(Unknown Source)
at javax.swing.table.DefaultTableModel.<init>(Unknown Source)
at javax.swing.table.DefaultTableModel.<init>(Unknown Source)

次のコード行の場合:

public int getRowCount() {
    return data.length;
}

何故ですか?コードの何が問題になっていますか? プログラムはデータを「見つける」ことができるべきではありませんか?


編集: 2 番目のアプローチ

データの保存場所として ArrayList を使用しようとしました...しかし、以下のコメントでマークされているように「cols-rows-issue」があります...配列値が見つかりません(現在ArrayListを使用しているため) )。どうすれば解決できますか?

import java.awt.Container;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

class sscce extends JFrame {

private static final long serialVersionUID = 1L;    // Serial ID...

Container content = getContentPane();

AbstractTableModel myAbstractTableModel = new AbstractTableModel () {
    private static final long serialVersionUID = 1L;    // whatever
    private String[] columnNames = {"AuftragNr", "Datum & Uhrzeit", "Von", "Nach", "erledigt?"};
    private ArrayList<Object> data = new ArrayList<Object>();


    public void addRow(List rowData) {
        data.add(rowData);
        fireTableRowsInserted(data.size() - 1, data.size() - 1);
    }
    public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
        return data.length;
        // can be solved via .size();
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
        return data[row][col];
        // no idea, how to solve that?!
    }

    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    public boolean isCellEditable(int row, int col) {
        if (col == 4) {
            return true;
        }
        return false;
    }

    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        // same issue here...
        fireTableCellUpdated(row, col);
    }
};

JTable auftragTable = new JTable(myAbstractTableModel);
JScrollPane tableScrollPane = new JScrollPane(auftragTable);
JButton auftragAenderungSpeichern = new JButton("speichern");

public sscce() {
    setTitle("Auftragsverwaltung");
    setSize(700, 500);
    setLocation(500, 200);
    setLayout(null);
    setResizable(false);
    tableScrollPane.setBounds(50, 50, 500, 200);

    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });
}

@SuppressWarnings("deprecation")
public static void main(String[] args) {
    JFrame f = new sscce();
    f.show();
}
}

編集: 3 番目のアプローチ

sscce クラス:

import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

class sscce extends JFrame {

    private static final long serialVersionUID = 1L;    // Serial ID...

    Container content = getContentPane();

    AbstractTableModel myAbstractTableModel = new AbstractTableModel() {
        private static final long serialVersionUID = 1L;    // whatever
        private String[] columnNames = {"AuftragNr", "Datum & Uhrzeit", "Von", "Nach", "erledigt?"};
        private ArrayList<DataStore> data = new ArrayList<DataStore>();


        public void addRow(DataStore rowData) {
            data.add(rowData);
            fireTableRowsInserted(data.size() - 1, data.size() - 1);
        }
        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return data.size(); // length
            // can be solved via .size();
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
//          change made here
            DataStore rowElement = data.get(row);
            Object value = rowElement.getItemOnPosition(col);
            return value;
        }

        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        public boolean isCellEditable(int row, int col) {
            if (col == 4) {
                return true;
            }
            return false;
        }

        public void setValueAt(Object value, int row, int col) {
            // change made here
            DataStore rowElement = data.get(row);
            rowElement.setItemOnPosition(col, value);
            fireTableCellUpdated(row, col);
        }
    };

    JTable auftragTable = new JTable(myAbstractTableModel);
    JScrollPane tableScrollPane = new JScrollPane(auftragTable);
    JButton auftragAenderungSpeichern = new JButton("speichern");

    public sscce() {
        setTitle("Auftragsverwaltung");
        setSize(700, 500);
        setLocation(500, 200);
        setLayout(null);
        setResizable(false);
        tableScrollPane.setBounds(50, 50, 500, 200);

        content.add(tableScrollPane);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    @SuppressWarnings("deprecation")
    public static void main(String[] args) {
        JFrame f = new sscce();
        f.show();
    }
}

データストア クラス:

public class DataStore {

    Integer auftragNr;
    String datumUhrzeit;
    String von;
    String nach;
    Boolean status;

    public DataStore(Integer a, String b, String c, String d, Boolean e) {
        auftragNr = a;
        datumUhrzeit = b;
        von = c;
        nach = d;
        status = e;
    }

    public Object getItemOnPosition(int pos) {
        if(pos == 1) {
            return (Integer) auftragNr;
        }
        if(pos == 2) {
            return datumUhrzeit;
        }
        if(pos == 3) {
            return von;
        }
        if(pos == 4) {
            return nach;
        }
        if(pos == 5) {
            return (Boolean) status;
        }
        return null;
    }

    public Object setItemOnPosition(int pos, Object newValue) {
        if(pos == 1) {
            auftragNr = (Integer) newValue;
        }
        if(pos == 2) {
            datumUhrzeit = (String) newValue;
        }
        if(pos == 3) {
            von = (String) newValue;
        }
        if(pos == 4) {
            nach = (String) newValue;
        }
        if(pos == 5) {
            status = (Boolean) newValue;
        }
        return null;
    }
}
4

2 に答える 2

3

独自の を作成しようとするため、 のような具体的な実装ではなく、AbstractTableModelmyAbstractTableModelを拡張する必要があります。ArrayList を使用してデータ オブジェクトを格納します。テーブルの使い方は、これを行う方法の基本を示しています。DefaultTableModel

ちなみに、理由がなければ、フィールドの可視性を可能な限り低くします。

また

public boolean isCellEditable(int row, int col) {
        if (col != 4) {
            return false;
        } else {
            return true;
        }
    }

作るだけ

public boolean isCellEditable(int row, int col) {
        return col == 4;
   }
于 2013-07-14T19:31:50.253 に答える
2

データの保存場所として ArrayList を使用しようとしました...しかし、以下のコメントでマークされているように「cols-rows-issue」があります...配列値が見つかりません(現在ArrayListを使用しているため) )。どうすれば解決できますか?

はい、配列を使用していないため、配列の値が見つかりません。ArrayList からデータを抽出する必要があります。ArrayList メソッドに慣れていない場合は、ArrayList APIを確認してください。

コードに関しては、コンパイル エラーがあり、これらのタイプのエラーが見つかった場合は、どこが間違っているのかを調べる必要があります。主に、ArrayList を配列であるかのように処理しようとしていますが、もちろんそうではありません。そのため、array.length を使用するか配列インデックス (array[i][j]) を使用する配列型構造は、惨めに失敗します。繰り返しますが、上記にリンクされている ArrayList API またはまともな ArrayList チュートリアルを見て、これらの人の使い方を見つけてください。たとえば、ArrayList に長さのプロパティまたはメソッドがないことがコンパイラから通知された場合は、必要な情報を取得する適切なメソッドを ArrayList API で探します。そのための API です。

また、ArrayList は Object を保持すべきではありません。つまり、保持すべきではありませんがArrayList<Object>、より具体的なものにする必要があります。通常、テーブル モデルの行には、行の各項目を表すプロパティを持つオブジェクトが保持されます。したがって、各行のデータ RowData を保持するクラスを呼び出すと、ArrayList はArrayList<RowData>. 行、列の値を取得するには、モデルの ArrayList から行インデックスの RowData (これが行データのクラスの名前であると想定) を抽出し、オブジェクトの getter メソッドを呼び出して列インデックスを抽出する必要があります。・関連アイテム。

于 2013-07-14T19:19:24.547 に答える