4

JTable私のスイングスクリーンに1つ持ってください。画面の読み込み中に、このテーブル専用に作成された 1 つのテーブル モデルを設定しています。実行時にデータが変更された場合は、同じモデルを再作成し、 を使用して再度設定しobjJTable.setModel(objCustTableModel)ます。

問題は、画面のロード時にロードされるテーブルモデルです。同じモデルオブジェクトが、クラスobjJTable.setModel(objCustTableModel)から getColumnClass(int col) メソッドを呼び出した実行時の設定中に呼び出されます。CustTableModelこのオブジェクト呼び出しの後、新しいモデル オブジェクトが呼び出されます。同じコードを使用して別の新しいテーブル モデルを設定するとobjJTable.setModel(objCustTableModel2)、モデル呼び出しの関数が最初に呼び出されobjCustTableModel、次に から呼び出されobjCustTableModel2ます。

要するに、setModel()関数は最初に前のモデル オブジェクトを呼び出し、次に現在のモデル オブジェクトを呼び出します。以前のモデル オブジェクトの呼び出しに制限するにはどうすればよいですか?

例えば

import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

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


/**
 * Steps to reproduce issue.
 * 1. Run this program.
 * 2. There will be two rows in table. Delete all rows one by one.
 * 3. Now click on Add button and see the exception.
 * 
 * I come to know that this exception is because of table.setAutoCreateRowSorter(true); line, which is there in TestCustTableModel's constructor
 * If you comment this line, then issue got resolved.
 * But I want to apply sorting on columns so this line is required.
 */

public class TestCustTableModel extends JPanel{
    JTable table = new JTable();
    public TestCustTableModel() {

        Object[][] data = new Object[2][3];
        data[0][0] = "1";
        data[0][1] = "User1";
        data[0][2] = "Delete";

        data[1][0] = "2";
        data[1][1] = "User2";
        data[1][2] = "Delete";

        JButton addButton = new JButton("Add");
        addButton.addMouseListener(new AddListener());
        table.setModel(new CustModel(data));
        table.addMouseListener(new TableListener());

        /**#################################
         * Following line throws ArrayIndexOutOfBoundsException. Please comment or Uncomment following line and see the difference.
         */
        table.setAutoCreateRowSorter(true);


        table.getTableHeader().setCursor(new Cursor(Cursor.HAND_CURSOR));
        JScrollPane scrollPane = new JScrollPane(table);

        this.add(addButton);
        this.add(scrollPane);
    }


    class TableListener extends MouseAdapter {
        public void mouseClicked(MouseEvent evnt) {
            Point p = evnt.getPoint();
            if(table.columnAtPoint(p) == 2) {
                Object[][] data = null;
                if(table.getModel().getRowCount() == 2 && table.rowAtPoint(p) == 0) {
                    data = new Object[1][3];
                    data[0][0] = "2";
                    data[0][1] = "User2";
                    data[0][2] = "Delete";
                }else if(table.getModel().getRowCount() == 2 && table.rowAtPoint(p) == 1) {
                    data = new Object[1][3];
                    data[0][0] = "1";
                    data[0][1] = "User1";
                    data[0][2] = "Delete";
                }else {
                    data = new Object[0][];
                }
                table.setModel(new CustModel(data));
            }
        }
    }


    class AddListener extends MouseAdapter{

        @Override
        public void mouseClicked(MouseEvent evnt) {
            if(table.getModel().getRowCount() == 2) {
                return;
            }
            Object[][] data = new Object[table.getModel().getRowCount() + 1][3];
            for(int i = 0; i <= table.getModel().getRowCount(); i++) {
                data[i][0] = i;
                data[i][1] = "User" + i;
                data[i][2] = "Delete";
            }
            table.setModel(new CustModel(data));
        }

    }

    class CustModel extends AbstractTableModel {
        private String[] columnNames = {"ID", "NAME", "DELETE"};
        private Object[][] data = null;

        public CustModel(Object[][] data) {
            this.data = data;
        }
        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 col) {
            return getValueAt(0, col).getClass();
        }
    }

    private void display() {
        JFrame f = new JFrame("SwapTableModel");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        TestCustTableModel obj = new TestCustTableModel();
        obj.display();
    }
}

このとき、swing は、最初に内部的に呼び出されgetColumnClassた関数に基づいてobjCustTableModel、その後、objCustTableModel2オブジェクトを使用します。に基づく通話を制限したいobjCustTableModel

4

3 に答える 3

4

この例から始めて、getColumnClass()以下に示す実装で予期しない動作は見られませんでした。

private Model() {
    final Object[] data = {this.toString()};
    this.model = new DefaultTableModel(data, 1){

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            System.out.println(data[0]);
            return super.getColumnClass(columnIndex);
        }
    };
    model.addRow(data);
}

は、セルのレンダリングが必要であると判断したときにいつでもJTable呼び出すことができることに注意してください。getColumnClass()必要に応じて、EventQueue.invokeLater()「保留中のすべてのイベントが処理された後に発生する」何かをスケジュールするために使用できます。

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        // do something
    }
});

補遺:

  • である場合getAutoCreateRowSorter()true、古いモデルを使用しsetModel()て作成された を復元しようとします。RowSorter

  • 以下に示すようにモデルを変更setAutoCreateRowSorter(true) した後に指定するか、ここTableModelに示すようにモデルをその場で更新するように拡張することができます。

  • の代わりにActionListenerforを使用します。JButtonMouseListener

  • ここここTableCellEditorに示すように、表のボタンには を使用します。

コード:

addButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        if (table.getModel().getRowCount() == 2) {
            return;
        }
        Object[][] data = new Object[table.getModel().getRowCount() + 1][5];
        table.setRowSorter(null);
        for (int i = 0; i <= table.getModel().getRowCount(); i++) {
            data[i][0] = i;
            data[i][6] = "User" + i;
            data[i][7] = "Delete";
        }
        table.setModel(new CustModel(data));
        table.setAutoCreateRowSorter(true);
    }
});
于 2013-04-16T17:15:22.017 に答える
3
 DefaultTableModel model ;
    /** Creates new form DynRowAdd */
    public DynRowAdd() {
        initComponents();
          model = new DefaultTableModel();
                    jTable1.setModel(model);
                    model.addColumn("Id");
                    model.addColumn("First Name");
                    model.addColumn("Last Name");
                    model.addColumn("Company Name");
    }
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

        model.addRow(new Object[]{jTextField1.getText(), jTextField2.getText(),jTextField3.getText(),jTextField4.getText()});

    }                
于 2014-03-13T07:28:15.637 に答える