如何修复 Java 中的 'TableModel.setValueAt ArrayIndexOutOfBoundsException' 错误
How to fix 'TableModel.setValueAt ArrayIndexOutOfBoundsException' error in Java
我有一个 JTable 应用程序。我需要更改单元格值并保存数据,但只有索引小于或等于 4 的单元格在数组范围内。
package fi.allu.neliojuuri;
import com.sun.glass.events.KeyEvent;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import javax.swing.event.CellEditorListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
public class Neliojuuri extends JPanel
implements ActionListener, ItemListener, TableModelListener {
String newline = "\n";
private JTable table;
private JCheckBox rowCheck;
private JCheckBox columnCheck;
private JCheckBox cellCheck;
private ButtonGroup buttonGroup;
private JTextArea output;
private String[] sarakenimet = new String[70];
private String[] sisakkainen = new String[70];
private Object[][] ulkoinen = new String[71][71];
private DefaultTableModel oletusmalli = null;
private CellEditorListener solumuokkaaja = null;
public Neliojuuri() {
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
for (int i = 0; i < 70; i++) {
sarakenimet[i] = String.valueOf(i + 1);
}
for (int i = 0; i < sisakkainen.length; i++) {
sisakkainen[i] = String.valueOf(i + 1);
}
for (int i = 0; i < ulkoinen.length; i++) {
ulkoinen[i] = sisakkainen;
}
table = new JTable(ulkoinen, sarakenimet);
table.setPreferredScrollableViewportSize(new Dimension(500, 210));
table.setFillsViewportHeight(true);
table.setRowHeight(30);
TableColumnModel sarakeMalli = table.getColumnModel();
for (int i = 0; i < 70; i++) {
sarakeMalli.getColumn(i).setPreferredWidth(75);
}
oletusmalli = new javax.swing.table.DefaultTableModel();
table.setModel(oletusmalli);
String[] sarakenimet = new String[70];
for (int i = 0; i < 70; i++) {
sarakenimet[i] = String.valueOf(i + 1);
}
String[] sisakkainen = new String[70];
for (int i = 0; i < sisakkainen.length; i++) {
sisakkainen[i] = String.valueOf(i + 1);
}
Object[][] ulkoinen = new String[71][71];
for (int i = 0; i < ulkoinen.length; i++) {
ulkoinen[i] = sisakkainen;
}
oletusmalli.setColumnIdentifiers(sarakenimet);
for (int count = 0; count < 70; count++){
oletusmalli.insertRow(count, sisakkainen);
}
table.getSelectionModel().addListSelectionListener(new RowListener());
table.getColumnModel().getSelectionModel().
addListSelectionListener(new ColumnListener());
add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getModel().addTableModelListener(this);
add(new JLabel("Selection Mode"));
buttonGroup = new ButtonGroup();
addRadio("Multiple Interval Selection").setSelected(true);
addRadio("Single Selection");
addRadio("Single Interval Selection");
add(new JLabel("Selection Options"));
rowCheck = addCheckBox("Row Selection");
rowCheck.setSelected(true);
columnCheck = addCheckBox("Column Selection");
cellCheck = addCheckBox("Cell Selection");
cellCheck.setEnabled(false);
output = new JTextArea(5, 40);
output.setEditable(false);
output.setFont(new Font("Segoe UI", Font.PLAIN, 20));
add(new JScrollPane(output));
}
private JCheckBox addCheckBox(String text) {
JCheckBox checkBox = new JCheckBox(text);
checkBox.addActionListener(this);
add(checkBox);
return checkBox;
}
private JRadioButton addRadio(String text) {
JRadioButton b = new JRadioButton(text);
b.addActionListener(this);
buttonGroup.add(b);
add(b);
return b;
}
public void actionPerformed(ActionEvent e) {
JFileChooser tiedostovalitsin = new JFileChooser();
JMenuItem source = (JMenuItem)(e.getSource());
if (source.getText() == "Save") {
int palautusArvo = tiedostovalitsin.showSaveDialog(Neliojuuri.this);
if (palautusArvo == JFileChooser.APPROVE_OPTION) {
File tiedosto = tiedostovalitsin.getSelectedFile();
// Tallenna tiedosto oikeasti
for (int i = 0; i < oletusmalli.getRowCount(); i++) {
System.out.println(oletusmalli.getValueAt(1, i).toString());
}
System.out.println(tiedosto.getName());
}
}
String command = e.getActionCommand();
//Cell selection is disabled in Multiple Interval Selection
//mode. The enabled state of cellCheck is a convenient flag
//for this status.
if ("Row Selection" == command) {
table.setRowSelectionAllowed(rowCheck.isSelected());
//In MIS mode, column selection allowed must be the
//opposite of row selection allowed.
if (!cellCheck.isEnabled()) {
table.setColumnSelectionAllowed(!rowCheck.isSelected());
}
} else if ("Column Selection" == command) {
table.setColumnSelectionAllowed(columnCheck.isSelected());
//In MIS mode, row selection allowed must be the
//opposite of column selection allowed.
if (!cellCheck.isEnabled()) {
table.setRowSelectionAllowed(!columnCheck.isSelected());
}
} else if ("Cell Selection" == command) {
table.setCellSelectionEnabled(cellCheck.isSelected());
} else if ("Multiple Interval Selection" == command) {
table.setSelectionMode(
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
//If cell selection is on, turn it off.
if (cellCheck.isSelected()) {
cellCheck.setSelected(false);
table.setCellSelectionEnabled(false);
}
//And don't let it be turned back on.
cellCheck.setEnabled(false);
} else if ("Single Interval Selection" == command) {
table.setSelectionMode(
ListSelectionModel.SINGLE_INTERVAL_SELECTION);
//Cell selection is ok in this mode.
cellCheck.setEnabled(true);
} else if ("Single Selection" == command) {
table.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
//Cell selection is ok in this mode.
cellCheck.setEnabled(true);
}
//Update checkboxes to reflect selection mode side effects.
rowCheck.setSelected(table.getRowSelectionAllowed());
columnCheck.setSelected(table.getColumnSelectionAllowed());
if (cellCheck.isEnabled()) {
cellCheck.setSelected(table.getCellSelectionEnabled());
}
}
private void outputSelection() {
output.append(String.format("Lead: %d, %d. ",
table.getSelectionModel().getLeadSelectionIndex(),
table.getColumnModel().getSelectionModel().
getLeadSelectionIndex()));
output.append("Rows:");
for (int c : table.getSelectedRows()) {
output.append(String.format(" %d", c));
}
output.append(". Columns:");
for (int c : table.getSelectedColumns()) {
output.append(String.format(" %d", c));
}
output.append(".\n");
}
@Override
public void itemStateChanged(ItemEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void tableChanged(TableModelEvent e) {
int rivi = e.getFirstRow();
int sarake = e.getColumn();
TableModel malli = (TableModel)e.getSource();
String sarakeNimi = malli.getColumnName(sarake);
Object data = malli.getValueAt(rivi, sarake);
MyTableModel taulumalli = new MyTableModel();
taulumalli.setValueAt(data, rivi, sarake);
System.out.println("rivi: " + rivi + " sarake: " + sarake + " data: " + data);
}
private void setValueAt(Object data, int rivi, int sarake) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
private class RowListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent event) {
if (event.getValueIsAdjusting()) {
return;
}
output.append("ROW SELECTION EVENT. ");
outputSelection();
}
}
private class ColumnListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent event) {
if (event.getValueIsAdjusting()) {
return;
}
output.append("COLUMN SELECTION EVENT. ");
outputSelection();
}
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
private Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown",
"Pool", new Integer(10), 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];
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public boolean isCellEditable(int row, int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
if (col < 2) {
return false;
} else {
return true;
}
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
public JMenuBar luoValikkoPalkki() {
JMenuBar valikkopalkki = new JMenuBar();
JMenu valikko = new JMenu("File");
valikko.setMnemonic(KeyEvent.VK_F);
valikko.getAccessibleContext().setAccessibleDescription(
"File saving menu");
valikkopalkki.add(valikko);
JMenuItem valikkoitem = new JMenuItem("Save", KeyEvent.VK_S);
valikkoitem.setAccelerator(KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_S, ActionEvent.CTRL_MASK));
valikkoitem.addActionListener(this);
valikko.add(valikkoitem);
return valikkopalkki;
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
//Disable boldface controls.
UIManager.put("swing.boldMetal", Boolean.FALSE);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
//Create and set up the window.
JFrame frame = new JFrame("Neliöjuuri");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Neliojuuri neliojuuri = new Neliojuuri();
frame.setJMenuBar(neliojuuri.luoValikkoPalkki());
//Create and set up the content pane.
Neliojuuri newContentPane = new Neliojuuri();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
堆栈跟踪:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 5
at fi.allu.neliojuuri.Neliojuuri$MyTableModel.setValueAt(Neliojuuri.java:356)
at fi.allu.neliojuuri.Neliojuuri.tableChanged(Neliojuuri.java:261)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableCellUpdated(AbstractTableModel.java:275)
at javax.swing.table.DefaultTableModel.setValueAt(DefaultTableModel.java:666)
at javax.swing.JTable.setValueAt(JTable.java:2744)
at javax.swing.JTable.editingStopped(JTable.java:4729)
at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:141)
at javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(DefaultCellEditor.java:368)
at javax.swing.DefaultCellEditor.stopCellEditing(DefaultCellEditor.java:233)
at javax.swing.JTable$GenericEditor.stopCellEditing(JTable.java:5473)
at javax.swing.DefaultCellEditor$EditorDelegate.actionPerformed(DefaultCellEditor.java:385)
at javax.swing.JTextField.fireActionPerformed(JTextField.java:508)
at javax.swing.JTextField.postActionEvent(JTextField.java:721)
at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:836)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1668)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2882)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2929)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2845)
at java.awt.Component.processEvent(Component.java:6316)
at java.awt.Container.processEvent(Container.java:2239)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:835)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1103)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:974)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:800)
at java.awt.Component.dispatchEventImpl(Component.java:4760)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
at java.awt.EventQueue.run(EventQueue.java:733)
at java.awt.EventQueue.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
我希望能够更改 table 中的所有单元格值,但我只能更改其中的一部分。索引大于或等于 5 的单元格 return ArrayIndexOutOfBounds 错误。
Cells with index greater than or equal to 5 return ArrayIndexOutOfBounds error.
因为你创建你的"MyTableModel"里面只有5行数据。如果模型中存在 row/column,您只能更改数据。
您为什么要使用 Swing 教程中的 "MyTableModel" 作为您的 TableModel?
此外,为什么每次生成 "tableChanged" 事件时都要创建一个新的 "MyTableModel"?这意味着您将丢失之前的更改。
我建议,如果您尝试将数据从一个 table 复制到另一个,那么您需要创建一个 DefaultTableModel
,其中 row/column 的数量与现有的相同在生成 "tableChanged" 事件的其他 TableModel 中。
但在不了解您的真实需求的情况下,我们无法给出合适的解决方案,只能排除错误。
当执行到 tableChanged()
内的第 taulumalli.setValueAt(data, rivi, sarake);
行时,有 2 个 table 模型。
第一个 table 模型由行 table = new JTable(ulkoinen, sarakenimet);
创建。这个模型实际上连接到显示的table。它有 70 行和 70 列。
第二个 table 模型是在 tableChanged()
中通过行 MyTableModel taulumalli = new MyTableModel();
创建的。尽管这是一个 table 模型,但它没有连接到任何 table。这有 5 行和 5 列。
当用户编辑 table 中的值时,将调用 tableChanged()
。在这个方法中,在前两行中,你得到的行索引和列索引来自第一个 table 模型(因为显示的 table 连接到这个 table 模型)。然后将第一个 table 模型的这些行索引和列索引传递给第二个 table 模型的 setValueAt()
。这是不正确的,因为 2 table 模型具有不同的结构。这会导致错误。
我有一个 JTable 应用程序。我需要更改单元格值并保存数据,但只有索引小于或等于 4 的单元格在数组范围内。
package fi.allu.neliojuuri;
import com.sun.glass.events.KeyEvent;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import javax.swing.event.CellEditorListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
public class Neliojuuri extends JPanel
implements ActionListener, ItemListener, TableModelListener {
String newline = "\n";
private JTable table;
private JCheckBox rowCheck;
private JCheckBox columnCheck;
private JCheckBox cellCheck;
private ButtonGroup buttonGroup;
private JTextArea output;
private String[] sarakenimet = new String[70];
private String[] sisakkainen = new String[70];
private Object[][] ulkoinen = new String[71][71];
private DefaultTableModel oletusmalli = null;
private CellEditorListener solumuokkaaja = null;
public Neliojuuri() {
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
for (int i = 0; i < 70; i++) {
sarakenimet[i] = String.valueOf(i + 1);
}
for (int i = 0; i < sisakkainen.length; i++) {
sisakkainen[i] = String.valueOf(i + 1);
}
for (int i = 0; i < ulkoinen.length; i++) {
ulkoinen[i] = sisakkainen;
}
table = new JTable(ulkoinen, sarakenimet);
table.setPreferredScrollableViewportSize(new Dimension(500, 210));
table.setFillsViewportHeight(true);
table.setRowHeight(30);
TableColumnModel sarakeMalli = table.getColumnModel();
for (int i = 0; i < 70; i++) {
sarakeMalli.getColumn(i).setPreferredWidth(75);
}
oletusmalli = new javax.swing.table.DefaultTableModel();
table.setModel(oletusmalli);
String[] sarakenimet = new String[70];
for (int i = 0; i < 70; i++) {
sarakenimet[i] = String.valueOf(i + 1);
}
String[] sisakkainen = new String[70];
for (int i = 0; i < sisakkainen.length; i++) {
sisakkainen[i] = String.valueOf(i + 1);
}
Object[][] ulkoinen = new String[71][71];
for (int i = 0; i < ulkoinen.length; i++) {
ulkoinen[i] = sisakkainen;
}
oletusmalli.setColumnIdentifiers(sarakenimet);
for (int count = 0; count < 70; count++){
oletusmalli.insertRow(count, sisakkainen);
}
table.getSelectionModel().addListSelectionListener(new RowListener());
table.getColumnModel().getSelectionModel().
addListSelectionListener(new ColumnListener());
add(new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getModel().addTableModelListener(this);
add(new JLabel("Selection Mode"));
buttonGroup = new ButtonGroup();
addRadio("Multiple Interval Selection").setSelected(true);
addRadio("Single Selection");
addRadio("Single Interval Selection");
add(new JLabel("Selection Options"));
rowCheck = addCheckBox("Row Selection");
rowCheck.setSelected(true);
columnCheck = addCheckBox("Column Selection");
cellCheck = addCheckBox("Cell Selection");
cellCheck.setEnabled(false);
output = new JTextArea(5, 40);
output.setEditable(false);
output.setFont(new Font("Segoe UI", Font.PLAIN, 20));
add(new JScrollPane(output));
}
private JCheckBox addCheckBox(String text) {
JCheckBox checkBox = new JCheckBox(text);
checkBox.addActionListener(this);
add(checkBox);
return checkBox;
}
private JRadioButton addRadio(String text) {
JRadioButton b = new JRadioButton(text);
b.addActionListener(this);
buttonGroup.add(b);
add(b);
return b;
}
public void actionPerformed(ActionEvent e) {
JFileChooser tiedostovalitsin = new JFileChooser();
JMenuItem source = (JMenuItem)(e.getSource());
if (source.getText() == "Save") {
int palautusArvo = tiedostovalitsin.showSaveDialog(Neliojuuri.this);
if (palautusArvo == JFileChooser.APPROVE_OPTION) {
File tiedosto = tiedostovalitsin.getSelectedFile();
// Tallenna tiedosto oikeasti
for (int i = 0; i < oletusmalli.getRowCount(); i++) {
System.out.println(oletusmalli.getValueAt(1, i).toString());
}
System.out.println(tiedosto.getName());
}
}
String command = e.getActionCommand();
//Cell selection is disabled in Multiple Interval Selection
//mode. The enabled state of cellCheck is a convenient flag
//for this status.
if ("Row Selection" == command) {
table.setRowSelectionAllowed(rowCheck.isSelected());
//In MIS mode, column selection allowed must be the
//opposite of row selection allowed.
if (!cellCheck.isEnabled()) {
table.setColumnSelectionAllowed(!rowCheck.isSelected());
}
} else if ("Column Selection" == command) {
table.setColumnSelectionAllowed(columnCheck.isSelected());
//In MIS mode, row selection allowed must be the
//opposite of column selection allowed.
if (!cellCheck.isEnabled()) {
table.setRowSelectionAllowed(!columnCheck.isSelected());
}
} else if ("Cell Selection" == command) {
table.setCellSelectionEnabled(cellCheck.isSelected());
} else if ("Multiple Interval Selection" == command) {
table.setSelectionMode(
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
//If cell selection is on, turn it off.
if (cellCheck.isSelected()) {
cellCheck.setSelected(false);
table.setCellSelectionEnabled(false);
}
//And don't let it be turned back on.
cellCheck.setEnabled(false);
} else if ("Single Interval Selection" == command) {
table.setSelectionMode(
ListSelectionModel.SINGLE_INTERVAL_SELECTION);
//Cell selection is ok in this mode.
cellCheck.setEnabled(true);
} else if ("Single Selection" == command) {
table.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
//Cell selection is ok in this mode.
cellCheck.setEnabled(true);
}
//Update checkboxes to reflect selection mode side effects.
rowCheck.setSelected(table.getRowSelectionAllowed());
columnCheck.setSelected(table.getColumnSelectionAllowed());
if (cellCheck.isEnabled()) {
cellCheck.setSelected(table.getCellSelectionEnabled());
}
}
private void outputSelection() {
output.append(String.format("Lead: %d, %d. ",
table.getSelectionModel().getLeadSelectionIndex(),
table.getColumnModel().getSelectionModel().
getLeadSelectionIndex()));
output.append("Rows:");
for (int c : table.getSelectedRows()) {
output.append(String.format(" %d", c));
}
output.append(". Columns:");
for (int c : table.getSelectedColumns()) {
output.append(String.format(" %d", c));
}
output.append(".\n");
}
@Override
public void itemStateChanged(ItemEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void tableChanged(TableModelEvent e) {
int rivi = e.getFirstRow();
int sarake = e.getColumn();
TableModel malli = (TableModel)e.getSource();
String sarakeNimi = malli.getColumnName(sarake);
Object data = malli.getValueAt(rivi, sarake);
MyTableModel taulumalli = new MyTableModel();
taulumalli.setValueAt(data, rivi, sarake);
System.out.println("rivi: " + rivi + " sarake: " + sarake + " data: " + data);
}
private void setValueAt(Object data, int rivi, int sarake) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
private class RowListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent event) {
if (event.getValueIsAdjusting()) {
return;
}
output.append("ROW SELECTION EVENT. ");
outputSelection();
}
}
private class ColumnListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent event) {
if (event.getValueIsAdjusting()) {
return;
}
output.append("COLUMN SELECTION EVENT. ");
outputSelection();
}
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
private Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown",
"Pool", new Integer(10), 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];
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public boolean isCellEditable(int row, int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
if (col < 2) {
return false;
} else {
return true;
}
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
public JMenuBar luoValikkoPalkki() {
JMenuBar valikkopalkki = new JMenuBar();
JMenu valikko = new JMenu("File");
valikko.setMnemonic(KeyEvent.VK_F);
valikko.getAccessibleContext().setAccessibleDescription(
"File saving menu");
valikkopalkki.add(valikko);
JMenuItem valikkoitem = new JMenuItem("Save", KeyEvent.VK_S);
valikkoitem.setAccelerator(KeyStroke.getKeyStroke(
java.awt.event.KeyEvent.VK_S, ActionEvent.CTRL_MASK));
valikkoitem.addActionListener(this);
valikko.add(valikkoitem);
return valikkopalkki;
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
//Disable boldface controls.
UIManager.put("swing.boldMetal", Boolean.FALSE);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
//Create and set up the window.
JFrame frame = new JFrame("Neliöjuuri");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Neliojuuri neliojuuri = new Neliojuuri();
frame.setJMenuBar(neliojuuri.luoValikkoPalkki());
//Create and set up the content pane.
Neliojuuri newContentPane = new Neliojuuri();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
堆栈跟踪:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 5
at fi.allu.neliojuuri.Neliojuuri$MyTableModel.setValueAt(Neliojuuri.java:356)
at fi.allu.neliojuuri.Neliojuuri.tableChanged(Neliojuuri.java:261)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableCellUpdated(AbstractTableModel.java:275)
at javax.swing.table.DefaultTableModel.setValueAt(DefaultTableModel.java:666)
at javax.swing.JTable.setValueAt(JTable.java:2744)
at javax.swing.JTable.editingStopped(JTable.java:4729)
at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:141)
at javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(DefaultCellEditor.java:368)
at javax.swing.DefaultCellEditor.stopCellEditing(DefaultCellEditor.java:233)
at javax.swing.JTable$GenericEditor.stopCellEditing(JTable.java:5473)
at javax.swing.DefaultCellEditor$EditorDelegate.actionPerformed(DefaultCellEditor.java:385)
at javax.swing.JTextField.fireActionPerformed(JTextField.java:508)
at javax.swing.JTextField.postActionEvent(JTextField.java:721)
at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:836)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1668)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2882)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2929)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2845)
at java.awt.Component.processEvent(Component.java:6316)
at java.awt.Container.processEvent(Container.java:2239)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:835)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1103)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:974)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:800)
at java.awt.Component.dispatchEventImpl(Component.java:4760)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
at java.awt.EventQueue.run(EventQueue.java:733)
at java.awt.EventQueue.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
我希望能够更改 table 中的所有单元格值,但我只能更改其中的一部分。索引大于或等于 5 的单元格 return ArrayIndexOutOfBounds 错误。
Cells with index greater than or equal to 5 return ArrayIndexOutOfBounds error.
因为你创建你的"MyTableModel"里面只有5行数据。如果模型中存在 row/column,您只能更改数据。
您为什么要使用 Swing 教程中的 "MyTableModel" 作为您的 TableModel?
此外,为什么每次生成 "tableChanged" 事件时都要创建一个新的 "MyTableModel"?这意味着您将丢失之前的更改。
我建议,如果您尝试将数据从一个 table 复制到另一个,那么您需要创建一个 DefaultTableModel
,其中 row/column 的数量与现有的相同在生成 "tableChanged" 事件的其他 TableModel 中。
但在不了解您的真实需求的情况下,我们无法给出合适的解决方案,只能排除错误。
当执行到 tableChanged()
内的第 taulumalli.setValueAt(data, rivi, sarake);
行时,有 2 个 table 模型。
第一个 table 模型由行 table = new JTable(ulkoinen, sarakenimet);
创建。这个模型实际上连接到显示的table。它有 70 行和 70 列。
第二个 table 模型是在 tableChanged()
中通过行 MyTableModel taulumalli = new MyTableModel();
创建的。尽管这是一个 table 模型,但它没有连接到任何 table。这有 5 行和 5 列。
当用户编辑 table 中的值时,将调用 tableChanged()
。在这个方法中,在前两行中,你得到的行索引和列索引来自第一个 table 模型(因为显示的 table 连接到这个 table 模型)。然后将第一个 table 模型的这些行索引和列索引传递给第二个 table 模型的 setValueAt()
。这是不正确的,因为 2 table 模型具有不同的结构。这会导致错误。