J
John Raggio
I have done some reading on this and think that I understand it. I
have a some questions regarding a test program that I wrote. It
essentially tests menu items that lauch lengthy operations. I will
paste it in below.
1) If I have an action that takes some time, is there any way to have
the menu item that was clicked be dismissed before starting the
lengthy action? Depending on the L&F in use either the menu and its
text remains after clicking or the text is removed leaving only a gray
box behind. I realize the correct thing to do is to spawn a thread to
do the work, but I'd like to cheat a bit if I could.
2) Please explain why the method doItThreadedLater() takes MUCH longer
to run than doItThreaded(). My guess is that the overhead involved
with creating the extra objects and threads takes resources and time.
I also suspect that the fact that 4M events needs to be put on the
event queuue and processed may come into play. I also suspect that
doItThreaded() will allow for paints() to be combined more often. In
this case it just seems that doing it the right way takes much loinger
to execute, but is still the way to go.
I look forward to any commments.
Thanks,
John
+++++++++++++++++++++++++++++++++
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
/**
* @author raggioj, Feb 15, 2004
*/
public class TestMenu extends JFrame {
private static final int MAX = 4000000;
JProgressBar pb;
/**
* @throws java.awt.HeadlessException
*/
public TestMenu() throws HeadlessException {
super();
}
public TestMenu(String title){
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,200);
String cplf = UIManager.getCrossPlatformLookAndFeelClassName();
String slf = UIManager.getSystemLookAndFeelClassName();
try {
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel(cplf);
// threaded works fine and non-threaded menu text dismisses, but
gray box remains
// sometimes leads to threaded version working inconsistently and
even out
// of memeory errors
UIManager.setLookAndFeel(slf);
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MetalLookAndFeel");
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel("javax.swing.plaf.basic.BasicLookAndFeel");
}
catch (Exception e1) {}
JMenu menu = new JMenu("Window");
menu.setMnemonic(KeyEvent.VK_W);
JMenuItem item = null;
item = new JMenuItem("Threaded");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MyDialog d = new MyDialog("Threaded");
d.show();
d.doItThreaded();
}
});
menu.add(item);
item = new JMenuItem("Threaded Using Invoke Later");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MyDialog d = new MyDialog("Threaded Using Invoke
Later");
d.show();
d.doItThreadedLater();
}
});
menu.add(item);
menu.addSeparator();
item = new JMenuItem("Non-Threaded");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MyDialog d = new MyDialog("Non-Threaded");
d.show();
d.doItNonThreaded();
}
});
menu.add(item);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
setJMenuBar(menuBar);
JLabel l = new
JLabel(UIManager.getLookAndFeel().getClass().getName(),
SwingConstants.CENTER);
getContentPane().setBackground(Color.CYAN);
getContentPane().add(l,BorderLayout.CENTER);
}
public static void main(String[] args) {
final TestMenu t = new TestMenu("Menu Test App");
t.show();
}
class MyDialog extends JDialog{
JProgressBar pb;
public MyDialog(String title){
super(TestMenu.this, "Test Dialog : " + title);
setSize(400,200);
setLocation(300,300);
getContentPane().add(new JLabel("Progress:"), BorderLayout.NORTH);
pb = new JProgressBar();
pb.setPreferredSize(new Dimension(400, 50));
pb.setMaximum(MAX);
getContentPane().add(pb, BorderLayout.CENTER);
}
public void doItThreaded(){
new Thread(){
public void run(){
for(int i =0; i<= MAX ; i++){
pb.setValue(i);
}
}
}.start();
}
// MUCH slower using invoke later to update the gui than not
public void doItThreadedLater(){
new Thread(){
public void run(){
for(int i =0; i<= MAX ; i++){
final int t = i;
SwingUtilities.invokeLater( new Runnable() {
public void run() {
pb.setValue(t);
}
}
);
}
}
}.start();
}
public void doItNonThreaded(){
for(int i =0; i<= MAX ; i++){
pb.setValue(i);
}
/*
SwingUtilities.invokeLater(new Runnable() {
public void run() {
for(int i =0; i<= MAX ; i++){
pb.setValue(i);
}
}
});
*/
}
}
}
have a some questions regarding a test program that I wrote. It
essentially tests menu items that lauch lengthy operations. I will
paste it in below.
1) If I have an action that takes some time, is there any way to have
the menu item that was clicked be dismissed before starting the
lengthy action? Depending on the L&F in use either the menu and its
text remains after clicking or the text is removed leaving only a gray
box behind. I realize the correct thing to do is to spawn a thread to
do the work, but I'd like to cheat a bit if I could.
2) Please explain why the method doItThreadedLater() takes MUCH longer
to run than doItThreaded(). My guess is that the overhead involved
with creating the extra objects and threads takes resources and time.
I also suspect that the fact that 4M events needs to be put on the
event queuue and processed may come into play. I also suspect that
doItThreaded() will allow for paints() to be combined more often. In
this case it just seems that doing it the right way takes much loinger
to execute, but is still the way to go.
I look forward to any commments.
Thanks,
John
+++++++++++++++++++++++++++++++++
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
/**
* @author raggioj, Feb 15, 2004
*/
public class TestMenu extends JFrame {
private static final int MAX = 4000000;
JProgressBar pb;
/**
* @throws java.awt.HeadlessException
*/
public TestMenu() throws HeadlessException {
super();
}
public TestMenu(String title){
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400,200);
String cplf = UIManager.getCrossPlatformLookAndFeelClassName();
String slf = UIManager.getSystemLookAndFeelClassName();
try {
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel(cplf);
// threaded works fine and non-threaded menu text dismisses, but
gray box remains
// sometimes leads to threaded version working inconsistently and
even out
// of memeory errors
UIManager.setLookAndFeel(slf);
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MetalLookAndFeel");
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
// threaded looks fine and non threaded menu and menu text remains
when
// selecting non-threaded
// UIManager.setLookAndFeel("javax.swing.plaf.basic.BasicLookAndFeel");
}
catch (Exception e1) {}
JMenu menu = new JMenu("Window");
menu.setMnemonic(KeyEvent.VK_W);
JMenuItem item = null;
item = new JMenuItem("Threaded");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MyDialog d = new MyDialog("Threaded");
d.show();
d.doItThreaded();
}
});
menu.add(item);
item = new JMenuItem("Threaded Using Invoke Later");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MyDialog d = new MyDialog("Threaded Using Invoke
Later");
d.show();
d.doItThreadedLater();
}
});
menu.add(item);
menu.addSeparator();
item = new JMenuItem("Non-Threaded");
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MyDialog d = new MyDialog("Non-Threaded");
d.show();
d.doItNonThreaded();
}
});
menu.add(item);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
setJMenuBar(menuBar);
JLabel l = new
JLabel(UIManager.getLookAndFeel().getClass().getName(),
SwingConstants.CENTER);
getContentPane().setBackground(Color.CYAN);
getContentPane().add(l,BorderLayout.CENTER);
}
public static void main(String[] args) {
final TestMenu t = new TestMenu("Menu Test App");
t.show();
}
class MyDialog extends JDialog{
JProgressBar pb;
public MyDialog(String title){
super(TestMenu.this, "Test Dialog : " + title);
setSize(400,200);
setLocation(300,300);
getContentPane().add(new JLabel("Progress:"), BorderLayout.NORTH);
pb = new JProgressBar();
pb.setPreferredSize(new Dimension(400, 50));
pb.setMaximum(MAX);
getContentPane().add(pb, BorderLayout.CENTER);
}
public void doItThreaded(){
new Thread(){
public void run(){
for(int i =0; i<= MAX ; i++){
pb.setValue(i);
}
}
}.start();
}
// MUCH slower using invoke later to update the gui than not
public void doItThreadedLater(){
new Thread(){
public void run(){
for(int i =0; i<= MAX ; i++){
final int t = i;
SwingUtilities.invokeLater( new Runnable() {
public void run() {
pb.setValue(t);
}
}
);
}
}
}.start();
}
public void doItNonThreaded(){
for(int i =0; i<= MAX ; i++){
pb.setValue(i);
}
/*
SwingUtilities.invokeLater(new Runnable() {
public void run() {
for(int i =0; i<= MAX ; i++){
pb.setValue(i);
}
}
});
*/
}
}
}