Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #36780 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2017-06-30 10:35 -0700 |
| Last post | 2017-06-30 17:19 -0400 |
| Articles | 11 — 4 participants |
Back to article view | Back to comp.lang.java.programmer
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
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-06-30 10:35 -0700 |
| Subject | Can 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]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-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]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-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]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2017-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]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-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