我想做的事:
我想列出数据库的一些记录。此列表应显示在 JFrame弹出窗口中。
描述:
我有3节课:
将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)
And this is my whole code:
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); } }
Additional question: Is there a better way to achieve my goal or could this be stated as best practise?
参见JTable教程,那里有所有描述
我看不到有使用的理由AbstractTableModel,不知道为什么要麻烦JTable包含真正数量的行和列(最多500/ 1000&20/ 50),DefaultTableModel而从
AbstractTableModel
500/ 1000&20/ 50
DefaultTableModel
或DefaultTableModel使用此AbstractTableModel进行更改
可以开始
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.border.LineBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.*; public class RemoveAddRows extends JFrame { private static final long serialVersionUID = 1L; private Object[] columnNames = {"Type", "Company", "Shares", "Price"}; private Object[][] data = { {"Buy", "IBM", new Integer(1000), new Double(80.50)}, {"Sell", "MicroSoft", new Integer(2000), new Double(6.25)}, {"Sell", "Apple", new Integer(3000), new Double(7.35)}, {"Buy", "Nortel", new Integer(4000), new Double(20.00)} }; private JTable table; private DefaultTableModel model; private javax.swing.Timer timer = null; public RemoveAddRows() { model = new DefaultTableModel(data, columnNames) { private static final long serialVersionUID = 1L; @Override public Class getColumnClass(int column) { return getValueAt(0, column).getClass(); } }; table = new JTable(model) { private static final long serialVersionUID = 1L; @Override public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { Component c = super.prepareRenderer(renderer, row, column); if (isRowSelected(row) && isColumnSelected(column)) { ((JComponent) c).setBorder(new LineBorder(Color.red)); } return c; } }; ListSelectionModel rowSelMod = table.getSelectionModel(); rowSelMod.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { int row = table.getSelectedRow(); int col = table.getSelectedColumn(); String str = "Selected Row(s): "; int[] rows = table.getSelectedRows(); for (int i = 0; i < rows.length; i++) { str += rows[i] + " "; } str += "Selected Column(s): "; int[] cols = table.getSelectedColumns(); for (int i = 0; i < cols.length; i++) { str += cols[i] + " "; } str += "Selected Cell: " + table.getSelectedRow() + ", " + table.getSelectedColumn(); System.out.println(str); Object value = table.getValueAt(row, col); System.out.println(String.valueOf(value)); } }); table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane); JButton button1 = new JButton("Remove all rows"); button1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { if (model.getRowCount() > 0) { for (int i = model.getRowCount() - 1; i > -1; i--) { model.removeRow(i); } } System.out.println("model.getRowCount() --->" + model.getRowCount()); } }); JButton button2 = new JButton("Add new rows"); button2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { start(); } }); JPanel southPanel = new JPanel(); southPanel.add(button1); southPanel.add(button2); add(southPanel, BorderLayout.SOUTH); } private void start() { timer = new javax.swing.Timer(2500, updateCol()); timer.start(); } public Action updateCol() { return new AbstractAction("text load action") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { DefaultTableModel model = (DefaultTableModel) table.getModel(); Object[] data0 = {"Buy", "IBM", new Integer(1000), new Double(80.50)}; model.addRow(data0); Object[] data1 = {"Sell", "MicroSoft", new Integer(2000), new Double(6.25)}; model.addRow(data1); Object[] data2 = {"Sell", "Apple", new Integer(3000), new Double(7.35)}; model.addRow(data2); Object[] data3 = {"Buy", "Nortel", new Integer(4000), new Double(20.00)}; model.addRow(data3); System.out.println("model.getRowCount() --->" + model.getRowCount()); timer.stop(); int rowIndex = table.getRowCount() - 1; table.changeSelection(rowIndex, 0, false, false); } }; } public static void main(String[] args) { try { for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { System.out.println(info.getName()); if ("Nimbus".equals(info.getName())) { UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (UnsupportedLookAndFeelException e) { // handle exception } catch (ClassNotFoundException e) { // handle exception } catch (InstantiationException e) { // handle exception } catch (IllegalAccessException e) { // handle exception } javax.swing.SwingUtilities.invokeLater(new Runnable() { @Override public void run() { RemoveAddRows frame = new RemoveAddRows(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } }