java - ResultSet 填充 JTable 列名称但不填充数据

标签 java mysql swing prepared-statement resultset

注意:这不是重复的,我已经 checkout :I can't get my JTable to show anythingI get the Jtable but no data

尽管这些问题看起来非常相似,但它们与我遇到的问题并不相同。让我解释一下:

我有一个 GUI,其中有几个从 MySQL 数据库填充的 JTable。在我最初的 GUI 上,该表工作正常。然而,有一次我将用户带到一个新的 JFrame。在此框架上,由于某种原因,显示了表格并填充了列名称,但没有数据。我一生都无法弄清楚为什么。

这是我的第一个可以运行的 GUI 中的代码:

 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);

我的 writeItemResult 方法:

public static DefaultTableModel writeItemResult (ResultSet res4) throws SQLException {

    ResultSetMetaData metaData = res4.getMetaData();

    Vector<String> columnNames = new Vector<String>();
    int columnCount = metaData.getColumnCount();
    for (int column = 1; column <= columnCount; column++) {
        columnNames.add(metaData.getColumnName(column));
    }

    Vector<Vector<Object>> data = new Vector<Vector<Object>>();
    while (res4.next()) {
        Vector<Object> vector = new Vector<Object>();
        for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
            vector.add(res4.getObject(columnIndex));
        }
        data.add(vector);
    }
    return new DefaultTableModel(data, columnNames);
}

我的 res4 结果集:

statement2 = connect.createStatement();
res4 = statement2.executeQuery("SELECT id, prompt, type FROM items ORDER BY prompt");

所以,正如我所说,上面的代码对于我的第一个 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();
  }
  }

如果您好奇,p_statement6 是:

p_statement6 = connect.prepareStatement("SELECT * from checklists where id = ?");

顺便说一句,我没有收到任何错误。

splinter 的 table 图片: broken

工作台图片:working

所以,这就是我认为适用的一切。如果您需要更多信息,请随时询问。

解决方案

感谢@peeskillet,我的问题的解决方案非常简单:我试图使用耗尽的结果集。通过简单设置结果集Scroll_Insensitive和Concur_Updatable,问题就解决了。

最佳答案

看起来您正在尝试对两个表使用相同的 ResultSet

 new JTable(writeItemResult(res4));

这两个表都使用res4。问题是第一个方法可以正常工作,但它会耗尽 ResultSet 中的数据。数据已经跑通了。因此,尝试在第二个 writeItemResult(res4) 中执行 rs.next() 只会返回列标题,因为这只是元数据

A default ResultSet object is not updatable and has a cursor that moves forward only. Thus, you can iterate through it only once and only from the first row to the last row. It is possible to produce ResultSet objects that are scrollable and/or updatable.The following code fragment, in which con is a valid Connection object, illustrates how to make a result set that is scrollable and insensitive to updates by others, and that is updatable.

   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
  • static final int TYPE_SCROLL_INSENSITIVE - 该常量指示 ResultSet 对象的类型,该对象可滚动,但通常对 ResultSet 底层数据的更改不敏感。
  • static final int CONCUR_READ_ONLY - 指示可能无法更新的 ResultSet 对象的并发模式的常量。

因此,您必须执行上述操作才能使 ResultSet 可滚动。那么你需要使用

  • void beforeFirst() throws SQLException - 将光标移动到此 ResultSet 对象的前面,就在第一行之前。如果结果集不包含行,则此方法无效。

因此,如果您只是将 res4.beforeFirst() 放入 writeItemResult() 中,它也应该适用于第二个表。

<小时/>

另外,顺便说一句,如果您希望表使用相同的数据,为什么不让它们共享相同的 TableModel

table2.setModel(table1.getModel());

关于java - ResultSet 填充 JTable 列名称但不填充数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21150934/

相关文章:

java - JTable 的 setSelectedRow() 在哪里?

java - 如何搜索和过滤 fragment 中的文本

java - $ bin/hadoop namenode -format STARTUP_MSG : host = java.net.UnknownHostException:

Mysql 查询,每个列具有不同类别的子查询

java - 如何在 Java Swing 中设置相同的按钮大小?

java - 如何模拟 swing 弹出对话框中的按钮单击?

java - 如何测试返回复杂对象的函数?

java - IBM i (AS400) JVM - 是否可以定义 JVM 查找 .jar 文件的位置?

mysql - mysql中"Read Only Database"vs "Read and Write database"配置

mysql - $wpdb->get_results 问题