0

I am new to Java Swing. I have spent a lot of time trying to find a way to insert a row into a JTable using run() method but haven't found it yet. So, can anyone please give me a solution.

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class ShowTable extends JFrame {
    JFrame f=new JFrame();
    JTable jt=new JTable(new DefaultTableModel());
    DefaultTableModel model=(DefaultTableModel)jt.getModel();

    public void showdata(int count, String host, String ip, String os_name, String os_arch, String os_version, String pro_detail, String Mac_add, float  disk_size, float max_memory) {
        System.out.println("Row  :"+count);
        Object data[] = {host, ip, os_name, os_arch, os_version, pro_detail, Mac_add, disk_size, max_memory};
        if (count == 0)
        {       
            model.addColumn("HOSTNAME");
            model.addColumn("IP ADDRESS");
            model.addColumn("OS NAME");
            model.addColumn("OS ARCHITECTURE");
            model.addColumn("OS VERSION");
            model.addColumn("PROCESSOR DETAIL");
            model.addColumn("MAC ADDRESS");
            model.addColumn("HARD DISK");
            model.addColumn("RAM SIZE");
            model.addRow(data);  
        }
        else
        {
            model.addRow(data);
        }
        jt.setBounds(30,40,200,300);
        jt.setFocusable(false);
        jt.setRowSelectionAllowed(false);
        JScrollPane sp = new JScrollPane(jt);
        f.add(sp);
        f.setSize(1300,100);
        f.setVisible(true);
    }

    public static void main() {
        JScrollPane jScrollPane1;
        JTable jTable1;
    }
}

I write this code but it only shows a blank frame every time the run() method executes.

Abra
  • 19,142
  • 7
  • 29
  • 41
Lakshraj
  • 291
  • 2
  • 18
  • 1
    The sort answer is, don't. Swing is not thread safe and you should not make modifications to the UI from outside the context of the Event Dispatching Thread. Instead, you can make use of a `SwingWorker` which will allow you to perform operations off the EDT (and not block the UI), but which provides a simplified means to update the UI safely. [For example](https://stackoverflow.com/questions/17414109/populate-jtable-with-large-number-of-rows/17415635#17415635) – MadProgrammer Feb 26 '18 at 10:02
  • and [example](https://stackoverflow.com/questions/26477744/how-to-search-subfolders-and-repaint-a-jtable-with-new-data-in-java/26478059#26478059) – MadProgrammer Feb 26 '18 at 10:06
  • @MadProgrammer thank you for the valuable answer. Actually I am making a Client Server Application using Socket Programming. In which their are multiple clients which are handled by server using Multithreading. So, I have to basically show the Hardware level specification of the client in JTable – Lakshraj Feb 26 '18 at 11:04

1 Answers1

1

Modifications from other threads should be made by SwingUtilities.invokeLater, for example:

SwingUtilities.invokeLater(() -> {
    // code to be invoked in awt thread
});

Working example below (it adds new row every second):

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;

public class ShowTable extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            startApp();
        });

    }

    static void startApp(){
        JFrame frame = new JFrame();


        DefaultTableModel model = new DefaultTableModel(0, 1);
        JTable table = new JTable(model);
        frame.getContentPane().add(new JScrollPane(table));

        frame.setSize(new Dimension(800, 600));
        frame.setVisible(true);

        new Thread(){
            @Override
            public void run() {
                while(true) {
                    SwingUtilities.invokeLater(() -> {
                        model.addRow(new Object[]{"some data"});

                    });
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
}
Wojciech Wirzbicki
  • 3,887
  • 6
  • 36
  • 59
  • 1
    The key is using the `SwingUtilties.invokeLater(...)`. This will make sure the code is executed on the `Event Dispatch Thread (EDT)`. See the Swing tutorial on [Concurrency](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html) for more information why this is important. The tutorial also covers the usage of a `SwingWorker` – camickr Feb 26 '18 at 15:22
  • Yes, this is quite important. Maybe add it directly to my answer. – Wojciech Wirzbicki Feb 27 '18 at 07:13