Displaying data from database in JTable

此生再无相见时 提交于 2019-11-29 15:45:21

Download the source for SQuirreL SQl and have a look at the table implementation.

Some things to note:

Database tables aren't Java JTables. A table in a database is in fact a set (curse the fool who used the wrong term) with items and each item has properties (usually called "columns" which isn't a JColumn which explains why it's so hard to map the two).

A set can grow to any size. It has no intrinsic order. You can do lots of set operations on it like: union, difference, sub set.

Therefore, it's not a table, especially not a UI table.

There is no easy UI paradigm which maps "set" to "table". You can

  1. Load N records and page through the results.

  2. You can load more as the user scrolls down

  3. You can count the size of the set and adjust the scrollbar accordingly. As the user scrolls through the data, it is fetched from the DB and displayed.

Pros + cons:

Solution 1 is most simple to implement and the one which users hate most. Why do they need to wait to see data again when the go backwards? This is especially frustrating if each fetch takes 15 seconds. Page ... wait ... page ... oops! There it was! Damn! Wait wait wait ... back ... wait ... aaargh.

Also databases often have a hard time to page data. For some queries, performance can be disastrous.

Solution 2 is simple to implement, especially if you can keep the ResultSet open forever. But 100% of the time, you can't. It will start to fail if you keep it open for a couple of hours or a day. After that time, the DB will think "oh, it's dead, Jim" and close the connection and your user will get a nice error message and you will get an angry user.

So you need to page here, too, but not as often. On the positive side, users need not wait again for data they already have. One huge point: If the set contains millions of rows, users intuitively understand that they need to attack the problem from a different angle as they scroll down. Eventually, they will get tired and ask for a better solution (instead of being angry at you because your stupid program can't display 15 million rows in less than 0.0000000001s).

Solution 3 is worse than #2, again. If the table grows, the UI will become unusable: Even looking at the scroll know will move you to a random place in the table. So it makes your mouse useless. And your users angry.

So I usually try a solution which:

  1. Reads 1000 rows, max. Plus I stop after 100 rows (so the user has at least some data) if reading the rows takes more than 1 second. Usually, the query is slow and reading the result set takes virtually no time, but I like being defensive here.

  2. On top of each column is a filter and an "order by" which can be mapped directly to SQL. That way, I can make sure that if you want the data sorted by a column, it's sorted by all values (and not only those which you can see on the screen).

This allows users to chop huge amounts of data into meaningful sub sets.

Table From Database has a couple of ideas.

R. Simac

Maks,

Here is another example on generic sql to table implementation:

http://www.oreillynet.com/pub/a/oreilly/java/news/javaex_1000.html

It may be a good place to look for your answer.

Also, this local question/answer may help you with ResultSet size: Java JDBC Lazy-Loaded ResultSet

Hope this helps,

Robert

This blog post explains how to lazy load data into a table model: JTable Bound to a Database With Lazy Loading

Stephan

You want to use the DBTable component from the QuickTable project.

Check this SO answer with sample code usage.

Here's a class that extract data rows and columns from database.

Look at table = new JTable(rows(), columns());

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PrinterException;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import com.swtdesigner.SwingResourceManager;
import java.util.*;
import java.sql.*;
import javax.swing.*;
public class listing extends JDialog {


private JTable table;
public static Vector rows() {

    Vector data = new Vector();
    String sql= null;
    Connection C;


        try {

            DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
            C = (Connection) DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
                    "system", "manager");

            Statement stmt = C.createStatement();
            ResultSet rset = stmt.executeQuery("SELECT * FROM site ");
            ResultSetMetaData md = rset.getMetaData();
            int columns = md.getColumnCount();



            while (rset.next()) {
                Vector row = new Vector(columns);

                for (int i = 1; i <= columns; i++) {
                    row.addElement(rset.getObject(i));
                }

                data.addElement(row);

            }

            rset.close();
            stmt.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.println(e.getStackTrace());
        }

        //System.out.println("lignes :  "+data);
        return data;
}


   public static Vector columns()
    {   Connection c ;
        Vector cols = new Vector ();
        String sql2=null;
        try { 
            DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
            c = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
                    "system", "manager");

            sql2 = "select * from SITE";

            Statement stmt = c.createStatement();
            ResultSet rs = stmt.executeQuery(sql2);
            ResultSetMetaData md = rs.getMetaData();
            int columns = md.getColumnCount();

              //récupération des noms des colonnes dans la table site

            for (int i = 1; i <= columns; i++) {
            cols.addElement(md.getColumnName(i));
            }
           } catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.println(e.getStackTrace());
        }
        //System.out.println("colonnes ::: "+cols);
        return cols;
    }

public static void main(String args[]) {
    try {
        listing dialog = new listing();
        dialog.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        dialog.setVisible(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


public listing() {
    super();
    getContentPane().setLayout(null);
    setTitle("Listing de la table \"SITE\"");
    setBounds(100, 100, 500, 363);
    setResizable(false);

    final JLabel laTablesiteLabel = new JLabel();
    laTablesiteLabel.setText("La table \"SITE\" contient . . . ");
    laTablesiteLabel.setBounds(10, 34, 274, 16);
    getContentPane().add(laTablesiteLabel);

    final JLabel label = new JLabel();
    label.setIcon(SwingResourceManager.getIcon(listing.class, "/pictures/130.png"));
    label.setBounds(402, 18, 49, 48);
    getContentPane().add(label);

    final JButton okButton = new JButton();
    okButton.addActionListener(new ActionListener() {
        public void actionPerformed(final ActionEvent arg0) {
            dispose();
            setVisible(false);
        }


    });
    okButton.setIcon(SwingResourceManager.getIcon(listing.class, "/pictures/33-32x32.png"));
    okButton.setText("Ok");
    okButton.setBounds(10, 291, 148, 32);
    getContentPane().add(okButton);

    final JButton refeshButton_1 = new JButton();
    refeshButton_1.setIcon(SwingResourceManager.getIcon(listing.class, "/pictures/48-32x32.png"));
    refeshButton_1.setText("Actualiser");
    refeshButton_1.setBounds(171, 291, 148, 32);
    getContentPane().add(refeshButton_1);

    final JScrollPane scrollPane = new JScrollPane();
    scrollPane.setBounds(10, 85, 474, 187);
    getContentPane().add(scrollPane);

    table = new JTable(rows(), columns()); // chargement de JTable 
    scrollPane.setViewportView(table);

    final JButton printButton_1_1 = new JButton();
    printButton_1_1.addActionListener(new ActionListener() {
        public void actionPerformed(final ActionEvent arg0) {
            try {
                table.print();
            } catch (PrinterException e) {

                e.printStackTrace();
            }
        }
    });
    printButton_1_1.setIcon(SwingResourceManager.getIcon(listing.class, "/pictures/Printer_h.png"));
    printButton_1_1.setText("Imprimer");
    printButton_1_1.setBounds(336, 291, 148, 32);
    getContentPane().add(printButton_1_1);




    }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!