6 Replies - 1306 Views - Last Post: 16 July 2012 - 10:59 AM Rate Topic: -----

#1 cassiopeia  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 86
  • Joined: 03-April 11

jprogressbar does not progress

Posted 15 July 2012 - 06:18 AM

it does not progress until the entire process is done. i know this problem related with threading, and i've been trying to understand for a couple days. perhaps i still not very well understood yet :dead:

i want the progress bar to be related with the jTable where the data being loaded. code below is the latest code after many code that i've tried before.


public class RunnableProgress implements Runnable, TableModelListener{

    private JProgressBar jProgressBar;
    private JTable jTable;
    private int newValue;
    
    public RunnableProgress(JProgressBar _jProgressBar, JTable _jTable, int _totalRecords){

        jProgressBar=_jProgressBar;
        jTable=_jTable;
        
        jProgressBar.setMinimum(0);
        jProgressBar.setMaximum(_totalRecords);
        jProgressBar.setStringPainted(true);

        jTable.getModel().addTableModelListener(RunnableProgress.this);
    }
    
    @Override
    public void run() {
        newValue = jTable.getRowCount();
        jProgressBar.setValue(newValue);
        jProgressBar.repaint();            
    }

    @Override
    public void tableChanged(TableModelEvent e) {
        switch (e.getType()) {
            case TableModelEvent.INSERT:
                run();
            break;
        }
    }
}




and this how i call the runnable : line 08

public final class LoadDialogAToZ extends javax.swing.JDialog implements ActionListener{
...
    @Override
    public void actionPerformed(ActionEvent e) {

        int totalRecords = QueryPresenter.LoadItemTotalRows(session, _tableName, _property,_firstRange, _lastRange); 

        SwingUtilities.invokeLater(new RunnableProgress(jProgressBar,jTable,totalRecords-1));

        List listItem = QueryPresenter.LoadItem(session, _tableName, _property, _firstRange,_lastRange);

        Item item;
        for (int row = 0; row <= listItem.size()-1; row++){
            ...
            jTable.setValueAt(row+1, row, 1);       
            jTable.setValueAt(item.getItemId(), row, ColumnTable.getPositionItemId(jTable)); 
            ...
        }
    }
...
}



can someone tell me what i'm missing here. its been days im stuck with this :death:
and if you have any other idea i also apreciate that.
thank you :)

This post has been edited by cassiopeia: 15 July 2012 - 06:26 AM


Is This A Good Question/Topic? 0
  • +

Replies To: jprogressbar does not progress

#2 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1275
  • View blog
  • Posts: 2,837
  • Joined: 05-April 11

Re: jprogressbar does not progress

Posted 15 July 2012 - 06:29 AM

Are you sure you shouldn't be using TableModelEvent.UPDATE ?

You are not using threading when you call run() directly, that way you are not starting a new thread.
Was This Post Helpful? 0
  • +
  • -

#3 cassiopeia  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 86
  • Joined: 03-April 11

Re: jprogressbar does not progress

Posted 15 July 2012 - 06:43 AM

View PostCasiOo, on 15 July 2012 - 06:29 AM, said:

Are you sure you shouldn't be using TableModelEvent.UPDATE ?

You are not using threading when you call run() directly, that way you are not starting a new thread.


ok .. i change into something like this :


    @Override
    public void run() {
        jProgressBar.setValue(newValue);
        jProgressBar.repaint();            
    }

    @Override
    public void tableChanged(TableModelEvent e) {
        switch (e.getType()) {
            case TableModelEvent.UPDATE:
                newValue = jTable.getRowCount();
            break;
        }
    }




how bout the code above ? i try but still progressbar does not progress.
and second question : how about the way i use "SwingUtilities.invokeLater" is it right?
Was This Post Helpful? 0
  • +
  • -

#4 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1275
  • View blog
  • Posts: 2,837
  • Joined: 05-April 11

Re: jprogressbar does not progress

Posted 15 July 2012 - 07:14 AM

Lets take a look at it. Here you are making a new instance of your runnable and puts it in the queue to run on the event dispatching thread where they run method will be called
SwingUtilities.invokeLater(new RunnableProgress(jProgressBar,jTable,totalRecords-1));


I don't see a reason for you to put it on the event queue, you will be working on the event thread anyway because of the action performed.

In your run method you use newValue = jTable.getRowCount(); but you never add new rows to your tablemodel, so this is not what you want?
There is no reason to call jProgressBar.repaint(); after you have used the setValue method, since it will update the UI itself :)

When you call jTable.setValueAt it will tricker a TableModelEvent.UPDATE because a value is being updated, it will not be a new row.

You should catch the update event and then change the progress of the JProgressBar.

I made a little example of a working JProgressBar with a JTable
import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;


public class MyFrame extends JFrame {

	public static void main(String[] args) {
		new MyFrame();
	}
	
	private JProgressBar bar;
	private JTable table;
	
	public MyFrame() {
		bar = new JProgressBar();
		bar.setMinimum(0);
		bar.setMaximum(100);
		bar.setIndeterminate(false);
		
		//Add some random rows and columns
		Object[] columns = { "Test", "Test", "Test" };
		Object[][] tableValues = { { "one", "two", "three" },
															 { "four", "five", "six" }};
		table = new JTable(tableValues, columns);
		//We want to listen on changes on the model
		table.getModel().addTableModelListener(new MyModelListener());
		
		add(table, BorderLayout.CENTER);
		add(bar, BorderLayout.SOUTH);
		
		setVisible(true);
		pack();
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		changeValues();
	}
	
	public void changeValues() {
		
		for (int i=0; i<100; i++) {
			//Make a change to the model
			table.setValueAt("1", 0, 0);
			
			//Sleep 200ms so we can see the change happen to the progressbar
			try {
				Thread.sleep(200);
			}
			catch (InterruptedException e) {
			}
		}
	}
	
	public class MyModelListener implements TableModelListener {

		@Override
		public void tableChanged(TableModelEvent e) {
			//The table model has been changed, update the progressbar
			bar.setValue(bar.getValue() + 1);
		}
	}
}



Are you sure your for loop isn't executing so fast that you will not be able to see any progress? I think it will just jump from 0% to 100%
for (int row = 0; row <= listItem.size()-1; row++){


This post has been edited by CasiOo: 15 July 2012 - 07:37 AM

Was This Post Helpful? 1
  • +
  • -

#5 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1275
  • View blog
  • Posts: 2,837
  • Joined: 05-April 11

Re: jprogressbar does not progress

Posted 15 July 2012 - 07:28 AM

I am actually not sure if JTable.setValueAt and JProgressBar.setValue are thread safe I couldn't find any information on this. If they are not thread safe then you should call them on the event thread and not the way I did it in my example.

This post has been edited by CasiOo: 15 July 2012 - 07:38 AM

Was This Post Helpful? 0
  • +
  • -

#6 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1275
  • View blog
  • Posts: 2,837
  • Joined: 05-April 11

Re: jprogressbar does not progress

Posted 15 July 2012 - 08:05 AM

I edited my example so it is now thread safe.
The work is being done in a SwingWorker, where you are doing work in the background and then publish the progress on the way, where you then can make changes to the gui.

import java.awt.BorderLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;


public class MyFrame extends JFrame {

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new MyFrame();
			}
		});
	}
	
	private JProgressBar bar;
	private JTable table;
	
	
	public MyFrame() {
		bar = new JProgressBar();
		bar.setMinimum(0);
		bar.setMaximum(100);
		bar.setIndeterminate(false);
		
		//Add some random rows and columns
		Object[] columns = { "Test", "Test", "Test" };
		Object[][] tableValues = { { "one", "two", "three" },
															 { "four", "five", "six" }};
		table = new JTable(tableValues, columns);
		//We want to listen on changes on the model
		table.getModel().addTableModelListener(new MyModelListener());
		
		add(table, BorderLayout.CENTER);
		add(bar, BorderLayout.SOUTH);
		
		setVisible(true);
		pack();
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		MySwingWorker worker = new MySwingWorker();
		worker.execute();
	}
	
	public class MyModelListener implements TableModelListener {

		@Override
		public void tableChanged(TableModelEvent e) {
			//The table model has been changed, update the progressbar
			bar.setValue(bar.getValue() + 1);
		}
	}
	
	public class MySwingWorker extends SwingWorker<Integer, String> {

		@Override
		protected Integer doInBackground() throws Exception {
			//This work will get done in a background thread
			
			for (int i=0; i<100; i++) {
				//Get new values for our JTable
				//In this case our new value will be foo
				publish("foo");
				
				//Sleep so we can see changes
				Thread.sleep(200);
			}
			
                        //We have nothing to return to the done method, we do not care about this part.
			return null;
		}
		
		@Override
		protected void process(List<String> chunks) {
			//We are now in the event dispatching thread, so update our JTable with our new data
			table.setValueAt(chunks.get(0), 0, 0);
		}
	}
}




Was This Post Helpful? 1
  • +
  • -

#7 cassiopeia  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 86
  • Joined: 03-April 11

Re: jprogressbar does not progress

Posted 16 July 2012 - 10:59 AM

sory for a late reply, i take a break from any coding for a day or two :scooter:
by the way thank you for the code, i really apreciate that. :^:

View PostCasiOo, on 15 July 2012 - 07:14 AM, said:

Lets take a look at it. Here you are making a new instance of your runnable and puts it in the queue to run on the event dispatching thread where they run method will be called
SwingUtilities.invokeLater(new RunnableProgress(jProgressBar,jTable,totalRecords-1));


I don't see a reason for you to put it on the event queue, you will be working on the event thread anyway because of the action performed.


Do you mean that because i already in even dispatch tread (action performed in my example) so i dont need to use invokeLater. so, if im not in even dispatch thread, that when i must use invokeLater in order the thread to start whenever even dispatch triggered ?


View PostCasiOo, on 15 July 2012 - 07:14 AM, said:

In your run method you use newValue = jTable.getRowCount(); but you never add new rows to your tablemodel, so this is not what you want?
There is no reason to call jProgressBar.repaint(); after you have used the setValue method, since it will update the UI itself :)


I did add new row, its in line 15 of my second example. I just don’t put a whole code to minimze the size of code. and jProgressBar.repaint(); is one of my desperate attempt to make progressbar progress haha :lol:

View PostCasiOo, on 15 July 2012 - 07:14 AM, said:

When you call jTable.setValueAt it will tricker a TableModelEvent.UPDATE because a value is being updated, it will not be a new row.

You should catch the update event and then change the progress of the JProgressBar.


ok, I get the point why I should use TableModelEvent.UPDATE, and not TableModelEvent.INSERT.

View PostCasiOo, on 15 July 2012 - 07:14 AM, said:

Are you sure your for loop isn't executing so fast that you will not be able to see any progress? I think it will just jump from 0% to 100%
for (int row = 0; row <= listItem.size()-1; row++){



Not very sure, but the GUI seems freezing. I load 25 records, and it freeze couple second. I did try with more than 100 records and no progress at all. Only when the data already loeded into table, jproressbar suddenly reach 100%.

View PostCasiOo, on 15 July 2012 - 08:05 AM, said:

I edited my example so it is now thread safe.
The work is being done in a SwingWorker, where you are doing work in the background and then publish the progress on the way, where you then can make changes to the gui.


thanks a lot cas, I gonna try with swingworker. actually back then I already try swingworker, but does not end very well. but this time hopefuly will end with different story :D

Thank you :)

This post has been edited by cassiopeia: 16 July 2012 - 11:08 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1