Reputation: 417
I have created an extension of JDialog
.
public class ImageDialog extends JDialog implements ActionListener {
private JTextField textField;
public ImageDialog(JFrame parent, String title,
String message, BufferedImage bufferedImage) {
super(parent, title, true);
if (parent != null) {
Dimension parentSize = parent.getSize();
Point p = parent.getLocation();
setLocation(p.x + parentSize.width / 4, p.y + parentSize.height / 4);
}
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.setModal(true);
JPanel frame = new JPanel();
frame.setLayout(new BoxLayout(frame, BoxLayout.Y_AXIS));
frame.add(new JLabel(message), BorderLayout.PAGE_START);
JLabel lblimage = new JLabel(new ImageIcon(bufferedImage));
frame.add(lblimage, BorderLayout.CENTER);
textField = new JTextField(1);
frame.add(textField, BorderLayout.PAGE_END);
getContentPane().add(frame);
JPanel buttonPane = new JPanel();
JButton button = new JButton("OK");
buttonPane.add(button);
button.addActionListener(this);
getContentPane().add(buttonPane, BorderLayout.SOUTH);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setVisible(true);
}
public String getTextField() {
return textField.getText();
}
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
}
}
It works well and does what's it supposed to do, except that jvm won't close after it's been used. I use it as follows:
ImageDialog dlg = new ImageDialog(new JFrame(), "Important question", "How many fluffy bunnies do you see?", img);
System.out.println(dlg.getTextField());
dlg.dispose();
But JVM just hangs there when the program is done. Is there any way to fix this?
Upvotes: 3
Views: 1606
Reputation: 3652
//Set all your:
.DISPOSE_ON_CLOSE
//to:
.EXIT_ON_CLOSE
//and if dispose(); is the last thing to happen change it to:
System.exit(0);
EDIT for comment answer:
System.gc();
dialog.setVisible(false);
The JVM will run as long as your program is running so I don't see the issue with that.
Upvotes: 2
Reputation: 168815
It seems to work just fine in this SSCCE that uses DISPOSE_ON_CLOSE
for the dialogs as well as the frame.
Note: When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate.
That note is important if the app. uses DISPOSE_ON_CLOSE
consistently and the VM fails to terminate. It indicates that there is a stray non-daemon thread running (amok?). Better to find the source of that thread and take reasonable action to terminate it gracefully.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class ImageDialog extends JDialog implements ActionListener {
private JTextField textField;
public static void main(String[] args) {
JFrame f = new JFrame("Image Dialog Test");
BufferedImage bi = new BufferedImage(128,50,BufferedImage.TYPE_INT_RGB);
f.setLocationByPlatform(true);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setSize(400,100);
f.setVisible(true);
new ImageDialog(f, "Hi!", "Hello World", bi);
}
public ImageDialog(JFrame parent, String title,
String message, BufferedImage bufferedImage) {
super(parent, title, true);
if (parent != null) {
Dimension parentSize = parent.getSize();
Point p = parent.getLocation();
setLocation(p.x + parentSize.width / 4, p.y + parentSize.height / 4);
}
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.setModal(true);
JPanel frame = new JPanel();
frame.setLayout(new BoxLayout(frame, BoxLayout.Y_AXIS));
frame.add(new JLabel(message), BorderLayout.PAGE_START);
JLabel lblimage = new JLabel(new ImageIcon(bufferedImage));
frame.add(lblimage, BorderLayout.CENTER);
textField = new JTextField(1);
frame.add(textField, BorderLayout.PAGE_END);
getContentPane().add(frame);
JPanel buttonPane = new JPanel();
JButton button = new JButton("OK");
buttonPane.add(button);
button.addActionListener(this);
getContentPane().add(buttonPane, BorderLayout.SOUTH);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setVisible(true);
}
public String getTextField() {
return textField.getText();
}
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
}
}
Upvotes: 3
Reputation: 8928
You need to set for your frame setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Or in any other place:
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
After closing dialog program will exit.
For dialog you should set DISPOSE_ON_CLOSE
close operation property. Dialog is frame dependent. Your program will end when you close your frame.
That's why don't forget to make your frame visible.
EDIT
Instead of this:
ImageDialog dlg = new ImageDialog(new JFrame(), "Screen captcha", "Enter the letters from the image", img);
System.out.println(dlg.getTextField());
dlg.dispose();
You should have sth like this:
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
//ideally frame should have a button that creates the dialog and sets it to visible
// no need to dispose dialog here
Upvotes: 5