AppletTalk.com Forum Index AppletTalk.com
Java discussions newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

making a modal progressdialog with SWING
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java GUI Toolkits
View previous topic :: View next topic  
Author Message
Robert Ludewig
Guest





PostPosted: Sat Nov 15, 2003 12:51 pm    Post subject: making a modal progressdialog with SWING Reply with quote



Hello,

for quite some time I am trying to make a modal Progressdialog that may be
updated by another thread.

COULD ANYONE PLEASE EXPLAIN TO ME HOW SUCH THING CAN BE DONE WITH SWING? AND
MAYBE THREADSAFE ?

This is how I tried it:
- Build my own JDialog derived JprogressDialog that has a JProgressBar
- in the WindowsActivated EventHandler of JProgressDialog start a Thread
that takes ProgressInformation from the WorkingThread (this is done via an
own Interface)
- Start a Working thread that implemtents that ObservationInterface
- create sn Instance of JProgressDialog

It looks like it works. BUT:
- I think that is not a beautiful way to do it, somehow it looks like I am
doing a detor, can't acess the content of a modal JDialog directly somehow?
- I can not find a way to close the window after the Working Thread is done
- I can not find a way to cancel the Working Thread with a cancelbutton on
JprogressDilag

And here the code:

////////////////////MainTest.java
import java.awt.event.*;
import javax.swing.*;
public class MainTest extends JFrame
{
public MainTest()
{
super("PanelViewer");
}
public static void CreateAndShowGUI()
{
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel
");
}
catch (Exception e)
{
System.out.println(e);
}
JFrame frame = new MainTest();
WindowListener listener = new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
};
MainTestPanel mp = new MainTestPanel();
frame.setContentPane(mp);
frame.addWindowListener(listener);
frame.setTitle("Test");
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
CreateAndShowGUI();
}
});
}
}

////////////////////MainTextPanel.java

import java.awt.BorderLayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainTestPanel extends JPanel implements ActionListener
{
JButton b;
JTextPane p;
public MainTestPanel()
{
setLayout(new BorderLayout());
b = new JButton("Start");
p = new JTextPane();
p.setPreferredSize(new Dimension(200, 200));
add(b, BorderLayout.SOUTH);
add(p, BorderLayout.CENTER);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
Runnable updater = new Runnable()
{
public void run()
{
doProgress();
}
};
Thread t = new Thread (updater);
t.start();
}
private void doProgress()
{

System.out.println("progress");
WorkerThread wt = new WorkerThread();
Thread t = new Thread (wt);
t.start();
JProgressDialog jpd = new JProgressDialog((Frame)
SwingUtilities.windowForComponent(this), true, wt);
}
}

///////////////////////////WorkerThread.java

public class WorkerThread implements ThreadProgressObservable
{
private int i;
private String statusText;
private boolean isRunning;
public void run()
{
isRunning=true;
for (i = 0; i <= 100; i++)
{
statusText = new Integer(i).toString();
try
{
Thread.sleep(200);
}
catch (InterruptedException e)
{
}
}
isRunning=false;
}
public int getProgress()
{
return i;
}
public String getText()
{
return statusText;
}
public boolean isRunning()
{
return isRunning;
}
}

///////////////////////////////JProgressDialog.java

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.*;
public class JProgressDialog extends JDialog implements WindowListener
{
private JLabel jl;
private JProgressBar jpb;
private ThreadProgressObservable workerthread;
public JProgressDialog(Frame owner, boolean modal, ThreadProgressObservable
wt)
{
super(owner, modal);
addWindowListener(this);
jpb = new JProgressBar();
jl = new JLabel("text");
getContentPane().add(jl, BorderLayout.NORTH);
getContentPane().add(jpb, BorderLayout.SOUTH);
pack();
workerthread = wt;
show();
}
public void SetText(String t)
{
jl.setText(t);
}
public void SetProgress()
{
}
public void doProgress()
{
Thread t = new Thread(new Runnable()
{
public void run()
{
while (workerthread.isRunning())
{
try
{
Thread.sleep(50);
}
catch (InterruptedException e)
{
}
jpb.setValue(workerthread.getProgress());
jl.setText(workerthread.getText());
}
}
});
t.start();
}
public void windowActivated(WindowEvent e)
{
doProgress();
}
public void windowClosed(WindowEvent e)
{
}
public void windowClosing(WindowEvent e)
{
}
public void windowDeactivated(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowIconified(WindowEvent e)
{
}
public void windowOpened(WindowEvent e)
{
}
}

//////////////////ThreadProgressObservable.java

public interface ThreadProgressObservable extends Runnable
{
public int getProgress ();
public String getText();
public boolean isRunning();
}


Back to top
kevinc
Guest





PostPosted: Sat Nov 15, 2003 3:33 pm    Post subject: Re: making a modal progressdialog with SWING Reply with quote




Use the MVC pattern as such.
Think of your thread as your model.
Your progress modal dialog as the view.
Create an association class, use this as the controller.
I don't see anywhere in your code where you are utilizing the
Observer/Observable pattern. This would solve your problem.




Robert Ludewig wrote:
Quote:
Hello,

for quite some time I am trying to make a modal Progressdialog that may be
updated by another thread.

COULD ANYONE PLEASE EXPLAIN TO ME HOW SUCH THING CAN BE DONE WITH SWING? AND
MAYBE THREADSAFE ?

This is how I tried it:
- Build my own JDialog derived JprogressDialog that has a JProgressBar
- in the WindowsActivated EventHandler of JProgressDialog start a Thread
that takes ProgressInformation from the WorkingThread (this is done via an
own Interface)
- Start a Working thread that implemtents that ObservationInterface
- create sn Instance of JProgressDialog

It looks like it works. BUT:
- I think that is not a beautiful way to do it, somehow it looks like I am
doing a detor, can't acess the content of a modal JDialog directly somehow?
- I can not find a way to close the window after the Working Thread is done
- I can not find a way to cancel the Working Thread with a cancelbutton on
JprogressDilag

And here the code:

////////////////////MainTest.java
import java.awt.event.*;
import javax.swing.*;
public class MainTest extends JFrame
{
public MainTest()
{
super("PanelViewer");
}
public static void CreateAndShowGUI()
{
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel
");
}
catch (Exception e)
{
System.out.println(e);
}
JFrame frame = new MainTest();
WindowListener listener = new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
};
MainTestPanel mp = new MainTestPanel();
frame.setContentPane(mp);
frame.addWindowListener(listener);
frame.setTitle("Test");
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
CreateAndShowGUI();
}
});
}
}

////////////////////MainTextPanel.java

import java.awt.BorderLayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainTestPanel extends JPanel implements ActionListener
{
JButton b;
JTextPane p;
public MainTestPanel()
{
setLayout(new BorderLayout());
b = new JButton("Start");
p = new JTextPane();
p.setPreferredSize(new Dimension(200, 200));
add(b, BorderLayout.SOUTH);
add(p, BorderLayout.CENTER);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
Runnable updater = new Runnable()
{
public void run()
{
doProgress();
}
};
Thread t = new Thread (updater);
t.start();
}
private void doProgress()
{

System.out.println("progress");
WorkerThread wt = new WorkerThread();
Thread t = new Thread (wt);
t.start();
JProgressDialog jpd = new JProgressDialog((Frame)
SwingUtilities.windowForComponent(this), true, wt);
}
}

///////////////////////////WorkerThread.java

public class WorkerThread implements ThreadProgressObservable
{
private int i;
private String statusText;
private boolean isRunning;
public void run()
{
isRunning=true;
for (i = 0; i <= 100; i++)
{
statusText = new Integer(i).toString();
try
{
Thread.sleep(200);
}
catch (InterruptedException e)
{
}
}
isRunning=false;
}
public int getProgress()
{
return i;
}
public String getText()
{
return statusText;
}
public boolean isRunning()
{
return isRunning;
}
}

///////////////////////////////JProgressDialog.java

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.*;
public class JProgressDialog extends JDialog implements WindowListener
{
private JLabel jl;
private JProgressBar jpb;
private ThreadProgressObservable workerthread;
public JProgressDialog(Frame owner, boolean modal, ThreadProgressObservable
wt)
{
super(owner, modal);
addWindowListener(this);
jpb = new JProgressBar();
jl = new JLabel("text");
getContentPane().add(jl, BorderLayout.NORTH);
getContentPane().add(jpb, BorderLayout.SOUTH);
pack();
workerthread = wt;
show();
}
public void SetText(String t)
{
jl.setText(t);
}
public void SetProgress()
{
}
public void doProgress()
{
Thread t = new Thread(new Runnable()
{
public void run()
{
while (workerthread.isRunning())
{
try
{
Thread.sleep(50);
}
catch (InterruptedException e)
{
}
jpb.setValue(workerthread.getProgress());
jl.setText(workerthread.getText());
}
}
});
t.start();
}
public void windowActivated(WindowEvent e)
{
doProgress();
}
public void windowClosed(WindowEvent e)
{
}
public void windowClosing(WindowEvent e)
{
}
public void windowDeactivated(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowIconified(WindowEvent e)
{
}
public void windowOpened(WindowEvent e)
{
}
}

//////////////////ThreadProgressObservable.java

public interface ThreadProgressObservable extends Runnable
{
public int getProgress ();
public String getText();
public boolean isRunning();
}




Back to top
Robert Ludewig
Guest





PostPosted: Sat Nov 15, 2003 5:47 pm    Post subject: Re: making a modal progressdialog with SWING Reply with quote




Quote:
Use the MVC pattern as such.
Think of your thread as your model.
Your progress modal dialog as the view.
Create an association class, use this as the controller.
I don't see anywhere in your code where you are utilizing the
Observer/Observable pattern. This would solve your problem.

I sthere a tutorial or something out there that exlpains how to do that in
java and how it works? Especially how to implement a mvc architecture ?



Back to top
Robert Ludewig
Guest





PostPosted: Sat Nov 15, 2003 6:01 pm    Post subject: Re: making a modal progressdialog with SWING Reply with quote

Someone suggested something about property listeners. What is that? Is that
the same thing ?

"To do it the way you're trying to do it you're going to need to understand
property change listeners. Essentially you want to add properties to your
dialog to hold the minimum value of your progress bar, the maximum value of
your progress bar and the current value of the progress bar. Then you want
to add a property change listener for the current value and when it changes
you pipe that change through to the JProgressBar control on the dialog. "


Back to top
kevinc
Guest





PostPosted: Sat Nov 15, 2003 6:49 pm    Post subject: Re: making a modal progressdialog with SWING Reply with quote


Conceptually. It's the same. All that is happening here is that.
When a change of state occurs on a given "item | attribute | object"
a change notification event is triggered and sent to interested listeners.

Robert Ludewig wrote:
Quote:
Someone suggested something about property listeners. What is that? Is that
the same thing ?

"To do it the way you're trying to do it you're going to need to understand
property change listeners. Essentially you want to add properties to your
dialog to hold the minimum value of your progress bar, the maximum value of
your progress bar and the current value of the progress bar. Then you want
to add a property change listener for the current value and when it changes
you pipe that change through to the JProgressBar control on the dialog. "




Back to top
kevinc
Guest





PostPosted: Sat Nov 15, 2003 6:50 pm    Post subject: Re: making a modal progressdialog with SWING Reply with quote

Tons

Robert Ludewig wrote:
Quote:
Use the MVC pattern as such.
Think of your thread as your model.
Your progress modal dialog as the view.
Create an association class, use this as the controller.
I don't see anywhere in your code where you are utilizing the
Observer/Observable pattern. This would solve your problem.


I sthere a tutorial or something out there that exlpains how to do that in
java and how it works? Especially how to implement a mvc architecture ?




Back to top
R. Kevin Cole
Guest





PostPosted: Sun Nov 16, 2003 10:00 pm    Post subject: Re: making a modal progressdialog with SWING Reply with quote

Robert,

Here's a modification to your original code that works and
is a bit simpler. In this implementation, the model is setup as
kevinc suggested. The WorkerThread (the model) responds
to internal state changes by informing the JProgressDialog
(the view). The combination of MainTest and MainTestPanel
constitute the controller.

Hope this helps,

R. Kevin Cole

------------------ cut here --------------------------

////////////////////MainTest.java
import java.awt.event.*;
import javax.swing.*;

public class MainTest extends JFrame
{
public MainTest()
{
super("PanelViewer");
}

public static void CreateAndShowGUI()
{
JFrame frame = new MainTest();
WindowListener listener = new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
};

MainTestPanel mp = new MainTestPanel( frame );
frame.setContentPane(mp);
frame.addWindowListener(listener);
frame.setTitle("Test");
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args)
{
CreateAndShowGUI();
}
}


////////////////////MainTestPanel.java

import java.awt.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;

public class MainTestPanel extends JPanel
{
JTextPane p;
static JProgressDialog jpd;
WorkerThread wt;
JButton btnStop = new JButton("Stop");
JButton btnStart = new JButton("Start");

public MainTestPanel( JFrame frame )
{
jpd = new JProgressDialog(frame, false);

setLayout(new BorderLayout());
p = new JTextPane();
p.setPreferredSize(new Dimension(200, 200));

JPanel panel = new JPanel( new FlowLayout( FlowLayout.RIGHT ) );
btnStart.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
btnStart.setEnabled(false);
btnStop.setEnabled(true);
wt = new WorkerThread(jpd);
Thread t = new Thread(wt);
t.start();
jpd.setVisible(true);
}
});

btnStop.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
btnStart.setEnabled(true);
btnStop.setEnabled(false);
wt.cancel();
jpd.setVisible(false);
}
});
btnStop.setEnabled(false);

panel.add(btnStart);
panel.add(btnStop);
add(panel, BorderLayout.SOUTH);
add(p, BorderLayout.CENTER);
}
}

//////////////////ThreadProgressObservable.java
public interface ThreadProgressObservable extends Runnable
{
public int getProgress();
public String getText();
public boolean isRunning();
}

///////////////////////////WorkerThread.java
import javax.swing.SwingUtilities;

public class WorkerThread implements Runnable, ThreadProgressObservable
{
private int i;
private String statusText;
boolean isRunning = true;
JProgressDialog jpd;

public WorkerThread( JProgressDialog jpd )
{
this.jpd = jpd;
}

public void run()
{
for(i = 0; i <= 100; i++)
{
if( !isRunning )
return;

statusText = new Integer(i).toString();

try
{
Thread.sleep(200);
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
jpd.setValue(i);
}
});
}
catch(InterruptedException e) {}
}
isRunning = false;
}

public int getProgress()
{
return i;
}

public String getText()
{
return statusText;
}

public void cancel()
{
isRunning = false;
}

public boolean isRunning()
{
return isRunning;
}
}

------------------------ cut here --------------------------------


kevinc
Quote:

Use the MVC pattern as such.
Think of your thread as your model.
Your progress modal dialog as the view.
Create an association class, use this as the controller.
I don't see anywhere in your code where you are utilizing the
Observer/Observable pattern. This would solve your problem.




Robert Ludewig wrote:
Hello,

for quite some time I am trying to make a modal Progressdialog that may be
updated by another thread.

COULD ANYONE PLEASE EXPLAIN TO ME HOW SUCH THING CAN BE DONE WITH SWING? AND
MAYBE THREADSAFE ?

This is how I tried it:
- Build my own JDialog derived JprogressDialog that has a JProgressBar
- in the WindowsActivated EventHandler of JProgressDialog start a Thread
that takes ProgressInformation from the WorkingThread (this is done via an
own Interface)
- Start a Working thread that implemtents that ObservationInterface
- create sn Instance of JProgressDialog

It looks like it works. BUT:
- I think that is not a beautiful way to do it, somehow it looks like I am
doing a detor, can't acess the content of a modal JDialog directly somehow?
- I can not find a way to close the window after the Working Thread is done
- I can not find a way to cancel the Working Thread with a cancelbutton on
JprogressDilag

And here the code:

////////////////////MainTest.java
import java.awt.event.*;
import javax.swing.*;
public class MainTest extends JFrame
{
public MainTest()
{
super("PanelViewer");
}
public static void CreateAndShowGUI()
{
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel
");
}
catch (Exception e)
{
System.out.println(e);
}
JFrame frame = new MainTest();
WindowListener listener = new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
};
MainTestPanel mp = new MainTestPanel();
frame.setContentPane(mp);
frame.addWindowListener(listener);
frame.setTitle("Test");
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
CreateAndShowGUI();
}
});
}
}

////////////////////MainTextPanel.java

import java.awt.BorderLayout;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainTestPanel extends JPanel implements ActionListener
{
JButton b;
JTextPane p;
public MainTestPanel()
{
setLayout(new BorderLayout());
b = new JButton("Start");
p = new JTextPane();
p.setPreferredSize(new Dimension(200, 200));
add(b, BorderLayout.SOUTH);
add(p, BorderLayout.CENTER);
b.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
Runnable updater = new Runnable()
{
public void run()
{
doProgress();
}
};
Thread t = new Thread (updater);
t.start();
}
private void doProgress()
{

System.out.println("progress");
WorkerThread wt = new WorkerThread();
Thread t = new Thread (wt);
t.start();
JProgressDialog jpd = new JProgressDialog((Frame)
SwingUtilities.windowForComponent(this), true, wt);
}
}

///////////////////////////WorkerThread.java

public class WorkerThread implements ThreadProgressObservable
{
private int i;
private String statusText;
private boolean isRunning;
public void run()
{
isRunning=true;
for (i = 0; i <= 100; i++)
{
statusText = new Integer(i).toString();
try
{
Thread.sleep(200);
}
catch (InterruptedException e)
{
}
}
isRunning=false;
}
public int getProgress()
{
return i;
}
public String getText()
{
return statusText;
}
public boolean isRunning()
{
return isRunning;
}
}

///////////////////////////////JProgressDialog.java

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.*;
public class JProgressDialog extends JDialog implements WindowListener
{
private JLabel jl;
private JProgressBar jpb;
private ThreadProgressObservable workerthread;
public JProgressDialog(Frame owner, boolean modal, ThreadProgressObservable
wt)
{
super(owner, modal);
addWindowListener(this);
jpb = new JProgressBar();
jl = new JLabel("text");
getContentPane().add(jl, BorderLayout.NORTH);
getContentPane().add(jpb, BorderLayout.SOUTH);
pack();
workerthread = wt;
show();
}
public void SetText(String t)
{
jl.setText(t);
}
public void SetProgress()
{
}
public void doProgress()
{
Thread t = new Thread(new Runnable()
{
public void run()
{
while (workerthread.isRunning())
{
try
{
Thread.sleep(50);
}
catch (InterruptedException e)
{
}
jpb.setValue(workerthread.getProgress());
jl.setText(workerthread.getText());
}
}
});
t.start();
}
public void windowActivated(WindowEvent e)
{
doProgress();
}
public void windowClosed(WindowEvent e)
{
}
public void windowClosing(WindowEvent e)
{
}
public void windowDeactivated(WindowEvent e)
{
}
public void windowDeiconified(WindowEvent e)
{
}
public void windowIconified(WindowEvent e)
{
}
public void windowOpened(WindowEvent e)
{
}
}

//////////////////ThreadProgressObservable.java

public interface ThreadProgressObservable extends Runnable
{
public int getProgress ();
public String getText();
public boolean isRunning();
}




Back to top
Robert Ludewig
Guest





PostPosted: Mon Nov 17, 2003 12:53 am    Post subject: Re: making a modal progressdialog with SWING Reply with quote

what did you modify in JProgressDiaolog ? You did not paste that code ...

jpd = new JProgressDialog(frame, false);

false for non-modal right ? (I do not know your JProgressDiaolg-Class)

and you directly setting the value in the thread:

jpd.setValue(i);

right?

The goal is to have a _modal_ progressdialog and in your solution I do not
see a way how to modify the progressbar from the workerthread directly, like
you tried.
When a window is modal the show() or setVisible() blocks all code execution.
so SetValue(i) will have no effect ....

or am I confusing things here right now ?





Back to top
ak
Guest





PostPosted: Mon Nov 17, 2003 1:22 am    Post subject: Re: making a modal progressdialog with SWING Reply with quote

Robert, what you need is - add WindowListener to your dialog, on
windowOpened event you should start your job.
I am not sure, but it could work, another and better way is
http://www.javaworld.com/javaworld/javatips/jw-javatip89.html


"Robert Ludewig" <schwertfischtrombose (AT) gmx (DOT) de> schrieb im Newsbeitrag
news:bp967b$1lv6ik$1 (AT) ID-140548 (DOT) news.uni-berlin.de...
Quote:
what did you modify in JProgressDiaolog ? You did not paste that code ...

jpd = new JProgressDialog(frame, false);

false for non-modal right ? (I do not know your JProgressDiaolg-Class)

and you directly setting the value in the thread:

jpd.setValue(i);

right?

The goal is to have a _modal_ progressdialog and in your solution I do
not
see a way how to modify the progressbar from the workerthread directly,
like
you tried.
When a window is modal the show() or setVisible() blocks all code
execution.
so SetValue(i) will have no effect ....

or am I confusing things here right now ?








Back to top
Robert Ludewig
Guest





PostPosted: Mon Nov 17, 2003 1:43 am    Post subject: Re: making a modal progressdialog with SWING Reply with quote

Oh man I didn't know it is possible in such a simple way, did u mean it that
way:
(The only problem here is: the cancel-button must be on the JProgressDialg)
///////////////////////////////////////MainTestPanel.java
public class MainTestPanel extends JPanel
{
private JTextPane p;
private JProgressDialog jpd;
WorkerThread wt;
JButton btnStop = new JButton("Stop");
JButton btnStart = new JButton("Start");
public MainTestPanel(JFrame frame)
{
setLayout(new BorderLayout());
p = new JTextPane();
p.setPreferredSize(new Dimension(200, 200));
JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
jpd = new JProgressDialog(frame, false);
btnStart.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
btnStart.setEnabled(false);
btnStop.setEnabled(true);
wt = new WorkerThread(jpd);
Thread t;
t = new Thread(wt);
t.start();
jpd.pack();
jpd.setVisible(true);
}
});
btnStop.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
btnStart.setEnabled(true);
btnStop.setEnabled(false);
jpd.setVisible(false);
}
});
btnStop.setEnabled(false);
panel.add(btnStart);
panel.add(btnStop);
add(panel, BorderLayout.SOUTH);
add(p, BorderLayout.CENTER);
}
}
///////////////////////////////////MainTest.java
public class MainTest extends JFrame
{
public MainTest()
{
super("PanelViewer");
}

public static void CreateAndShowGUI()
{
JFrame frame = new MainTest();
WindowListener listener = new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
};

MainTestPanel mp = new MainTestPanel(frame);
frame.setContentPane(mp);
frame.addWindowListener(listener);
frame.setTitle("Test");
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args)
{
CreateAndShowGUI();
}
}
/////////////////JProgressDialog.java
public class JProgressDialog extends JDialog
{
private JLabel jl;
private JProgressBar jpb;
public JProgressDialog(Frame owner, boolean modal)
{
super(owner, modal);
jpb = new JProgressBar();
jl = new JLabel("text");
getContentPane().add(jl, BorderLayout.NORTH);
getContentPane().add(jpb, BorderLayout.SOUTH);
}
public void setText(String t)
{
jl.setText(t);
}
public void SetValue (int i)
{
jpb.setValue(i);
}
}
/////////////////////WorkerThread.java
public class WorkerThread implements Runnable
{
private int i;
boolean isRunning = true;
JProgressDialog jpd;
public WorkerThread(JProgressDialog jpd)
{
this.jpd = jpd;
}
public void run()
{
for (i = 0; i <= 100; i++)
{
if (!isRunning) return;
try
{
Thread.sleep(200);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
jpd.SetValue(i);
jpd.setTitle(new Integer (i).toString());
jpd.setText(new Integer (i).toString());
}
});
}
catch (InterruptedException e)
{
}
}
isRunning = false;
}
}


Back to top
R. Kevin Cole
Guest





PostPosted: Mon Nov 17, 2003 2:48 am    Post subject: Re: making a modal progressdialog with SWING Reply with quote

Here's the missing JProgressDialog. It can run as a modal
dialog, but you would have to move the "stop" button from
MainTestPanel to the JProgressDialog. I've implemented that
and will follow this post with a modal implementation. Sorry
for the confusion.



///////////////////////////////JProgressDialog.java
import java.awt.*;

import javax.swing.*;


public class JProgressDialog extends JDialog
{
private JLabel jl;
private JProgressBar jpb;
private ThreadProgressObservable workerthread;

public JProgressDialog(Frame owner, boolean modal )
{
super(owner, modal);
jpb = new JProgressBar();
jl = new JLabel("text");
getContentPane().add(jl, BorderLayout.NORTH);
getContentPane().add(jpb, BorderLayout.SOUTH);
pack();
}


public void setValue( int i )
{
jpb.setValue( i );
}

public void SetText(String t)
{
jl.setText(t);
}

public void SetProgress() {}
}


"Robert Ludewig" <schwertfischtrombose (AT) gmx (DOT) de> wrote:

Quote:
what did you modify in JProgressDiaolog ? You did not paste that code ...

jpd = new JProgressDialog(frame, false);

false for non-modal right ? (I do not know your JProgressDiaolg-Class)

and you directly setting the value in the thread:

jpd.setValue(i);

right?

The goal is to have a _modal_ progressdialog and in your solution I do not
see a way how to modify the progressbar from the workerthread directly, like
you tried.
When a window is modal the show() or setVisible() blocks all code execution.
so SetValue(i) will have no effect ....

or am I confusing things here right now ?






Back to top
R. Kevin Cole
Guest





PostPosted: Mon Nov 17, 2003 2:54 am    Post subject: Re: making a modal progressdialog with SWING Reply with quote

Here's the complete file set for the modal progress dialog.
I've changed ThreadProgressObservable to
ThreadProgressObserver to reflect its new role in the following
implementation.


////////////////////MainTest.java
import java.awt.event.*;
import javax.swing.*;

public class MainTest extends JFrame
{
public MainTest()
{
super("PanelViewer");
}

public static void CreateAndShowGUI()
{
JFrame frame = new MainTest();
WindowListener listener = new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
System.exit(0);
}
};
MainTestPanel mp = new MainTestPanel( frame );
frame.setContentPane(mp);
frame.addWindowListener(listener);
frame.setTitle("Test");
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args)
{
CreateAndShowGUI();
}
}

////////////////////MainTestPanel.java

import java.awt.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;

public class MainTestPanel extends JPanel
{
JTextPane p;
JProgressDialog jpd;
WorkerThread wt;

public MainTestPanel( final JFrame frame )
{
setLayout(new BorderLayout());
p = new JTextPane();
p.setPreferredSize(new Dimension(200, 200));

JPanel panel = new JPanel( new FlowLayout( FlowLayout.RIGHT ) );
JButton btnStart = new JButton("Start");
btnStart.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
wt = new WorkerThread();
jpd = new JProgressDialog(frame, wt, true);
wt.setThreadProgressObserver(jpd);

Thread t = new Thread(wt);
t.start();
jpd.setVisible(true);
}
});

panel.add(btnStart);
add(panel, BorderLayout.SOUTH);
add(p, BorderLayout.CENTER);
}
}


///////////////////////////////JProgressDialog.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class JProgressDialog extends JDialog implements ThreadProgressObserver
{
private JLabel jl;
private JProgressBar jpb;
private WorkerThread workerThread;

public JProgressDialog(Frame owner, WorkerThread wt, boolean modal )
{
super(owner, modal);

workerThread = wt;
jpb = new JProgressBar();
jl = new JLabel("text");
getContentPane().add(jl, BorderLayout.NORTH);
getContentPane().add(jpb, BorderLayout.CENTER);

JButton btnStop = new JButton("Cancel");
btnStop.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
workerThread.cancel();
setVisible(false);
}
});
JPanel panel = new JPanel( new FlowLayout( FlowLayout.CENTER ) );
panel.add(btnStop);
getContentPane().add(panel, BorderLayout.SOUTH);
pack();
}

// begin implementation of ThreadProgressObserver
public void setText(String t) { jl.setText(t); }
public String getText() { return jl.getText(); }
public int getProgress() { return jpb.getValue(); }
public void setProgress( int i ) { jpb.setValue( i ); System.out.println(""+i); }
// end implementation of ThreadProgressObserver
}

//////////////////ThreadProgressObserver.java

public interface ThreadProgressObserver
{
public int getProgress();
public void setProgress( int i );

public String getText();
public void setText( String s );
}


///////////////////////////WorkerThread.java

import javax.swing.SwingUtilities;

public class WorkerThread implements Runnable
{
private int i;
private String statusText;
boolean isRunning = true;
ThreadProgressObserver observer;

public WorkerThread() { }

public void run()
{
for(i = 0; i <= 100; i++)
{
if( !isRunning )
return;

statusText = new Integer(i).toString();

try
{
Thread.sleep(200);
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
if( (i % 10) == 0 )
observer.setText( i + "%");
observer.setProgress(i);
}
});
}
catch(InterruptedException e) {}
}
isRunning = false;
}

public void setThreadProgressObserver( ThreadProgressObserver o )
{
observer = o;
}

public void cancel()
{
isRunning = false;
}

public boolean isRunning()
{
return isRunning;
}
}

Back to top
R. Kevin Cole
Guest





PostPosted: Mon Nov 17, 2003 3:46 am    Post subject: Re: making a modal progressdialog with SWING Reply with quote

"Robert Ludewig" <schwertfischtrombose (AT) gmx (DOT) de> wrote:

Quote:
Oh man I didn't know it is possible in such a simple way, did u mean it that
way:

Yes. Check out my previous post for an implementation that uses
your ThreadObserveable (renamed ThreadObserver due to its changed
role in the new implementation).

Hope this helps,

Kevin


.....

Back to top
Robert Ludewig
Guest





PostPosted: Mon Nov 17, 2003 9:39 am    Post subject: Re: making a modal progressdialog with SWING Reply with quote

Thread t = new Thread(wt);
t.start();

Is that threadsafe ?

should`'t I use invokelate here too ?

But then it doesn't work anymore


Back to top
R. Kevin Cole
Guest





PostPosted: Mon Nov 17, 2003 2:21 pm    Post subject: Re: making a modal progressdialog with SWING Reply with quote

This is a thread-safe construct. A new thread is started
from Swing's event-dispatching thread. Thread safety issues
are a bigger issue when going in the other direction. That is, when
a thread needs to update the GUI. In that case, a method like
SwingUtilities.invokeLater is used to execute the GUI-update
code in Swing's event-dispatching thread.

If you call invokeLater from an event handler, which is running
on the event-dispatching thread, Swing will throw and exception.

For additional thread safety, check out the SwingWorker class.
You'll find it with a quick search at java.sun.com.

Kevin


"Robert Ludewig" <schwertfischtrombose (AT) gmx (DOT) de> wrote:

Quote:
Thread t = new Thread(wt);
t.start();

Is that threadsafe ?

should`'t I use invokelate here too ?

But then it doesn't work anymore



Back to top
Display posts from previous:   
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java GUI Toolkits All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.