Scroll Pane is visible but doesn't work when dynamically updating rows in java table

180 views Asked by At

I have a java table where i update rows dynamically. Here is an example which i created. It mimics my actual program line by line for creating table and adding scrollpane. My actual program is huge and sorry i can't share it.

import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
class SimpleTableExample extends JFrame
{
private JPanel      topPanel;
private JTable      table;
private JScrollPane scrollPane;
private DefaultTableModel model = null;
private JPanel pMainMenu = null;
public SimpleTableExample()
{

    pMainMenu = new JPanel();
    BorderLayout thisLayout = new BorderLayout();
    pMainMenu.setLayout(thisLayout);
    {
        JPanel pButtons = new JPanel();
        pMainMenu.add(pButtons, BorderLayout.NORTH);

        GridBagLayout pButtonsLayout = new GridBagLayout();
        pButtonsLayout.columnWidths = new int[]{7, 7, 7};
        pButtonsLayout.rowHeights = new int[]{25};
        pButtonsLayout.columnWeights = new double[]{0.1, 0.1, 0.1};
        pButtonsLayout.rowWeights = new double[]{0.1};
        {
            JButton btNew = new JButton();
            pButtons.add(btNew, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
                    GridBagConstraints.CENTER, GridBagConstraints.NONE,
                    new Insets(0, 5, 0, 0), 0, 0));
            btNew.setText("<html><center>Run</center><center>Configuration</center></html>");
            btNew.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    btRunConfiguration(evt);
                }
            });
        }
    }




    topPanel = new JPanel();
    topPanel.setLayout( new BorderLayout() );
    {
        model = new DefaultTableModel();
        table = new JTable(model);
        scrollPane = new JScrollPane( table );
        topPanel.add( scrollPane, BorderLayout.CENTER );
        model.addColumn(" ");
        model.addColumn(" ");
        model.addColumn(" ");
    }

    getContentPane().add(pMainMenu);
    getContentPane().repaint();
    pack();
    setSize(520, 130);
    setLocationRelativeTo(null);
    setVisible(true);


}

private void btRunConfiguration(ActionEvent evt) {
    getContentPane().removeAll();
    getContentPane().add( topPanel );
    getContentPane().repaint();

    setTitle("Simple Table Application");
    setSize(300, 100);
    setBackground(Color.gray);
    pack();
    setVisible(true);

    String columnNames[] = { "Column 1", "Column 2", "Column 3" };

    for(int i=0;i<300;i++)
    {
        try {
            Thread.sleep(1000);
        } catch(InterruptedException ie) {
            // ignore!
            ie.printStackTrace();
        }
        model.addRow(new Object[]{i,i,i});
        /**************This message dialog box show row updated to refresh table for viewing***********/
        //Must schedule the close before the dialog becomes visible
        JFrame closeDialog = new JFrame();
        final JDialog dialog = new JDialog(closeDialog, "Updated", true);

        ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
        s.schedule(new Runnable() {
            public void run() {
                dialog.setVisible(false); //should be invoked on the EDT
                dialog.dispose();
            }
        }, 500, TimeUnit.MILLISECONDS);

        dialog.setVisible(true); // if modal, application will pause here

        //System.out.println("Dialog closed");
        /**************This message dialog box show row updated to refresh table for viewing***********/

    }
}


public static void main( String args[] )
{
    // Create an instance of the test application
    SimpleTableExample mainFrame    = new SimpleTableExample();
    mainFrame.setVisible( true );
}
}

Scroll pane doesn't work. Can you please help. Thanks

***************************New Code***************************************

 import java.awt.*;
 import java.awt.event.*;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import javax.swing.*;
 import javax.swing.table.DefaultTableModel;
 class SimpleTableExample extends JFrame
 {
 private JPanel      topPanel;
private JTable      table;
private JScrollPane scrollPane;
private DefaultTableModel model = null;
private JPanel pMainMenu = null;
public SimpleTableExample()
{

    pMainMenu = new JPanel();
    BorderLayout thisLayout = new BorderLayout();
    pMainMenu.setLayout(thisLayout);
    {
        JPanel pButtons = new JPanel();
        pMainMenu.add(pButtons, BorderLayout.NORTH);

        GridBagLayout pButtonsLayout = new GridBagLayout();
        pButtonsLayout.columnWidths = new int[]{7, 7, 7};
        pButtonsLayout.rowHeights = new int[]{25};
        pButtonsLayout.columnWeights = new double[]{0.1, 0.1, 0.1};
        pButtonsLayout.rowWeights = new double[]{0.1};
        {
            JButton btNew = new JButton();
            pButtons.add(btNew, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
                    GridBagConstraints.CENTER, GridBagConstraints.NONE,
                    new Insets(0, 5, 0, 0), 0, 0));
            btNew.setText("<html><center>Run</center><center>Configuration</center></html>");
            btNew.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    btRunConfiguration(evt);
                }
            });
        }
    }




    topPanel = new JPanel();
    topPanel.setLayout( new BorderLayout() );
    {
        model = new DefaultTableModel();
        table = new JTable(model);
        scrollPane = new JScrollPane( table );
        topPanel.add( scrollPane, BorderLayout.CENTER );
        model.addColumn(" ");
        model.addColumn(" ");
        model.addColumn(" ");
    }

    getContentPane().add(pMainMenu);
    getContentPane().repaint();
    pack();
    setSize(520, 130);
    setLocationRelativeTo(null);
    setVisible(true);


}

private void btRunConfiguration(ActionEvent evt) {
    getContentPane().removeAll();
    getContentPane().add( topPanel );
    getContentPane().repaint();

    setTitle("Simple Table Application");
    setSize(300, 100);
    setBackground(Color.gray);
    pack();
    setVisible(true);

    String columnNames[] = { "Column 1", "Column 2", "Column 3" };

    for(int i=0;i<300;i++) {
        try {
            Thread.sleep(1000);
        } catch(InterruptedException ie) {
            // ignore!
            ie.printStackTrace();
        }
        new MyWorker(model).execute();
        /**************This message dialog box show row updated to refresh table for viewing***********/
        //Must schedule the close before the dialog becomes visible
        JFrame closeDialog = new JFrame();
        final JDialog dialog = new JDialog(closeDialog, "Updated", true);

        ActionListener timerAction = new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent ae)
            {
                dialog.setVisible(false); //should be invoked on the EDT
                dialog.dispose();
            }
        };
        Timer timer = new Timer(500, timerAction);
        timer.start();
        dialog.setVisible(true); // if modal, application will pause here

        //System.out.println("Dialog closed");
        /**************This message dialog box show row updated to refresh table for viewing***********/
    }
}
class MyWorker extends SwingWorker<Void, Void> {
    DefaultTableModel model;
    MyWorker(DefaultTableModel model){
        this.model=model;
    }
    @Override
    public Void doInBackground() {
     model.addRow(new Object[]{1,1,1});
    return null;
    }

    @Override
    protected void done() {

    }
}


public static void main( String args[] )
{
    // Create an instance of the test application
    SimpleTableExample mainFrame    = new SimpleTableExample();
    mainFrame.setVisible( true );
}}

*************************************New Code 2 Timer Problem*******************

 import java.awt.*;
 import java.awt.event.*;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
class SimpleTableExample extends JFrame
{
private JPanel      topPanel;
private JTable      table;
private JScrollPane scrollPane;
private DefaultTableModel model = null;
private JPanel pMainMenu = null;
private Timer timer = null;
public SimpleTableExample()
{

    pMainMenu = new JPanel();
    BorderLayout thisLayout = new BorderLayout();
    pMainMenu.setLayout(thisLayout);
    {
        JPanel pButtons = new JPanel();
        pMainMenu.add(pButtons, BorderLayout.NORTH);

        GridBagLayout pButtonsLayout = new GridBagLayout();
        pButtonsLayout.columnWidths = new int[]{7, 7, 7};
        pButtonsLayout.rowHeights = new int[]{25};
        pButtonsLayout.columnWeights = new double[]{0.1, 0.1, 0.1};
        pButtonsLayout.rowWeights = new double[]{0.1};
        {
            JButton btNew = new JButton();
            pButtons.add(btNew, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
                    GridBagConstraints.CENTER, GridBagConstraints.NONE,
                    new Insets(0, 5, 0, 0), 0, 0));
            btNew.setText("<html><center>Run</center><center>Configuration</center></html>");
            btNew.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    btRunConfiguration(evt);
                }
            });
        }
    }




    topPanel = new JPanel();
    topPanel.setLayout( new BorderLayout() );
    {
        model = new DefaultTableModel();
        table = new JTable(model);
        scrollPane = new JScrollPane( table );
        topPanel.add( scrollPane, BorderLayout.CENTER );
        model.addColumn(" ");
        model.addColumn(" ");
        model.addColumn(" ");
    }

    getContentPane().add(pMainMenu);
    getContentPane().repaint();
    pack();
    setSize(520, 130);
    setLocationRelativeTo(null);
    setVisible(true);

    String columnNames[] = { "Column 1", "Column 2", "Column 3" };

    //new MyWorker().execute();


}

private void btRunConfiguration(ActionEvent evt) {
    getContentPane().removeAll();
    getContentPane().add( topPanel );
    getContentPane().repaint();

    setTitle("Simple Table Application");
    setSize(300, 100);
    setBackground(Color.gray);
    pack();
    showOnScreen(1,this);
    setVisible(true);
    new MyWorker().execute();

}
class MyWorker extends SwingWorker<Void, Void> {



    @Override
    public Void doInBackground() {


        ActionListener taskPerformer = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < 300; i++) {
                    try {
                        Runtime rt = Runtime.getRuntime();
                        String url = "http://stackoverflow.com";
                        rt.exec("rundll32 url.dll,FileProtocolHandler " + url);
                        Thread.sleep(1000);
                    } catch (InterruptedException ie) {
                        // ignore!
                        ie.printStackTrace();
                    } catch (IOException le) {
                        le.printStackTrace();
                    }
                    model.addRow(new Object[]{i, i, i});
                    /**************This message dialog box show row updated to refresh table for viewing***********/
                    //Must schedule the close before the dialog becomes visible
                    JFrame closeDialog = new JFrame();
                    final JDialog dialog = new JDialog(closeDialog, "Updated", true);

                    ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
                    s.schedule(new Runnable() {
                        public void run() {
                            dialog.setVisible(false); //should be invoked on the EDT
                            dialog.dispose();
                        }
                    }, 500, TimeUnit.MILLISECONDS);

                    dialog.setVisible(true); // if modal, application will pause here

                    //System.out.println("Dialog closed");
                    /**************This message dialog box show row updated to refresh table for viewing***********/

                }
            }
        };


        timer = new Timer(20, taskPerformer);

        timer.start();
        return null;
    }

    @Override
    protected void done() {

    }
}



public static void main( String args[] )
{
    // Create an instance of the test application
    SimpleTableExample mainFrame    = new SimpleTableExample();
    mainFrame.setVisible( true );
}

public void showOnScreen( int screen, JFrame frame ) {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gd = ge.getScreenDevices();
    if( screen > 0 && screen < 2 ) {
        int x = frame.getWidth()/2;
        int y = frame.getHeight()/2;
        frame.setLocation((gd[screen].getDefaultConfiguration().getBounds().width * 3/2) - x,   (gd[screen].getDefaultConfiguration().getBounds().height *1/2) - y);
        // JFrame dummy = new JFrame(gd[screen].getDefaultConfiguration());
        // setLocationRelativeTo(dummy);
        // dummy.dispose();
    } else if( gd.length > 0 ) {
        frame.setLocationRelativeTo(null);
    } else {
        throw new RuntimeException( "No Screens Found" );
    }
}

}
1

There are 1 answers

9
Sarfaraz Khan On BEST ANSWER

Always use swing threads when interacting with swing components.Try the below solution it works

import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
class SimpleTableExample extends JFrame
{
    private JPanel      topPanel;
    private JTable      table;
    private JScrollPane scrollPane;
    private DefaultTableModel model = null;
    private JPanel pMainMenu = null;
    public SimpleTableExample()
    {

    pMainMenu = new JPanel();
    BorderLayout thisLayout = new BorderLayout();
    pMainMenu.setLayout(thisLayout);
    {
        JPanel pButtons = new JPanel();
        pMainMenu.add(pButtons, BorderLayout.NORTH);

        GridBagLayout pButtonsLayout = new GridBagLayout();
        pButtonsLayout.columnWidths = new int[]{7, 7, 7};
        pButtonsLayout.rowHeights = new int[]{25};
        pButtonsLayout.columnWeights = new double[]{0.1, 0.1, 0.1};
        pButtonsLayout.rowWeights = new double[]{0.1};
        {
            JButton btNew = new JButton();
            pButtons.add(btNew, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
                    GridBagConstraints.CENTER, GridBagConstraints.NONE,
                    new Insets(0, 5, 0, 0), 0, 0));
            btNew.setText("<html><center>Run</center><center>Configuration</center></html>");
            btNew.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    btRunConfiguration(evt);
                }
            });
        }
    }




    topPanel = new JPanel();
    topPanel.setLayout( new BorderLayout() );
    {
        model = new DefaultTableModel();
        table = new JTable(model);
        scrollPane = new JScrollPane( table );
        topPanel.add( scrollPane, BorderLayout.CENTER );
        model.addColumn(" ");
        model.addColumn(" ");
        model.addColumn(" ");
    }

    getContentPane().add(pMainMenu);
    getContentPane().repaint();
    pack();
    setSize(520, 130);
    setLocationRelativeTo(null);
    setVisible(true);


}

private void btRunConfiguration(ActionEvent evt) {
    getContentPane().removeAll();
    getContentPane().add( topPanel );
    getContentPane().repaint();

    setTitle("Simple Table Application");
    setSize(300, 100);
    setBackground(Color.gray);
    pack();
    setVisible(true);

    String columnNames[] = { "Column 1", "Column 2", "Column 3" };

    new MyWorker(model).execute();
}
class MyWorker extends SwingWorker<Void, Void> {
    DefaultTableModel model;
    MyWorker(DefaultTableModel model){
        this.model=model;
    }
    @Override
       public Void doInBackground() {
        for(int i=0;i<300;i++)
        {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException ie) {
                // ignore!
                ie.printStackTrace();
            }
            model.addRow(new Object[]{i,i,i});
            /**************This message dialog box show row updated to refresh table for viewing***********/
            //Must schedule the close before the dialog becomes visible
            JFrame closeDialog = new JFrame();
            final JDialog dialog = new JDialog(closeDialog, "Updated", true);

             ActionListener timerAction = new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent ae)
                {
                    dialog.setVisible(false); //should be invoked on the EDT
                    dialog.dispose();
                }
            };
            Timer timer = new Timer(500, timerAction);
            timer.start();
            dialog.setVisible(true); // if modal, application will pause here

            //System.out.println("Dialog closed");
            /**************This message dialog box show row updated to refresh table for viewing***********/

        }
          return null;
       }

       @Override
       protected void done() {

       }
   }


public static void main( String args[] )
{
    // Create an instance of the test application
    SimpleTableExample mainFrame    = new SimpleTableExample();
    mainFrame.setVisible( true );
}}

UPDATE According to your problem that you updated with your design.You just have to make sure the loop needs to run through a Swing Thread.For example if you have this method of update table

private void updateTable(){
 for(int i=0;i<300;i++)
    {
        try {
            Thread.sleep(1000);
        } catch(InterruptedException ie) {
            // ignore!
            ie.printStackTrace();
        }
        model.addRow(new Object[]{i,i,i});
        /**************This message dialog box show row updated to refresh table for viewing***********/
        //Must schedule the close before the dialog becomes visible
        JFrame closeDialog = new JFrame();
        final JDialog dialog = new JDialog(closeDialog, "Updated", true);

        ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
        s.schedule(new Runnable() {
            public void run() {
                dialog.setVisible(false); //should be invoked on the EDT
                dialog.dispose();
            }
        }, 500, TimeUnit.MILLISECONDS);

        dialog.setVisible(true); // if modal, application will pause here

        //System.out.println("Dialog closed");
        /**************This message dialog box show row updated to refresh table for viewing***********/

    }}

Make sure you call it from SwingWorker

private void btRunConfiguration(ActionEvent evt) {
getContentPane().removeAll();
getContentPane().add( topPanel );
getContentPane().repaint();

setTitle("Simple Table Application");
setSize(300, 100);
setBackground(Color.gray);
pack();
setVisible(true);
  new MyWorker().execute();

}
class MyWorker extends SwingWorker<Void, Void> {



@Override
public Void doInBackground() {

     updateTable();
return null;
}

@Override
protected void done() {

} }

According to update 2

private void btRunConfiguration(ActionEvent evt) {
        getContentPane().removeAll();
        getContentPane().add( topPanel );
        getContentPane().repaint();

        setTitle("Simple Table Application");
        setSize(300, 100);
        setBackground(Color.gray);
        pack();
        showOnScreen(1,this);
        setVisible(true);
        final AtomicBoolean flag = new AtomicBoolean(false);
        ActionListener taskPerformer = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if(!flag.get()){
                    flag.set(true);
                    new MyWorker(flag).execute();
                    //flag.set(false);
                }
            }
        };
        Timer timer = new Timer(20, taskPerformer);
        timer.setRepeats(true);
        timer.start();

    }
    class MyWorker extends SwingWorker<Void, Void> {

        AtomicBoolean flag;
        MyWorker(AtomicBoolean flag){
            this.flag=flag;
        }

        @Override
        public Void doInBackground() {

            for (int i = 0; i < 300; i++) {
                try {
                    Runtime rt = Runtime.getRuntime();
                    String url = "http://stackoverflow.com";
                    rt.exec("rundll32 url.dll,FileProtocolHandler " + url);
                    Thread.sleep(1000);
                } catch (InterruptedException ie) {
                    // ignore!
                    ie.printStackTrace();
                } catch (Exception le) {
                    le.printStackTrace();
                }
                model.addRow(new Object[]{i, i, i});
                /**************This message dialog box show row updated to refresh table for viewing***********/
                //Must schedule the close before the dialog becomes visible
                JFrame closeDialog = new JFrame();
                final JDialog dialog = new JDialog(closeDialog, "Updated", true);

                ScheduledExecutorService s = Executors.newSingleThreadScheduledExecutor();
                s.schedule(new Runnable() {
                    public void run() {
                        dialog.setVisible(false); //should be invoked on the EDT
                        dialog.dispose();
                    }
                }, 500, TimeUnit.MILLISECONDS);

                dialog.setVisible(true); // if modal, application will pause here

                //System.out.println("Dialog closed");
                /**************This message dialog box show row updated to refresh table for viewing***********/

            }
            return null;
        }

        @Override
        protected void done() {
            flag.set(false);
        }

    }