I have a simple code, what it does is first there's a Frame with a button, if you click the button a message dialog appears, how will I set the visibility of the main frame to false when the button is pressed, then set back the visibility to true when the user clicks 'Ok' in the message dialog
here's the code:
package something;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*; //notice javax
public class Something extends JFrame implements ActionListener {
JLabel answer = new JLabel("");
JPanel pane = new JPanel();
JButton somethingButton = new JButton("Something");
Something() {
super("Something");
setBounds(100, 100, 300, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane(); // inherit main frame
con.add(pane); // add the panel to frame
pane.add(somethingButton);
somethingButton.requestFocus();
somethingButton.addActionListener(this);
setVisible(true); // display this frame
}
#Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == somethingButton) {
answer.setText("Button pressed!");
JOptionPane.showMessageDialog(null, "Something", "Message Dialog",
JOptionPane.PLAIN_MESSAGE);
setVisible(true); // show something
}
}
public static void main(String args[]) {
Something something = new Something();
}
}
#Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == somethingButton) {
answer.setText("Button pressed!");
setVisible(false); // hide something
JOptionPane.showMessageDialog(this, "Something", "Message Dialog",JOptionPane.PLAIN_MESSAGE);
setVisible(true); // show something
}
}
Related
Having an issue with some bits of my code.
label1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
label1.setText(-Here i want the button to open up a new "update window, and it will update the label to the text i'll provide in a seperate window);
}
});
Is there any way to do it without without an additional form? Just wanted to add that i have several labels, and i'm not sure on how to start with it.
One approach is to return a result from your update dialog which you can then use to update the text in label1. Here's an example which updates the label text based on the result return from a JOptionPane
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setMinimumSize(new Dimension(200, 85));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JLabel label = new JLabel("Original Text");
frame.add(label);
JButton button = new JButton("Click Me");
frame.add(button);
// to demonstrate, a JOptionPane will be used, but this could be replaced with a custom dialog or other control
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(frame, "Should I update the label?", "Test", JOptionPane.OK_CANCEL_OPTION );
// if the user selected 'Ok' then updated the label text
if(result == JOptionPane.OK_OPTION) {
label.setText("Updated text");
}
}
});
frame.setVisible(true);
}
});
}
}
Another approach would be to use an Observer and Observable which would listen for updates and change the label text accordingly. For more on the Observer, take a look at this question: When should we use Observer and Observable
public void windowClosing (WindowEvent e)
{
JFrame frame = new JFrame();
int confirm = JOptionPane.showConfirmDialog (frame, "Exit game?", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (confirm == JOptionPane.YES_OPTION)
{
dispose ();
}
else
{
frame.setVisible(false);
}
}
So when the user clicks on the close button, a JOptionPane pops up. When the user clicks on "No" the JOptionpane is supposed to disappear and then return to the frame it was originally displaying, but with my code, even when I click on No, both frames, the one for the JOptionPane and the one it sits on, disappear.
One thing:
I know I should not create a new JFrame for a JOptionPane, but I tried using this for the component, like: JOptionPane.showConfirmDialog (this, "...",...) when the user clicks on "No" the JOptionPane is the only thing that's supposed to disappear (so I set it to: this.setVisible(false);) but when I use this even the main frame disappears, so I just thought to create a new frame to meet my needs. I can't set it to null either because I need it to appear at the center of the screen. If anyone could advise me on how to handle this, please do.
It's really simple, your frame disappear because you say that it should not be visible, just remove that else:
public void windowClosing (WindowEvent e) {
int confirm = JOptionPane.showConfirmDialog (this, "Exit game?", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (confirm == JOptionPane.YES_OPTION) {
dispose();
}
}
EDIT:
Also replace setDefaultCloseOperation (EXIT_ON_CLOSE); with setDefaultCloseOperation (DO_NOTHING_ON_CLOSE);, else the main frame would close regardless of what happens in the windowClosing method.
Just don't put else if you don't want to hide the frame. The JOptionPane will disappear by itself, whether you click yes or no.
Don't create a new JFrame in the method. That's why you have random frame from now where.
public void windowClosing (WindowEvent e)
{
JFrame frame = new JFrame();
Pass the reference of the JFrame in question. If the code above is from a JDialog you can do something like this
public class MyDialog extends JDialog {
public MyDialog(final JFrame frame, boolean modal) {
super(frame, modal);
public void windowClosing (WindowEvent e) {
int confirm = JOptionPane.showConfirmDialog (frame, "Exit game?", "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (confirm == JOptionPane.YES_OPTION) {
dispose ();
}
}
}
}
And just instantiate the JDialog like this from your GUI class with the JFrame
MyDialog dialog = new MyDialog(thisFrame, true);
Side Note
Why Even have a JOptionPane and a JDialog? Ultimately, a JDialog is just a custom JOptionPane, they have the same functionality.
EDIT
If you just want to pass the JFrame class as reference to the JOPtionPane just pass
MyFrameClass.this
instead of a new JFrame()
UDPATE
Test out this program using a simple custom JDialog.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class JDialogExample extends JFrame {
public JDialogExample() {
JButton exit = new JButton("Do you want to Exit?");
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new HelloDialog(JDialogExample.this, true);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(exit);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private class HelloDialog extends JDialog {
public HelloDialog(final JFrame frame, boolean modal) {
super(frame, modal);
JButton exit = new JButton("EXIT");
JButton cancel = new JButton("CANCEL");
setLayout(new GridLayout(2, 1));
JPanel panel = new JPanel();
panel.add(exit);
panel.add(cancel);
add(new JLabel("Do you want to exit?", JLabel.CENTER));
add(panel);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JDialogExample();
}
});
}
}
Could you please help me on this one? I have a JDialog with some textfields, checkboxes and buttons. I want that when the frame is not focused anymore, to disappear. So I added a focus listener to the JDialog and when the focus is lost, I call dialog.setVisible(false);. The problem is that if I click on the checkbox,textfield or button, the frame loses it's focus and disappears. How could I keep it focused until the user clicks outside it's area?
EDIT : The "frame" I am referring to is a JDialog. I don't use a Frame nor a JFrame. All the components are placed on the JDialog. I want it to hide when not focused, but keep it focused until the user clicks outside it's area.
Seems like you had added the wrong Listener, what you should be adding is addWindowFocusListener(...), see this small sample program, is this what you want to happen :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogFocus
{
private JFrame frame;
private MyDialog myDialog;
public DialogFocus()
{
}
private void createAndDisplayGUI()
{
frame = new JFrame("JFRAME");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
myDialog = new MyDialog(frame, "My Dialog", false);
JButton showButton = new JButton("SHOW DIALOG");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (!(myDialog.isShowing()))
myDialog.setVisible(true);
}
});
frame.add(showButton, BorderLayout.PAGE_END);
frame.setSize(300, 300);
frame.setVisible(true);
}
public static void main(String\u005B\u005D args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new DialogFocus().createAndDisplayGUI();
}
});
}
}
class MyDialog extends JDialog
{
private WindowFocusListener windowFocusListener;
public MyDialog(JFrame frame, String title, boolean isModal)
{
setTitle(title);
setModal(isModal);
JPanel contentPane = new JPanel();
JTextField tfield = new JTextField(10);
JComboBox cbox = new JComboBox();
cbox.addItem("One");
cbox.addItem("Two");
cbox.addItem("Three");
contentPane.add(tfield);
contentPane.add(cbox);
windowFocusListener = new WindowFocusListener()
{
public void windowGainedFocus(WindowEvent we)
{
}
public void windowLostFocus(WindowEvent we)
{
setVisible(false);
}
};
addWindowFocusListener(windowFocusListener);
add(contentPane);
pack();
}
}
Make the dialog modal, then the user cannot click on the frame.
Check the FocusEvent
it has public Component getOppositeComponent(). If the opposite component is child component of the JDialog don't hide the dialog.
I have main application where is table with values. Then, I click "Add" button, new CUSTOM (I made it myself) JDialog type popup comes up. There I can input value, make some ticks and click "Confirm". So I need to read that input from dialog, so I can add this value to table in main application.
How can I listen when "confirm" button is pressed, so I can read that value after that?
addISDialog = new AddISDialog();
addISDialog.setVisible(true);
addISDialog.setLocationRelativeTo(null);
//somekind of listener...
//after "Confirm" button in dialog was pressed, get value
value = addISDialog.ISName;
If the dialog will disappear after the user presses confirm:
and you wish to have the dialog behave as a modal JDialog, then it's easy, since you know where in the code your program will be as soon as the user is done dealing with the dialog -- it will be right after you call setVisible(true) on the dialog. So you simply query the dialog object for its state in the lines of code immediately after you call setVisible(true) on the dialog.
If you need to deal with a non-modal dialog, then you'll need to add a WindowListener to the dialog to be notified when the dialog's window has become invisible.
If the dialog is to stay open after the user presses confirm:
Then you should probably use a PropertyChangeListener as has been suggested above. Either that or give the dialog object a public method that allows outside classes the ability to add an ActionListener to the confirm button.
For more detail, please show us relevant bits of your code, or even better, an sscce.
For example to allow the JDialog class to accept outside listeners, you could give it a JTextField and a JButton:
class MyDialog extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
and a method that allows outside classes to add an ActionListener to the button:
public void addConfirmListener(ActionListener listener) {
confirmBtn.addActionListener(listener);
}
Then an outside class can simply call the `addConfirmListener(...) method to add its ActionListener to the confirmBtn.
For example:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class OutsideListener extends JFrame {
private JTextField textField = new JTextField(10);
private JButton showDialogBtn = new JButton("Show Dialog");
private MyDialog myDialog = new MyDialog(this, "My Dialog");
public OutsideListener(String title) {
super(title);
textField.setEditable(false);
showDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (!myDialog.isVisible()) {
myDialog.setVisible(true);
}
}
});
// !! add a listener to the dialog's button
myDialog.addConfirmListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text = myDialog.getTextFieldText();
textField.setText(text);
}
});
JPanel panel = new JPanel();
panel.add(textField);
panel.add(showDialogBtn);
add(panel);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static void createAndShowGui() {
JFrame frame = new OutsideListener("OutsideListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyDialog extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
public MyDialog(JFrame frame, String title) {
super(frame, title, false);
JPanel panel = new JPanel();
panel.add(textfield);
panel.add(confirmBtn);
add(panel);
pack();
setLocationRelativeTo(frame);
}
public String getTextFieldText() {
return textfield.getText();
}
public void addConfirmListener(ActionListener listener) {
confirmBtn.addActionListener(listener);
}
}
Caveats though: I don't recommend subclassing JFrame or JDialog unless absolutely necessary. It was done here simply for the sake of brevity. I also myself prefer to use a modal dialog for solving this problem and just re-opening the dialog when needed.
Edit 2
An example of use of a Modal dialog:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class OutsideListener2 extends JFrame {
private JTextField textField = new JTextField(10);
private JButton showDialogBtn = new JButton("Show Dialog");
private MyDialog2 myDialog = new MyDialog2(this, "My Dialog");
public OutsideListener2(String title) {
super(title);
textField.setEditable(false);
showDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (!myDialog.isVisible()) {
myDialog.setVisible(true);
textField.setText(myDialog.getTextFieldText());
}
}
});
JPanel panel = new JPanel();
panel.add(textField);
panel.add(showDialogBtn);
add(panel);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static void createAndShowGui() {
JFrame frame = new OutsideListener2("OutsideListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyDialog2 extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
public MyDialog2(JFrame frame, String title) {
super(frame, title, true); // !!!!! made into a modal dialog
JPanel panel = new JPanel();
panel.add(new JLabel("Please enter a number between 1 and 100:"));
panel.add(textfield);
panel.add(confirmBtn);
add(panel);
pack();
setLocationRelativeTo(frame);
ActionListener confirmListener = new ConfirmListener();
confirmBtn.addActionListener(confirmListener); // add listener
textfield.addActionListener(confirmListener );
}
public String getTextFieldText() {
return textfield.getText();
}
private class ConfirmListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String text = textfield.getText();
if (isTextValid(text)) {
MyDialog2.this.setVisible(false);
} else {
// show warning
String warning = "Data entered, \"" + text +
"\", is invalid. Please enter a number between 1 and 100";
JOptionPane.showMessageDialog(confirmBtn,
warning,
"Invalid Input", JOptionPane.ERROR_MESSAGE);
textfield.setText("");
textfield.requestFocusInWindow();
}
}
}
// true if data is a number between 1 and 100
public boolean isTextValid(String text) {
try {
int number = Integer.parseInt(text);
if (number > 0 && number <= 100) {
return true;
}
} catch (NumberFormatException e) {
// one of the few times it's OK to ignore an exception
}
return false;
}
}
Why don't you check if your jDialog is visible?
yourJD.setVisible(true);
while(yourJD.isVisible())try{Thread.sleep(50);}catch(InterruptedException e){}
this works, also.
import javax.swing.JOptionPane;
or if you're already swinging
import javax.swing.*;
will have you covered.
After conditional trigger JOptionPane to send your warning or whatever modal message:
JOptionPane.showMessageDialog(
null,
"Your warning String: I can't do that John",
"Window Title",
JOptionPane.ERROR_MESSAGE);
check your options for JOptionPane.* to determine message type.
A typical way to use JFileChooser includes checking whether user clicked OK, like in this code:
private void addModelButtonMouseClicked(java.awt.event.MouseEvent evt) {
JFileChooser modelChooser = new JFileChooser();
if(modelChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION ){
File selectedFile = modelChooser.getSelectedFile();
if(verifyModelFile(selectedFile)){
MetModel newModel;
newModel = parser.parse(selectedFile, editedCollection.getDirectory() );
this.editedCollection.addModel(newModel);
this.modelListUpdate();
}
}
}
I tried to mimic this behavior in my own window inheriting JFrame. I thought that this way of handling forms is more convenient than passing collection that is to be edited to the new form. But I have realized that if I want to have a method in my JFrame returning something like exit status of it I need to make it wait for user clicking OK or Cancel without freezing the form/dialog window.
So, how does showOpenDialog() work? When I tried to inspect the implementation, I found only one line methods with note "Compiled code".
I tried to mimic this behavior in my own window inheriting JFrame.
JFrame is not a modal or 'blocking' component. Use a modal JDialog or JOptionPane instead.
E.G.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
/** Typical output:
[JTree, colors, violet]
User cancelled
[JTree, food, bananas]
Press any key to continue . . .
*/
class ConfirmDialog extends JDialog {
public static final int OK_OPTION = 0;
public static final int CANCEL_OPTION = 1;
private int result = -1;
JPanel content;
public ConfirmDialog(Frame parent) {
super(parent,true);
JPanel gui = new JPanel(new BorderLayout(3,3));
gui.setBorder(new EmptyBorder(5,5,5,5));
content = new JPanel(new BorderLayout());
gui.add(content, BorderLayout.CENTER);
JPanel buttons = new JPanel(new FlowLayout(4));
gui.add(buttons, BorderLayout.SOUTH);
JButton ok = new JButton("OK");
buttons.add(ok);
ok.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
result = OK_OPTION;
setVisible(false);
}
});
JButton cancel = new JButton("Cancel");
buttons.add(cancel);
cancel.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
result = CANCEL_OPTION;
setVisible(false);
}
});
setContentPane(gui);
}
public int showConfirmDialog(JComponent child, String title) {
setTitle(title);
content.removeAll();
content.add(child, BorderLayout.CENTER);
pack();
setLocationRelativeTo(getParent());
setVisible(true);
return result;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("Test ConfirmDialog");
final ConfirmDialog dialog = new ConfirmDialog(f);
final JTree tree = new JTree();
tree.setVisibleRowCount(5);
final JScrollPane treeScroll = new JScrollPane(tree);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton b = new JButton("Choose Tree Item");
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
int result = dialog.showConfirmDialog(
treeScroll, "Choose an item");
if (result==ConfirmDialog.OK_OPTION) {
System.out.println(tree.getSelectionPath());
} else {
System.out.println("User cancelled");
}
}
});
JPanel p = new JPanel(new BorderLayout());
p.add(b);
p.setBorder(new EmptyBorder(50,50,50,50));
f.setContentPane(p);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
});
}
}
I guess you wait for the user to click some button by constantly checking what button is pressed.
"I need to make it wait for user clicking OK or Cancel without freezing the form/dialog window."
May be you should use evens to get notified, when the user clicks on something, not waiting for them to press the button - maybe there is some OnWindowExit event?
Or maybe something like this:
MyPanel panel = new MyPanel(...);
int answer = JOptionPane.showConfirmDialog(
parentComponent, panel, title, JOptionPane.YES_NO_CANCEL,
JOptionPane.PLAIN_MESSAGE );
if (answer == JOptionPane.YES_OPTION)
{
// do stuff with the panel
}
Otherwise you might see how to handle window events, especially windowClosing(WindowEvent) here