1

I am new to Java language.. I want to display records from Mysql database into JTable.. But i'm getting only one row.. I've no idea where i'm going wrong. Any help would higly be appreciated.

My code is:

package test;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.sql.*;
import net.proteanit.sql.DbUtils;

class Test {
    JFrame frame;
    Container pane;
    JTable table;
    Connection con;
    Statement sth;
    ResultSet rs;

    public void connect () {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/SMS", "root", "phplover");
        } catch (Exception e) {
            System.out.println("Conection failed. " + e);
        }
    }

    public void initGUI () {
        frame = new JFrame();
        frame.setVisible(true);
        frame.setBounds(100, 100, 500, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        pane = frame.getContentPane();
    }

    public void fetchRecords () {
        try {
            sth = con.createStatement();
            rs = sth.executeQuery("SELECT * FROM `students`");

            while (rs.next()) {
                String name = rs.getString("name");
                String fname = rs.getString("fname");
                String age = rs.getString("age");

                String cols[] = {"Name", "Father's Name", "Age"};
                String rows[][] = {
                    {name, fname, age}
                };
                table = new JTable(rows, cols);
                pane.add(new JScrollPane(table));
            }

        } catch (Exception e) {
            System.out.println("An error occured. " + e);
        }
    }

    public static void main (String args[]) {
        Test obj = new Test();
        obj.connect();
        obj.initGUI();
        obj.fetchRecords();
    }

}

1 Answers1

0

Your issue mainly lies within the fact that while you iterate over your database, you create a brand new JTable everytime. In the below example, I have not only fixed your problem, but also enhanced it.

A few pointers:

  1. Don't use getContentPane(), create a JPanel and give it a layout. For you, I chose BorderLayout, you can choose your own if you so wish.
  2. Don't use setBounds() on a JFrame. Hell, don't use it on ANY Swing component ever. Heres some good reasons why.
  3. Use JFrame.setDefaultLocationRelativeTo(null) to position it in the center of the screen. I believe thats what you were doing with setBounds().
  4. Use JFrame.setVisible(true) after the frame has been initialised. Otherwise you will have it jumping everywhere as everything is added.

And finally, the code:

public class Test {
    JFrame frame;
    JPanel window;
    JTable table;
    JScrollPane scrollPane;

    Connection con;
    Statement sth;
    ResultSet rs;

    public void connect () {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/SMS", "root", "phplover");
        } catch (Exception e) {
            System.out.println("Conection failed. " + e);
        }
    }

    public void initGUI () {
        frame = new JFrame();
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        window.setLayout(new BorderLayout());
        frame.add(window);

        scrollPane = new JScrollPane(table);

        // USE THIS ONE IF YOU WANT YOUR SCROLL BARS TO ALWAYS BE VISIBLE!
        //scrollPane = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        window.add(scrollPane, BorderLayout.CENTER);

        frame.setVisible(true);
    }

    public void fetchRecords () {
        try {
            sth = con.createStatement();
            rs = sth.executeQuery("SELECT * FROM `students`");

            String[] columns = {"Name", "Father's Name", "Age"};

            List<Object[]> sets = new ArrayList<Object[]>();
            while (rs.next()) {
                String name = rs.getString("name");
                String fname = rs.getString("fname");
                String age = rs.getString("age");

                sets.add(new String[]{name, fname, age});
            }
            table = new JTable(sets.toArray(new Object[sets.size()][]), columns);
        } catch (Exception e) {
            System.out.println("An error occured. " + e);
        }
    }

    public static void main (String args[]) {
        Test obj = new Test();
        obj.connect();
        obj.fetchRecords(); // Notice I swapped the order between this and initGUI.
        obj.initGUI();      // The program will break if you have it the other way around as the
                            // JTable will throw a NullPointerException.
    }
}

Note: This initialises the JTable within the record fetching process. You may edit it whenever you want, but by calling fetchRecords() again, it will update it through the database. Very useful for loading new data in, but it will remove any data that you have added in yourself unless you push those changes to your database first.

  • It shows the error "reference to List is ambiguous" .. I've imported " java.awt.* " & " java.util.* " – Crazy Coder Jul 15 '17 at 07:50
  • Your answer deserves acceptance. One more thing.. Could you briefly explain " table = new JTable(sets.toArray(new Object[sets.size()][]), columns); " ? – Crazy Coder Jul 15 '17 at 08:32
  • Oh sorry, your last comment didn't show up. Let me check that. Also, please don't accept my answer unless it truly helps! :) –  Jul 15 '17 at 08:32
  • That piece of code converts a dynamic `List` of 1-dimensional `String` arrays into a single 2-dimensional `String` array. From `List` to `String[][]`. –  Jul 15 '17 at 08:34
  • @CrazyCoder The list you are looking for, is `java.util.List`, and `java.util.ArrayList`, they both must be imported. –  Jul 15 '17 at 08:34
  • @CrazyCoder Not a problem! Happy I could help. –  Jul 15 '17 at 08:39