Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #36780 > unrolled thread

Can you lock a dialog and continue?

Started byEric Douglas <e.d.programmer@gmail.com>
First post2017-06-30 10:35 -0700
Last post2017-06-30 17:19 -0400
Articles 11 — 4 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Can you lock a dialog and continue? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-30 10:35 -0700
    Re: Can you lock a dialog and continue? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-30 14:24 -0400
    Re: Can you lock a dialog and continue? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-30 11:34 -0700
      Re: Can you lock a dialog and continue? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-06-30 14:33 -0500
        Re: Can you lock a dialog and continue? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-30 13:19 -0700
          Re: Can you lock a dialog and continue? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-06-30 15:35 -0500
            Re: Can you lock a dialog and continue? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-30 13:56 -0700
          Re: Can you lock a dialog and continue? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-06-30 15:40 -0500
            Re: Can you lock a dialog and continue? Eric Douglas <e.d.programmer@gmail.com> - 2017-06-30 13:52 -0700
              Re: Can you lock a dialog and continue? Martin Gregorie <martin@address-in-sig.invalid> - 2017-06-30 21:14 +0000
              Re: Can you lock a dialog and continue? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-06-30 17:19 -0400

#36780 — Can you lock a dialog and continue?

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-06-30 10:35 -0700
SubjectCan you lock a dialog and continue?
Message-ID<34333fbb-4b83-454b-9395-4efaa019e95e@googlegroups.com>
I can display a window of type JDialog and keep running code, but if I display another one modal to that one to lock it, the code just freezes as soon as I make it visible until it's closed.  I was hoping to use this to pop up a window to show the user a processing status with a JProgressBar so they can't interact with the first window while the program updates it (need to do a background task to get data then populate the window).

public class WindowTest {
     public static void main(String[] args) {
          EventQueue.invokeLater(new Runnable() {

               @Override
               public void run() {
                    JDialog win1 = new JDialog();
                    win1.setVisible(true);
                    System.out.println("win 1 visible");
                    JDialog win2 = new JDialog(win1,true);
                    win2.setVisible(true);
                    System.out.println("win 2 visible");
               }
               
          });
     }

}
Displays 2 windows, then prints a second message only after you close the second window.

[toc] | [next] | [standalone]


#36781

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2017-06-30 14:24 -0400
Message-ID<oj64pn$b1s$1@dont-email.me>
In reply to#36780
On 6/30/2017 1:35 PM, Eric Douglas wrote:
> I can display a window of type JDialog and keep running code, but if I display another one modal to that one to lock it, the code just freezes as soon as I make it visible until it's closed.

     Um, er, that's what a "modal" dialog is supposed to do.  Consider
an input-gathering dialog, like one where the user chooses "Proceed"
vs. "Cancel."  The code shows the dialog, *waits until it closes*,
and collects the chosen answer.

     If you don't want to wait, use a modeless dialog.

> I was hoping to use this to pop up a window to show the user a processing status with a JProgressBar so they can't interact with the first window while the program updates it (need to do a background task to get data then populate the window).

     It's possible that I've failed to understand what you want to do,
but ... have you investigated javax.swing.ProgressMonitor?

-- 
esosman@comcast-dot-net.invalid
Thirteen hundred days to go.

[toc] | [prev] | [next] | [standalone]


#36782

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-06-30 11:34 -0700
Message-ID<fc1ca100-85e5-49fc-9f28-f961288b34e9@googlegroups.com>
In reply to#36780
I think I got it, how to make a non-modal dialog window which blocks it's parent but not the thread.  I just put this in the constructor.

addWindowListener(new WindowAdapter() {
          @Override
          public void windowOpened(final WindowEvent e) {
               Window curWin = e.getWindow();
               Window parent = curWin.getOwner();
               if (parent != null) {
                    parent.setEnabled(false);
               }
          }
          @Override
          public void windowClosing(final WindowEvent e) {
               Window curWin = e.getWindow();
               Window parent = curWin.getOwner();
               if (parent != null) {
                    parent.setEnabled(true);
               }
               curWin.dispose();
          }
     });

I want the user to wait, not the program.
I want to be able to execute a background process which may take a minute, and update controls on the screen which may take a minute possibly a table with a lot of values, and not let the user interact until any of that is done, and display a message with JProgressBar while they wait.

[toc] | [prev] | [next] | [standalone]


#36783

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-06-30 14:33 -0500
Message-ID<oj68qi$ohv$1@dont-email.me>
In reply to#36782
On 6/30/2017 13:34, Eric Douglas wrote:
> I want the user to wait, not the program.
> I want to be able to execute a background process which may take a minute, and update controls on the screen which may take a minute possibly a table with a lot of values, and not let the user interact until any of that is done, and display a message with JProgressBar while they wait.
> 

Use a modal dialog to stop user input.  Use a thread to do your work and 
then update your GUI/JProgressBar on the EDT.

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

public class test9 extends JFrame {
     private JProgressBar bar = new 
JProgressBar(SwingConstants.HORIZONTAL,0,10);

     public test9() {
         setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

         JButton start = new JButton("Start");
         start.addActionListener(event -> {
             JDialog dialog = new JDialog(this,true);
             dialog.addWindowListener(new WindowAdapter() {
                 public void windowOpened(WindowEvent we) {
                     new Thread(() -> {
                         int n = 0;
                         while (n < 11) {
                             int q = n;
                             EventQueue.invokeLater(() -> bar.setValue(q));
                             try { Thread.sleep(1000);
                             } catch (InterruptedException ie) { }
                             ++n;
                         }
                         dialog.dispose();
                     }).start();
                 }
             });
             dialog.add(bar,BorderLayout.CENTER);
             dialog.pack();
             dialog.setVisible(true);
         });
         add(start,BorderLayout.CENTER);
         pack();
         setVisible(true);
     }

     public static void main(String... args) {
         EventQueue.invokeLater(() -> new test9());
     }
}



-- 

Knute Johnson

[toc] | [prev] | [next] | [standalone]


#36784

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-06-30 13:19 -0700
Message-ID<c4b02e21-c034-43a5-be42-c5b2d5276a83@googlegroups.com>
In reply to#36783
On Friday, June 30, 2017 at 3:33:27 PM UTC-4, Knute Johnson wrote:
>...

I was thinking more of a reusable process window I can show and hide from anywhere that could take a second?
My test with 2 dialogs just disabling so I can keep running, rather than stopping for user input and putting everything inside the window open listener, sort of works.  Why can't I add new objects to the first window?

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

public class WindowTest {

     public static void main(final String[] args) {
          EventQueue.invokeLater(new Runnable() {

               @Override
               public void run() {
                    final JDialog win1 = new JDialog();
                    win1.setLayout(new BorderLayout());
                    win1.addWindowListener(new WindowAdapter() {

                         @Override
                         public void windowClosing(final WindowEvent e) {
                              e.getWindow().dispose();
                         }
                    });
                    win1.setSize(400, 300);
                    final JButton btn1 = new JButton("button one");
                    btn1.addActionListener(new ActionListener() {

                         @Override
                         public void actionPerformed(final ActionEvent e) {
                              System.out.println("clicked one");
                         }

                    });
                    win1.getContentPane().add(btn1, BorderLayout.PAGE_START);
                    win1.setVisible(true);
                    System.out.println("win 1 visible");
                    final JDialog win2 = new JDialog(win1);
                    win2.addWindowListener(new WindowAdapter() {

                         @Override
                         public void windowOpened(final WindowEvent e) {
                              final Window curWin = e.getWindow();
                              final Window parent = curWin.getOwner();
                              if (parent != null) {
                                   parent.setEnabled(false);
                              }
                         }

                         @Override
                         public void windowClosing(final WindowEvent e) {
                              final Window curWin = e.getWindow();
                              final Window parent = curWin.getOwner();
                              if (parent != null) {
                                   parent.setEnabled(true);
                              }
                              curWin.dispose();
                         }
                    });
                    // This works if I execute it here
                    // win1.getContentPane().add(new JLabel("Updated"),BorderLayout.PAGE_END);
                    win2.setSize(400, 150);
                    win2.setLocationRelativeTo(win1);
                    win2.setLayout(new BorderLayout());
                    final JProgressBar pb = new JProgressBar();
                    pb.setString("Hang on we're updating");
                    pb.setStringPainted(true);
                    pb.setIndeterminate(true);
                    win2.add(pb,BorderLayout.CENTER);
                    final JButton btn2 = new JButton("close me");
                    btn2.addActionListener(new ActionListener() {

                         @Override
                         public void actionPerformed(final ActionEvent e) {
                              System.out.println("clicked two");
                              final WindowEvent wev = new WindowEvent(win2, WindowEvent.WINDOW_CLOSING);
                              Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
                         }

                    });
                    btn2.setVisible(false);
                    win2.getContentPane().add(btn2,BorderLayout.PAGE_END);
                    win2.dispose();
                    win2.setUndecorated(true);
                    win2.setVisible(true);
                    System.out.println("win 2 visible");
                    final SwingWorker sw = new SwingWorker() {

                         @Override
                         protected Object doInBackground() throws Exception {
                              Thread.sleep(1000);
                              return null;
                         }

                         @Override
                         public void done() {
                              // button can display because it's already added
                              btn2.setVisible(true);
                              // Doesn't show up when I execute it here
                              win1.getContentPane().add(new JLabel("Updated"), BorderLayout.PAGE_END);
                              System.out.println("done");
                         }
                    };
                    sw.execute();
               }
          });
     }
}

[toc] | [prev] | [next] | [standalone]


#36785

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-06-30 15:35 -0500
Message-ID<oj6cg4$55h$1@dont-email.me>
In reply to#36784
On 6/30/2017 15:19, Eric Douglas wrote:
> On Friday, June 30, 2017 at 3:33:27 PM UTC-4, Knute Johnson wrote:
>> ...
> 
> I was thinking more of a reusable process window I can show and hide from anywhere that could take a second?
> My test with 2 dialogs just disabling so I can keep running, rather than stopping for user input and putting everything inside the window open listener, sort of works.  Why can't I add new objects to the first window?
> 
> import java.awt.BorderLayout;
> import java.awt.EventQueue;
> import java.awt.Toolkit;
> import java.awt.Window;
> import java.awt.event.ActionEvent;
> import java.awt.event.ActionListener;
> import java.awt.event.WindowAdapter;
> import java.awt.event.WindowEvent;
> 
> import javax.swing.JButton;
> import javax.swing.JDialog;
> import javax.swing.JLabel;
> import javax.swing.JProgressBar;
> import javax.swing.SwingWorker;
> 
> public class WindowTest {
> 
>       public static void main(final String[] args) {
>            EventQueue.invokeLater(new Runnable() {
> 
>                 @Override
>                 public void run() {
>                      final JDialog win1 = new JDialog();
>                      win1.setLayout(new BorderLayout());
>                      win1.addWindowListener(new WindowAdapter() {
> 
>                           @Override
>                           public void windowClosing(final WindowEvent e) {
>                                e.getWindow().dispose();
>                           }
>                      });
>                      win1.setSize(400, 300);
>                      final JButton btn1 = new JButton("button one");
>                      btn1.addActionListener(new ActionListener() {
> 
>                           @Override
>                           public void actionPerformed(final ActionEvent e) {
>                                System.out.println("clicked one");
>                           }
> 
>                      });
>                      win1.getContentPane().add(btn1, BorderLayout.PAGE_START);
>                      win1.setVisible(true);
>                      System.out.println("win 1 visible");
>                      final JDialog win2 = new JDialog(win1);
>                      win2.addWindowListener(new WindowAdapter() {
> 
>                           @Override
>                           public void windowOpened(final WindowEvent e) {
>                                final Window curWin = e.getWindow();
>                                final Window parent = curWin.getOwner();
>                                if (parent != null) {
>                                     parent.setEnabled(false);
>                                }
>                           }
> 
>                           @Override
>                           public void windowClosing(final WindowEvent e) {
>                                final Window curWin = e.getWindow();
>                                final Window parent = curWin.getOwner();
>                                if (parent != null) {
>                                     parent.setEnabled(true);
>                                }
>                                curWin.dispose();
>                           }
>                      });
>                      // This works if I execute it here
>                      // win1.getContentPane().add(new JLabel("Updated"),BorderLayout.PAGE_END);
>                      win2.setSize(400, 150);
>                      win2.setLocationRelativeTo(win1);
>                      win2.setLayout(new BorderLayout());
>                      final JProgressBar pb = new JProgressBar();
>                      pb.setString("Hang on we're updating");
>                      pb.setStringPainted(true);
>                      pb.setIndeterminate(true);
>                      win2.add(pb,BorderLayout.CENTER);
>                      final JButton btn2 = new JButton("close me");
>                      btn2.addActionListener(new ActionListener() {
> 
>                           @Override
>                           public void actionPerformed(final ActionEvent e) {
>                                System.out.println("clicked two");
>                                final WindowEvent wev = new WindowEvent(win2, WindowEvent.WINDOW_CLOSING);
>                                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
>                           }
> 
>                      });
>                      btn2.setVisible(false);
>                      win2.getContentPane().add(btn2,BorderLayout.PAGE_END);
>                      win2.dispose();
>                      win2.setUndecorated(true);
>                      win2.setVisible(true);
>                      System.out.println("win 2 visible");
>                      final SwingWorker sw = new SwingWorker() {
> 
>                           @Override
>                           protected Object doInBackground() throws Exception {
>                                Thread.sleep(1000);
>                                return null;
>                           }
> 
>                           @Override
>                           public void done() {
>                                // button can display because it's already added
>                                btn2.setVisible(true);
>                                // Doesn't show up when I execute it here
>                                win1.getContentPane().add(new JLabel("Updated"), BorderLayout.PAGE_END);
>                                System.out.println("done");
>                           }
>                      };
>                      sw.execute();
>                 }
>            });
>       }
> }
> 

win1.validate();		// see Container.validate()

Are you using some old version of Java?  You don't need all those finals 
or the getContentPane() calls any more.


-- 

Knute Johnson

[toc] | [prev] | [next] | [standalone]


#36788

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-06-30 13:56 -0700
Message-ID<671fa03b-17fc-4bec-ab97-1f0076427ae3@googlegroups.com>
In reply to#36785
On Friday, June 30, 2017 at 4:36:11 PM UTC-4, Knute Johnson wrote:
> 
> win1.validate();		// see Container.validate()
> 
That's a tricky one.  validate() does make that text appear.  I had tested invalidate(), which doesn't.

> Are you using some old version of Java?  You don't need all those finals 
> or the getContentPane() calls any more.
>
No, latest Java.  I don't know if declaring things final or calling getContentPane() in front of an add() helps or hurts anything in the compile or execution or if it's all the same now, aside from where it is necessary (final to ensure a variable won't be changed, and to allow a reference to a variable from an inner or inline class).

[toc] | [prev] | [next] | [standalone]


#36786

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-06-30 15:40 -0500
Message-ID<oj6cot$55h$2@dont-email.me>
In reply to#36784
On 6/30/2017 15:19, Eric Douglas wrote:
> I was thinking more of a reusable process window I can show and hide from anywhere that could take a second?
> My test with 2 dialogs just disabling so I can keep running, rather than stopping for user input and putting everything inside the window open listener, sort of works.  Why can't I add new objects to the first window?

The whole purpose of a modal dialog is to allow you to suspend user 
input.  You don't have to use the dialog's window listener to start your 
next process, that was just to keep the example simple.

I think you ought to use a modal dialog for this unless you haven't 
completely described what you are trying to do (or I can't understand 
what you are up to :-).

-- 

Knute Johnson

[toc] | [prev] | [next] | [standalone]


#36787

FromEric Douglas <e.d.programmer@gmail.com>
Date2017-06-30 13:52 -0700
Message-ID<c0a4a596-736b-48a8-8314-ff2282214aab@googlegroups.com>
In reply to#36786
On Friday, June 30, 2017 at 4:40:44 PM UTC-4, Knute Johnson wrote:
> 
> I think you ought to use a modal dialog for this unless you haven't 
> completely described what you are trying to do (or I can't understand 
> what you are up to :-).
> 

What I'm trying to do:  Create a window (using JDialog for every window which allows linking to other JDialog and customizing decorations).  Add something for user to do (ie a JTextField to type value, a JButton to submit value).  They click button, it runs a background process, which could take a minute.  While the process is running it displays a popup window with a progress bar that tells them it's running, and percentage complete if possible.  When the background process finishes getting data we want to update the main screen, possibly populating a JTable.  When the GUI is finished updating I want to close/hide the popup.

[toc] | [prev] | [next] | [standalone]


#36789

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2017-06-30 21:14 +0000
Message-ID<oj6ev5$9mp$1@dont-email.me>
In reply to#36787
On Fri, 30 Jun 2017 13:52:30 -0700, Eric Douglas wrote:

> On Friday, June 30, 2017 at 4:40:44 PM UTC-4, Knute Johnson wrote:
>> 
>> I think you ought to use a modal dialog for this unless you haven't
>> completely described what you are trying to do (or I can't understand
>> what you are up to :-).
>> 
>> 
> What I'm trying to do:  Create a window (using JDialog for every window
> which allows linking to other JDialog and customizing decorations).  Add
> something for user to do (ie a JTextField to type value, a JButton to
> submit value).  They click button, it runs a background process, which
> could take a minute.  While the process is running it displays a popup
> window with a progress bar that tells them it's running, and percentage
> complete if possible.  When the background process finishes getting data
> we want to update the main screen, possibly populating a JTable.  When
> the GUI is finished updating I want to close/hide the popup.
>
I think I'd design it a little differently, but of course ymmv. I would:

- pop up a dialog box to get the user's input

- once you've got their input you don't need the dialog box any more,
  so close it. You don't mention that the user can stop the long-running
  process so I assume that they can't stop it, which means you don't need
  the pop-up any more.

- start the background process (thread)

  - this displays a new window with the progress bar in it,

  - updates the progress bar while the process is running

  - closes the progress window when the process is complete

  - force the main screen to update

  - terminate the thread

If the user CAN stop the background process, I'd not bother with the 
dialog box, but just use a window containing:

 - the user input area
 - the progress bar
 - two JButtons, labelled 'Start' (inactive) and 'Quit' (active)

which would only vanish when the background process has ended. This 
arrangement lets the user quit at any time, but the Start button would 
only become active when the value has been entered.
 

-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


#36790

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2017-06-30 17:19 -0400
Message-ID<oj6f13$cu4$1@dont-email.me>
In reply to#36787
On 6/30/2017 4:52 PM, Eric Douglas wrote:
> On Friday, June 30, 2017 at 4:40:44 PM UTC-4, Knute Johnson wrote:
>>
>> I think you ought to use a modal dialog for this unless you haven't
>> completely described what you are trying to do (or I can't understand
>> what you are up to :-).
>>
> 
> What I'm trying to do:  Create a window (using JDialog for every window which allows linking to other JDialog and customizing decorations).  Add something for user to do (ie a JTextField to type value, a JButton to submit value).  They click button, it runs a background process, which could take a minute.  While the process is running it displays a popup window with a progress bar that tells them it's running, and percentage complete if possible.  When the background process finishes getting data we want to update the main screen, possibly populating a JTable.  When the GUI is finished updating I want to close/hide the popup.

https://docs.oracle.com/javase/8/docs/api/javax/swing/ProgressMonitor.html

http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html#monitors

-- 
esosman@comcast-dot-net.invalid
Thirteen hundred days to go.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web