Java 填充JTable列名但不填充数据的结果集
注意:这不是重复的,我已经签出:和 虽然这些问题看起来非常相似,但它们与我所经历的不一样。让我解释一下: 我有一个GUI,其中有几个JTables是从MySQL数据库填充的。在我最初的GUI上,表运行良好。然而,有一次我将用户带到一个新的JFrame。在这个框架中,由于某种原因,表显示出来,并且填充了列名,但没有数据。我一辈子都不知道为什么 以下是我的第一个GUI的代码:Java 填充JTable列名但不填充数据的结果集,java,mysql,swing,prepared-statement,resultset,Java,Mysql,Swing,Prepared Statement,Resultset,注意:这不是重复的,我已经签出:和 虽然这些问题看起来非常相似,但它们与我所经历的不一样。让我解释一下: 我有一个GUI,其中有几个JTables是从MySQL数据库填充的。在我最初的GUI上,表运行良好。然而,有一次我将用户带到一个新的JFrame。在这个框架中,由于某种原因,表显示出来,并且填充了列名,但没有数据。我一辈子都不知道为什么 以下是我的第一个GUI的代码: iTable = new JTable(writeItemResult(res4)); iTable.setAutoRe
iTable = new JTable(writeItemResult(res4));
iTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
iTable.getColumnModel().getColumn(0).setPreferredWidth(27);
iTable.getColumnModel().getColumn(1).setPreferredWidth(375);
iTable.getColumnModel().getColumn(2).setPreferredWidth(150);
iTable.getColumnModel().getColumn(0).setResizable(false);
sorter = new TableRowSorter<TableModel>(iTable.getModel());
iTable.setRowSorter(sorter);
JScrollPane scrollpane3 = new JScrollPane(iTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollpane3.setPreferredSize(new Dimension(500, 150));
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 16;
c.gridwidth = 6;
pane.add(scrollpane3, c);
因此,正如我所说的,上面的代码对于我的第一个JFrame很好。我的第一个JFrame的整个代码太大了,所以除非特别要求,否则我不会粘贴它
下面是我的第二个JFrame的完整代码,正如我所说,它返回表名和列名,但不返回数据:
} if (e.getSource() == design) {
int str = fTable.getSelectedRow();
int stc = fTable.getSelectedColumn();
if (stc != 0) {
JOptionPane.showMessageDialog(null, "Error: Please click the Form ID of the form you wish to modify.", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
selObj = (Object) fTable.getModel().getValueAt(str, stc);
try {
p_statement6.setString(1, selObj.toString());
res6 = p_statement6.executeQuery();
} catch (SQLException e1) {
e1.printStackTrace();
}
try {
while (res6.next()){
formID1 = res6.getString("id");
formName1 = res6.getString("title");
}
} catch (SQLException e1) {
e1.printStackTrace();
}
int width = 900;
int height = 900;
designForm = new JFrame("Designer");
designForm.setSize(width,height);
pane = designForm.getContentPane();
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
//natural height, maximum width
c.fill = GridBagConstraints.HORIZONTAL;
}
des_name = new JLabel("<html><small>Designing: "+formName1+"</small></html>");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
pane.add(des_name, c);
test = new JButton("Test");
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
pane.add(test, c);
test.addActionListener(this);
designForm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension sD = Toolkit.getDefaultToolkit().getScreenSize();
designForm.setLocation((sD.width - width)/2, (sD.height-height)/2);
designForm.setResizable(true);
designForm.setVisible(true);
} if (e.getSource() == test) {
try {
iTable = new JTable(writeItemResult(res4));
iTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
iTable.getColumnModel().getColumn(0).setPreferredWidth(27);
iTable.getColumnModel().getColumn(1).setPreferredWidth(330);
iTable.getColumnModel().getColumn(2).setPreferredWidth(140);
iTable.getColumnModel().getColumn(0).setResizable(false);
sorter = new TableRowSorter<TableModel>(iTable.getModel());
iTable.setRowSorter(sorter);
JScrollPane scrollpane4 = new JScrollPane(iTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollpane4.setPreferredSize(new Dimension(500, 150));
JOptionPane.showMessageDialog(null, scrollpane4);
} catch (Exception e1) {
e1.printStackTrace();
}
}
顺便说一下,我没有发现任何错误
损坏表格的图像:
工作台图像:
所以,这就是我认为适用的一切。如果您需要更多信息,请随时询问
解决方案
多亏了@peeskillet,我的问题的解决方案非常简单:我试图使用一个精疲力竭的结果集。只需将结果集Scroll\u设置为不敏感且Concur\u可更新,问题就解决了。此处:
int str = fTable.getSelectedRow();
int stc = fTable.getSelectedColumn();
...
selObj = (Object) fTable.getModel().getValueAt(str, stc); // wrong indexes!!
这些索引属于视图。如果要从表模型中获取值,则需要将它们转换为各自的模型索引:
selObj = fTable.getModel().getValueAt(fTable.convertRowIndexToModel(str), fTable.convertColumnIndexToModel(stc));
或者,您可以直接从表中获取正确的选定值:
selObj = fTable.getValueAt(str, stc);
由于selObj.toString()
是查询参数,错误的值可能会导致ResultSet
为空。因此,表将不会被填充
见:
编辑 我还要检查一下:
p_statement6 = connect.prepareStatement("SELECT * from checklists where id = ?");
p_statement6.setString(1, selObj.toString()); // is id a VARCHAR or is NUMERIC?
您说您在这里没有任何错误,但准备好的语句将被解析为如下内容:
SELECT * from checklists where id = '1';
如果id
列是一个VARCHAR,那么它是可以的,但是如果它是一些数字类型,那么您可能会得到一个
如果是这种情况,则需要将selObj
转换为Integer
,并使用而不是setString()
:
看起来您试图对两个表使用相同的
ResultSet
new JTable(writeItemResult(res4));
这两个表都使用了res4
。这样做的问题是,第一种方法可以很好地工作,但它会耗尽结果集
中的数据。数据已经过了一遍。因此,在第二个writeItemResult(res4)
中尝试canrs.next()
将只返回列标题,因为这只是元数据
默认的ResultSet
对象是不可更新的,其光标仅向前移动。因此,您只能遍历它一次,并且只能从第一行到最后一行。可以生成可滚动和/或可更新的ResultSet对象。以下代码片段(其中con是有效的连接对象)说明了如何创建可滚动、对其他人的更新不敏感且可更新的结果集
-表示结果集对象的类型的常量,该对象可滚动,但通常对结果集基础数据的更改不敏感static final int TYPE\u SCROLL\u INSENSITIVE
-表示可能不会更新的ResultSet对象的并发模式的常量static final int CONCUR_READ_ONLY
ResultSet
可滚动。那么你需要使用
-将光标移动到此ResultSet对象的前面,就在第一行之前。如果结果集不包含行,则此方法无效void beforeFirst()抛出SQLException
res4.beforeFirst()
放入writeItemResult()
中,它也应该适用于第二个表
另一方面,如果希望表使用相同的数据,为什么不让它们共享相同的
表模型呢
table2.setModel(table1.getModel());
替换
selObj = (Object) fTable.getModel().getValueAt(str, stc);
借
及
借
你好,谢谢你的回答!不幸的是,你的解决方案都没有帮助。不,ID是int(5)。但是我确信这不是问题。@user2221125不客气!现在,您已经解决了最初的问题,并且根据您的评论,您可能面临着我所说的SQLException
。看看我的更新来摆脱这个。哇,我不敢相信我错过了关于结果集的那个。解决问题的方法是使其对滚动不敏感且可更新。非常感谢。
p_statement6.setInt(1, (Integer)selObj);
new JTable(writeItemResult(res4));
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
// rs will be scrollable, will not show changes made by others,
// and will be updatable
table2.setModel(table1.getModel());
selObj = (Object) fTable.getModel().getValueAt(str, stc);
selObj = (Object) fTable.getValueAt(str, stc);
iTable = new JTable(writeItemResult(res4));
iTable = new JTable(writeItemResult(res6));