 |
AppletTalk.com Java discussions newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Robert Ludewig Guest
|
Posted: Sat Nov 15, 2003 12:51 pm Post subject: making a modal progressdialog with SWING |
|
|
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
|
Posted: Sat Nov 15, 2003 3:33 pm Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Sat Nov 15, 2003 5:47 pm Post subject: Re: making a modal progressdialog with SWING |
|
|
| 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
|
Posted: Sat Nov 15, 2003 6:01 pm Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Sat Nov 15, 2003 6:49 pm Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Sat Nov 15, 2003 6:50 pm Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Sun Nov 16, 2003 10:00 pm Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Mon Nov 17, 2003 12:53 am Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Mon Nov 17, 2003 1:22 am Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Mon Nov 17, 2003 1:43 am Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Mon Nov 17, 2003 2:48 am Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Mon Nov 17, 2003 2:54 am Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Mon Nov 17, 2003 3:46 am Post subject: Re: making a modal progressdialog with SWING |
|
|
"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
|
Posted: Mon Nov 17, 2003 9:39 am Post subject: Re: making a modal progressdialog with SWING |
|
|
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
|
Posted: Mon Nov 17, 2003 2:21 pm Post subject: Re: making a modal progressdialog with SWING |
|
|
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 |
|
 |
|
|
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
|
|