我想做的事:
我想列出数据库的一些记录。此列表应显示在 JFrame 弹出窗口中。
描述:
我有 3 节课:
- Main.java(运行程序)
- PeopleTableModel.java(保存数据,扩展 AbstractTableModel)
- PeopleTable.java(保存逻辑,扩展 JTable)
为什么在将 JFrame 设置为可见时出现 ArrayIndexOutOfBoundsException?
更新:
当我使用自己的 PeopleTable 类时,似乎只出现此错误。当我将表分配给普通的 JTable 时,它可以工作。
这是我得到的堆栈跟踪:
java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:470)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:294)
at javax.swing.JTable.getCellRect(JTable.java:2969)
at javax.swing.plaf.basic.BasicTableUI.createTableSize(BasicTableUI.java:1694)
at javax.swing.plaf.basic.BasicTableUI.getPreferredSize(BasicTableUI.java:1733)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1660)
at javax.swing.ScrollPaneLayout.preferredLayoutSize(ScrollPaneLayout.java:495)
at java.awt.Container.preferredSize(Container.java:1788)
at java.awt.Container.getPreferredSize(Container.java:1773)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1662)
at java.awt.BorderLayout.preferredLayoutSize(BorderLayout.java:719)
at java.awt.Container.preferredSize(Container.java:1788)
at java.awt.Container.getPreferredSize(Container.java:1773)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1662)
at javax.swing.JRootPane$RootLayout.preferredLayoutSize(JRootPane.java:917)
at java.awt.Container.preferredSize(Container.java:1788)
at java.awt.Container.getPreferredSize(Container.java:1773)
at javax.swing.JComponent.getPreferredSize(JComponent.java:1662)
at java.awt.BorderLayout.preferredLayoutSize(BorderLayout.java:719)
at java.awt.Container.preferredSize(Container.java:1788)
at java.awt.Container.getPreferredSize(Container.java:1773)
at java.awt.Window.pack(Window.java:809)
at ch.bs.jsd.personen.Main.main(Main.java:67)
这是我的全部代码:
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.sql.ResultSet;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
public class Main {
public static void main(String[] args) {
ArrayList<String[]> result = new ArrayList<String[]>();
SQLConnection sql = new SQLConnection();
String OBNr = "";
String firstName = "";
String lastName = "";
String qry = "SELECT loginid,ctitle as Grad,"
+ "name+' '+firstname as SachB,"
+ "cposition as Tour,Ressort,"
+ "left(location,2) as FNr "
+ "FROM dbo.abf_muPostenAdressen "
+ "WHERE loginid LIKE '%" + OBNr + "%'"
+ "AND name LIKE '%" + lastName + "%'"
+ "AND firstname LIKE '%" + firstName + "%'";
try {
ResultSet rs = sql.getConnection().prepareStatement(qry).executeQuery();
while (rs.next()) {
result.add(new String[]{
Integer.toString(rs.getRow()),
rs.getString("loginid"),
rs.getString("Grad"),
rs.getString("SachB"),
rs.getString("Tour"),
rs.getString("Ressort"),
rs.getString("FNr")
});
}
if (result.size() != 0) {
String[] selectedData = null;
if (result.size() > 1) {
String[] title = {"#", "loginid", "Grad", "SachB", "Tour",
"Ressort", "FNr"};
TableModel model = new PeopleTableModel(title, parse_2d_array(result));
JTable table = new PeopleTable(model);
JFrame frame = new JFrame();
frame.getContentPane().add(new JScrollPane(table));
frame.setVisible(true);
while (table.getSelectedRow() != -1) {
}
selectedData = result.get(table.getSelectedRow());
frame.dispose();
} else {
selectedData = result.get(0);
}
System.out.println(join(selectedData, ", "));
}
} catch (Exception e) {
e.printStackTrace();
}
sql.closeConnection();
}
private static String join(String[] s, String delimiter) {
if (s.length == 0) {
return null;
}
StringBuilder out = new StringBuilder();
out.append(s[0]);
for (int i = 1; i < s.length; ++i) {
out.append(delimiter).append(s[i]);
}
return out.toString();
}
private static String[][] parse_2d_array(ArrayList<String[]> al) {
String[][] data = new String[al.size()][6];
for (int i = 0; i < al.size(); i++) {
data[i] = al.get(i);
}
return data;
}
}
class PeopleTableModel extends AbstractTableModel {
private static final long serialVersionUID = -1080095595481949205L;
private String[] title;
private Object[][] data;
public PeopleTableModel(String[] title, Object[][] data) {
this.title = title;
this.data = data;
}
@Override
public int getColumnCount() {
return title.length;
}
@Override
public int getRowCount() {
return data.length;
}
@Override
public Object getValueAt(int row, int col) {
return data[row][col];
}
@Override
public String getColumnName(int column) {
return title[column];
}
}
class PeopleTable extends JTable {
private static final long serialVersionUID = -1080095595481949205L;
private JTable table;
private int selectedRow = -1;
private StringBuilder pressedKeys = new StringBuilder();
private long now = 0;
private long last = 0;
public PeopleTable(TableModel model) {
table = new JTable(model);
table.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
public void mouseClicked(java.awt.event.MouseEvent e) {
if (e.getClickCount() == 2) {
setSelectedRow(table.rowAtPoint(e.getPoint()));
}
}
});
table.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent evt) {
}
@Override
public void keyReleased(KeyEvent evt) {
}
@Override
public void keyPressed(KeyEvent evt) {
int key = evt.getKeyCode();
// add only numbers
if ((key > 47 && key < 58) || (key > 95 && key < 106)) {
last = now == 0 ? 0 : now;
now = evt.getWhen();
if (now - last > 700) {
pressedKeys = new StringBuilder();
}
pressedKeys.append(evt.getKeyChar());
int row = Integer.parseInt(pressedKeys.toString()) - 1;
table.setRowSelectionInterval(row, row);
table.scrollRectToVisible(table.getCellRect(row, 0, true));
} else if (key == KeyEvent.VK_ENTER) {
if (pressedKeys.length() == 0) {
pressedKeys.append(1);
}
setSelectedRow(Integer.parseInt(pressedKeys.toString()) - 1);
}
}
});
}
public JTable getTable() {
return table;
}
private void setSelectedRow(int i) {
selectedRow = i;
}
@Override
public int getSelectedRow() {
return selectedRow;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public int getColumnCount() {
return table.getColumnCount();
}
@Override
public int getRowCount() {
return table.getRowCount();
}
@Override
public Object getValueAt(int row, int col) {
return table.getValueAt(row, col);
}
}
附加问题:是否有更好的方法来实现我的目标,或者这可以说是最佳实践?