4

Java でテーブルから行を削除しようとすると、いくつかの問題に直面します。特に、私は を使用DefaultTableModelし、メソッドを使用して行を削除しようとすると、がremoveRow(int row)何であるかに関係なく、最後の行が削除されrowます。たとえば、6 つの行があるとします。removeRow(0)orが呼び出さremoveRow(2)れると、removeRow(5)最後の行は常に削除されます。なぜこれが起こっているのですか?

ありがとう

- -アップデート

jtable の特定のセルが押されると、対応する行が削除されます。

    class TagsTableMA extends MouseAdapter {

    @Override
    public void mousePressed(MouseEvent e){
        Point p = e.getPoint();
        int row = tagsJT.rowAtPoint(p);
        int column = tagsJT.columnAtPoint(p);

        if (column == COLUMN_DELETE_TAG){
            DocDialog docDialog = new DocDialog(parentMainJF, 
                                                true, 
                                                null, 
                                                "Please confirm...", 
                                                "Are you sure you want to delete the \"" + 
                                                tagsJT.getValueAt(row, COLUMN_TAG_NAME) +
                                                "\" tag?",
                                                DocDialog.TYPE_YES_NO);
            docDialog.show();
            int answer = docDialog.getAnswer();

            if (answer == DocDialog.YES)                                                
                    model.removeRow(row);
        }
    }   
}

--- no2 を更新 ここに私の問題のあるコードがあります。関係のないものをいくつか削除しました。

import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class MainJF extends JFrame {

public MainJF(){
    this.add(createTagsTable());
    setMinimumSize(new java.awt.Dimension(200,400));
}

 private JTable createTagsTable(){

    String[] columnNames = {"",          
                            "Tag",
                            "",
                            "",
                            ""};


    Object[][] data = new Object[10][columnNames.length];
    for (int i=0; i<data.length; i++){
        data[i][COLUMN_CHECK] = false;
        data[i][COLUMN_TAG_NAME] = "Tag " + i;
        data[i][COLUMN_TAG_ID] = i;
        data[i][COLUMN_EDIT_TAG] = "edit";
        data[i][COLUMN_DELETE_TAG] = "delete";
    }

    model = new TagsSelectionTableModel(columnNames, data);
    tagsJT = new JTable(model);

    tagsJT.setRowSelectionAllowed(true);
    tagsJT.addMouseListener(new TagsTableMA());

    return tagsJT;
}


class TagsSelectionTableModel extends DefaultTableModel{

    public TagsSelectionTableModel(String[] columnNames, Object[][] data){
        super(data, columnNames);
        this.columnNames = columnNames;
        this.data = data;
    }

    private String[] columnNames;
    private Object[][] data;


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

  class TagsTableMA extends MouseAdapter{

    @Override
    public void mousePressed(MouseEvent e){
        Point p = e.getPoint();
        int row = tagsJT.rowAtPoint(p);
        int column = tagsJT.columnAtPoint(p);

        if (column == COLUMN_DELETE_TAG){
            int irow = tagsJT.convertRowIndexToView(row);     
            model.removeRow(irow);
        }
    }
}


private JTable tagsJT;
private TagsSelectionTableModel model;   

private static int COLUMN_CHECK = 0;
private static int COLUMN_TAG_NAME = 1;
private static int COLUMN_TAG_ID = 2;
private static int COLUMN_EDIT_TAG = 3;
private static int COLUMN_DELETE_TAG = 4;


public static void main(String args[]) {
    new MainJF().setVisible(true);
}
}
4

2 に答える 2

5

row取得元はビュー座標ですが、モデル座標をcolumnAtPoint()想定ています。関連するチュートリアルセクションからの引用:removeRow()

列の並べ替え、フィルター処理、またはユーザー操作によって表示されたデータが再配置されていない限り、この区別は重要ではありません。

その場合、 を使用する必要があります。これについては、並べ替えとフィルタリングconvertRowIndexToModel()の最後の方で説明されています。

ソーターを使用するときは、常にセル座標を変換することを忘れないでください。

また、 のListSelectionListener代わりに を使用することを検討してMouseAdapterください。

補遺: の実装はgetValueAt()、コンストラクターに提供された配列にアクセスし続けましたが、モデルのデータは実際には親実装に格納されていました。モデルのデータ構造をさらに制御する必要がある場合は、ここAbstractTableModelに示すように を拡張します。

import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

/** @see https://stackoverflow.com/a/11237205/230513 */
public class MainJF extends JFrame {

    private JTable tagsJT;
    private TagsSelectionTableModel model;
    private static int COLUMN_CHECK = 0;
    private static int COLUMN_TAG_NAME = 1;
    private static int COLUMN_TAG_ID = 2;
    private static int COLUMN_EDIT_TAG = 3;
    private static int COLUMN_DELETE_TAG = 4;

    public MainJF() {
        this.add(new JScrollPane(createTagsTable()));
        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    private JTable createTagsTable() {

        String[] columnNames = {"0", "Tag", "2", "3", "4"};

        Object[][] data = new Object[10][columnNames.length];
        for (int i = 0; i < data.length; i++) {
            data[i][COLUMN_CHECK] = false;
            data[i][COLUMN_TAG_NAME] = "Tag " + i;
            data[i][COLUMN_TAG_ID] = i;
            data[i][COLUMN_EDIT_TAG] = "edit";
            data[i][COLUMN_DELETE_TAG] = "delete";
        }
        model = new TagsSelectionTableModel(columnNames, data);
        tagsJT = new JTable(model);
        tagsJT.setRowSelectionAllowed(true);
        tagsJT.addMouseListener(new TagsTableMA());
        return tagsJT;
    }

    class TagsSelectionTableModel extends DefaultTableModel {

        public TagsSelectionTableModel(String[] columnNames, Object[][] data) {
            super(data, columnNames);
        }
    }

    class TagsTableMA extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            Point p = e.getPoint();
            int row = tagsJT.rowAtPoint(p);
            int col = tagsJT.columnAtPoint(p);
            if (col == COLUMN_DELETE_TAG) {
                model.removeRow(row);
            }
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MainJF().setVisible(true);
            }
        });
    }
}
于 2012-06-28T08:59:03.220 に答える
3

removeRow(int)のメソッドのコードを見るとDefaultTableModel、バッキングの対応するインデックスで行配列が削除されることが明らかですVector

 public void removeRow(int row) {
    dataVector.removeElementAt(row);
    fireTableRowsDeleted(row, row);
} 

(Java 6 から)。

次の 2 つの可能性が考えられます。

  1. を拡張し、DefaultTableModelこのメソッドの実装を変更しました。(これが事実であるとは思えません-おそらく投稿でこれを認めたでしょう)

  2. テーブルのカスタム レンダラーがあり、セルの行インデックスに基づいてセル データを描画します。

于 2012-06-28T02:07:28.190 に答える