更改JTable模型后,键绑定消失

时间:2016-03-09 17:09:14

标签: java swing jtable

我有一个JTable,其创建如下,默认为空模型。

如果我通过文本文件(CSV)的外部处理更改了该数据模型,并使用RosterTable.setModel(...)重置它,则TAB和Shift + TAB的标准键绑定将丢失。 TableModel的更改非常标准,并在下面列出。

因此症状:全新的RosterTable按预期执行,这意味着TAB将一个单元格向右移动,Shift + TAB将一个单元格向左移动并且两者都包裹到表行末尾的下一行/上一行。调用setModel()后,TAB和Shift + TAB根本不再起作用。 设置InputMap后,为什么TableModel会发生变化?

NOTABLY:同一应用程序中的其他表通过使用序列化对象在实例化时加载其表。这些表也可以使用TAB和Shift + TAB键正常运行。更改表中的数据"即时"通过手动编辑似乎也不会影响键绑定。使用setModel时,它似乎只显示错误。

RosterTable = new javax.swing.JTable();

RosterTable.setModel(new javax.swing.table.DefaultTableModel(
    new Object [][] {
        {null, null, null, null, null, null, null, null},
        {null, null, null, null, null, null, null, null},
        {null, null, null, null, null, null, null, null},
...
    },
    new String [] {
        "Callsign", "Close Time", "Notes", "Precedence", "Dest RI", "List Time", "Status", "Sent Time"
    }
) {
    Class[] types = new Class [] {
        java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
    };

    public Class getColumnClass(int columnIndex) {
        return types [columnIndex];
    }
});

RosterTable.setFillsViewportHeight(true);
RosterTable.setRowSelectionAllowed(false);
RosterTable.getTableHeader().setReorderingAllowed(false);
RosterScrollPane.setViewportView(RosterTable);
RosterTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
setRosterTableColumWidths(); // to resize columns to preferred widths
RosterTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
RosterTable.setGridColor(java.awt.Color.DARK_GRAY);
RosterTable.setShowGrid (true);

然后,当需要以批发方式更改表数据时,完成此操作的代码如下所示。第一个语句是FileChooser打开操作的输出的接收者。 EMPTY是一个静态的空字符串,如果不是很明显的话。

        File f = fc.getSelectedFile();
        String lineIn = null;
        int count = -1;
        Vector<Vector> data = new Vector<>();
        Vector<String> row = null;
        String[] tokens = null;
        String delim = ",";
        try {
            BufferedReader br = new BufferedReader(new FileReader(f));
            // skip all data before the roster itself
            while ((lineIn = br.readLine()) != null) {
                // call is the start of the header text line
                if (lineIn.startsWith("NCS:")) {
                    break;
                }
            }

            // now process all roster lines until we get to BT
            while ((lineIn = br.readLine()) != null) {
                if (lineIn.startsWith("BT")) {
                    // we found the end of the data
                    break;
                }
                count++;
                row = new Vector<>();
                tokens = lineIn.split(delim);
                if (tokens.length > 0) {
                    for (String token : tokens) {
                        row.add(token.equals(EMPTY) ? null : token);
                    }
                } else {
                    for (int i = 0; i < 8; i++) {
                        row.add(null);
                    }
                }
                data.add(row);
            }
            br.close();
            // now fill the rest of the rows with nulls so
            // empty rows may be filled by the user in the UI
            while (count < 100) {
                row = new Vector<>();
                for (int i = 0; i < 8; i++) {
                    row.add(null);
                }
                data.add(row);
                count++;
            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(StationManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(StationManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        // reload the column labels from existing
        Vector<String> colsV = new Vector<>();
        TableModel tcm = RosterTable.getModel();
        for (int i = 0; i < 8; i++) {
            colsV.add((String) tcm.getColumnName(i));
        }
        TableModel tm = new DefaultTableModel(data, colsV);
        RosterTable.setModel(tm);
        setRosterTableColumWidths();

此方法完成后,表模型是正确的,但TAB,Shift + TAB和ENTER不再与首次初始化表模型时相同。 TAB,Shift + TAB和ENTER仅将突出显示的单元格置于编辑模式。箭头键正常工作。文本也可以按正常方式键入任何单元格。

JTable是否关心我使用Vector代替String[]等建立新模型?对我来说听起来不合逻辑。

这是一个SSCCE,如评论中所述,它按预期工作,所以我现在更加困惑。 ;)

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class TableModelChange extends JFrame {

private JTable t = null;

public TableModelChange() {
    super();
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setBounds(100, 100, 500, 200);
    JButton loadModel = new JButton("Load New Model");
    loadModel.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            loadModelButtonActionPerformed(evt);
        }
    });
    t = new JTable();
    t.setModel(new javax.swing.table.DefaultTableModel(
            new Object[][]{
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null},
                {null, null, null, null, null, null, null, null}
            },
            new String[]{
                "Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7", "Col8"
            }
    ) {
        Class[] types = new Class[]{
            java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
        };

        public Class getColumnClass(int columnIndex) {
            return types[columnIndex];
        }
    });
    this.getContentPane().add(t, BorderLayout.CENTER);
    this.getContentPane().add(loadModel, BorderLayout.NORTH);
    this.pack();
}

private void loadModelButtonActionPerformed(ActionEvent evt) {
    Vector<Vector> data = new Vector<>();
    Vector<String> row = new Vector<>();
    for (int j = 0; j < 6; j++) {
        for (int i = 0; i < 8; i++) {
            row.add("A");
        }
        data.add(row);
    }
    Vector<String> colsV = new Vector<>();
    TableModel tcm = t.getModel();
    for (int i = 0; i < 8; i++) {
        colsV.add((String) tcm.getColumnName(i));
    }
    t.setModel(new DefaultTableModel(data, colsV));
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            TableModelChange tm = new TableModelChange();
            tm.setVisible(true);
        }
    });
}

}

1 个答案:

答案 0 :(得分:0)

如果我在更改JTable模型后添加一个调用来加载现有的L&amp; F,问题就会消失。目前,这是解决方法,但我想深究这个问题。关于如何/在何处追踪的建议将受到欢迎。