JOptionPane.showMessageDialog wait until OK is clicked? - java

This might be a very simple thing that I'm overlooking, but I just can't seem to figure it out.
I have the following method that updates a JTable:
class TableModel extends AbstractTableModel {
public void updateTable() {
try {
// update table here
...
} catch (NullPointerException npe) {
isOpenDialog = true;
JOptionPane.showMessageDialog(null, "No active shares found on this IP!");
isOpenDialog = false;
}
}
}
However, I don't want isOpenDialog boolean to be set to false until the OK button on the message dialog is pressed, because if a user presses enter it will activate a KeyListener event on a textfield and it triggers that entire block of code again if it's set to false.
Part of the KeyListener code is shown below:
public class KeyReleased implements KeyListener {
...
#Override
public void keyReleased(KeyEvent ke) {
if(txtIPField.getText().matches(IPADDRESS_PATTERN)) {
validIP = true;
} else {
validIP = false;
}
if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
if (validIP && !isOpenDialog) {
updateTable();
}
}
}
}
Does JOptionPane.showMessageDialog() have some sort of mechanism that prevents executing the next line until the OK button is pressed? Thank you.

The JOptionPane creates a modal dialog and so the line beyond it will by design not be called until the dialog has been dealt with (either one of the buttons have been pushed or the close menu button has been pressed).
More important, you shouldn't be using a KeyListener for this sort of thing. If you want to have a JTextField listen for press of the enter key, add an ActionListener to it.

An easy work around to suite your needs is the use of showConfirmDialog(...), over showMessageDialog(), this lets you take the input from the user and then proceed likewise. Do have a look at this example program, for clarification :-)
import javax.swing.*;
public class JOptionExample
{
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
int selection = JOptionPane.showConfirmDialog(
null
, "No active shares found on this IP!"
, "Selection : "
, JOptionPane.OK_CANCEL_OPTION
, JOptionPane.INFORMATION_MESSAGE);
System.out.println("I be written" +
" after you close, the JOptionPane");
if (selection == JOptionPane.OK_OPTION)
{
// Code to use when OK is PRESSED.
System.out.println("Selected Option is OK : " + selection);
}
else if (selection == JOptionPane.CANCEL_OPTION)
{
// Code to use when CANCEL is PRESSED.
System.out.println("Selected Option Is CANCEL : " + selection);
}
}
});
}
}

You can get acces to the OK button if you create optionpanel and custom dialog. Here's an example of this kind of implementation:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author OZBORN
*/
public class TestyDialog {
static JFrame okno;
static JPanel panel;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
zrobOkno();
JButton przycisk =new JButton("Dialog");
przycisk.setSize(200,200);
panel.add(przycisk,BorderLayout.CENTER);
panel.setCursor(null);
BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
przycisk.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
cursorImg, new Point(0, 0), "blank cursor"));
final JOptionPane optionPane = new JOptionPane(
"U can close this dialog\n"
+ "by pressing ok button, close frame button or by clicking outside of the dialog box.\n"
+"Every time there will be action defined in the windowLostFocus function"
+ "Do you understand?",
JOptionPane.INFORMATION_MESSAGE,
JOptionPane.DEFAULT_OPTION);
System.out.println(optionPane.getComponentCount());
przycisk.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
final JFrame aa=new JFrame();
final JDialog dialog = new JDialog(aa,"Click a button",false);
((JButton)((JPanel)optionPane.getComponents()[1]).getComponent(0)).addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
aa.dispose();
}
});
dialog.setContentPane(optionPane);
dialog.pack();
dialog.addWindowFocusListener(new WindowFocusListener() {
#Override
public void windowLostFocus(WindowEvent e) {
System.out.println("Zamykam");
aa.dispose();
}
#Override public void windowGainedFocus(WindowEvent e) {}
});
dialog.setVisible(true);
}
});
}
public static void zrobOkno(){
okno=new JFrame("Testy okno");
okno.setLocationRelativeTo(null);
okno.setSize(200,200);
okno.setPreferredSize(new Dimension(200,200));
okno.setVisible(true);
okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel=new JPanel();
panel.setPreferredSize(new Dimension(200,200));
panel.setLayout(new BorderLayout());
okno.add(panel);
}
}

Try this,
catch(NullPointerException ex){
Thread t = new Thread(new Runnable(){
public void run(){
isOpenDialog = true;
JOptionPane.setMessageDialog(Title,Content);
}
});
t.start();
t.join(); // Join will make the thread wait for t to finish its run method, before
executing the below lines
isOpenDialog = false;
}

Related

Adding a 3rd button to JOptionPane drop down menu

I am relatively new to Java and have been trying to figure out a way to create a JOption window that not only has a drop down option with an "Ok" and "Cancel" button, but also adds an additional button called "Back." So far none of my attempts have successfully been able to add this Back button and every time I run the code it simply brings up the traditional dropdown/ok/cancel type window. Additionally I would also like the window to close when a button has been clicked, but I have been unsuccessful in that as well. Here is the code I have so far, not entirely sure what's missing/wrong with it:
public static String sampleWindow(){
JButton jbt_ok = new JButton("OK");
JButton jbt_back = new JButton("Back");
JButton jbt_cancel = new JButton("Cancel");
boolean greyOutBackButton = false;
jbt_ok.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("OK was clicked");
}
});
jbt_cancel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Cancel was clicked");
}
});
if(greyOutBackButton)
jbt_back.setEnabled(false);
else
jbt_back.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Back was clicked");
}
});
Object[] options = {jbt_ok, jbt_back, jbt_cancel};
Object selectionObject = JOptionPane.showInputDialog(null, "message", "", JOptionPane.DEFAULT_OPTION, null, options, options[0]);
if (selectionObject == null)
System.exit(0);
String selectionString = selectionObject.toString();
System.out.println("Selection String: "+ selectionString);
return selectionString;
}

Make a conditional in a JDialog

I'm trying to put a conditional in a JDialog which detect if the two buttons in it are disabled. I need that also to close the dialog when it reach this condition so I found 2 problems. Example code:
public static String windowvisitAlert(JButton but, JButton but2, String message1, String message2) throws Exception, Exception {
String n = "";
Object[] options = {but, but2};
Object a = message1;
JOptionPane pane = new JOptionPane(a, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION, null, options, options[0]);
JDialog dialog = pane.createDialog(message2);
dialog.setContentPane(pane);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setSize(new Dimension(450, 10));
dialog.pack();
dialog.setVisible(true);
return n;
}
This is the method which creates a JDialog from a JPanel options. We have 2 buttons and 2 "messages" which only determinates the name of the dialog window.
I tried to put :
if (but.isEnabled()==false && but2.isEnabled()==false) {
dialog.setVisible(false);
}else{
dialog.setVisible(true);}
Also this method will return the value n so I don't know how will a condition work inside it.
Where i implement this method:
public void actionPerformed(ActionEvent e) {
final JButton but = new JButton("VISITA");
final JButton but2 = new JButton("RESPONSABLE");
try {
ActionListener actionListener2 = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
//action performed
}
};
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
//action performed
}
};
but.addActionListener(actionListener2);
but2.addActionListener(actionListener);
Alerts.windowvisitAlert(but, but2, Gui.getProperties().getProperty("text"), Gui.getProperties().getProperty("text"));
}catch (Exception ex) {
sc.functionSavingInLog(Utils.getClassInfo(Thread.currentThread().getStackTrace()[1]), ex.toString());
System.out.println(Utils.getClassInfo(Thread.currentThread().getStackTrace()[1]) + ex);
}
}
This is actually not working so my question is:
-How can I make this condition work and make the JDialog close when it hits it?
If not, how can I change the method or just do a jpanel?

How to check if a JFrame is open by checking it's one of the components are visible

I have this code sample in a separate jDialog (jDialog is in the same package as that of JFrame) which used to check (using a Thread) if the jCheckBox1 in the jFrame is whether visible or not. JDialog is set to visible by clicking a JLabel (Change Password) in JFrame. I have not set the visibility of the JFrame even to false even after I click on the Change Password JLabel.
The problem I encountered is that even if the JFrame is not visible i.e when I run the JDialog separately (without clicking on the Change Password JLabel) it prints the "Visible" and I'm more than sure that the jFrame is not visible and not running.
This is the code snippet (Thread) I have used to check the visibility of the JFrame's jCheckBox1:
LockOptions lock = new LockOptions();
private void setLocation2() {
new Thread() {
public void run() {
boolean running = true;
while (running) {
try {
Thread.sleep(1000);
if (lock.jCheckBox1.isVisible()) {
System.out.println("Visible");
} else {
System.out.println("Not Visible");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
And this is the Code I have written in JFrame's Change Password JLabel:
private void jLabel9MouseClicked(java.awt.event.MouseEvent evt) {
Container c = new ChangePassword(this, rootPaneCheckingEnabled);
if (!c.isShowing()) {
c.setVisible(true);
hideMeToSystemTray();
this.requestFocusInWindow();
}
}
But when I run the JDialog separately (without clicking on the Change Password JLabel) it prints the "Visible"
I have attached a Screenshots of both JFrame and JDialog
JFrame containing jCheckBox1
JDialog:
OK, let's have the simplest possible example.
The following code creates a main frame having a button to create a new frame of class LockOptionsWindow, which extends JFrame.
The class FrameDemo implements Runnable. So can it be accessed on the event dispatching thread using SwingUtilities.invokeLater as mentioned in Swing's Threading Policy. So it is possible creating a new thread checklockoptionswindow which then can check whether the new window created by the button is visible or not visible.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FrameDemo extends WindowAdapter implements ActionListener, Runnable {
private LockOptionsWindow lockoptionswindow;
private Thread checklockoptionswindow = new Thread();
private void showLockOptionsWindow() {
if (lockoptionswindow != null && lockoptionswindow.isDisplayable()) {
lockoptionswindow.setVisible(true);
lockoptionswindow.setExtendedState(Frame.NORMAL);
} else {
lockoptionswindow = new LockOptionsWindow();
lockoptionswindow.setSize(new Dimension(300, 100));
lockoptionswindow.setVisible(true);
lockoptionswindow.setExtendedState(Frame.NORMAL);
}
}
private void startCheckLockOptionsWindow() {
if (!checklockoptionswindow.isAlive()) {
checklockoptionswindow = new Thread() {
public void run() {
boolean running = true;
while (running) {
try {
Thread.sleep(1000);
if (lockoptionswindow.isVisible()) {
if (lockoptionswindow.getExtendedState() == Frame.ICONIFIED) {
System.out.println("Visible iconified");
} else {
System.out.print("Visible on screen ");
int x = lockoptionswindow.getLocation().x;
int y = lockoptionswindow.getLocation().y;
System.out.println("at position " + x + ", " + y);
}
} else {
System.out.println("Not Visible");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
checklockoptionswindow.start();
}
}
public void actionPerformed(ActionEvent e) {
showLockOptionsWindow();
startCheckLockOptionsWindow();
}
public void run() {
JFrame frame = new JFrame("FrameDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Show LockOptions frame");
button.addActionListener(this);
Container contentPane = frame.getContentPane();
contentPane.add(button);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new FrameDemo());
}
class LockOptionsWindow extends JFrame {
public LockOptionsWindow() {
super("LockOptions frame");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
}
}
Edited to determine whether the LockOptionsWindow is visible iconified only or is really showed as window on the screen.

Extension of JDialog (hidden?) not showing up in front of parent JFrame?

I have an application I'm making for a game to automatically update a game client.
Once you press Launch, it will open up my DownloadFrame (extends JDialog), and will look like this:
If you click the icon for the application in the taskbar, (maybe Windows 8 is the problem?) it will minimize the application like usual. However when you go to maximise the application again, the JDialog will be hidden, I'm assuming, behind the parent. It looks like this:
Here's my code for my extension of JDialog. Apologies in advance for it being messy.
public class DownloadFrame extends JDialog implements Runnable {
private static final long serialVersionUID = -8764984599528942303L;
private Background frame;
private ImageIcon[] gifs;
private JLabel spinner;
public DownloadFrame() {
super(Loader.application, false);
setLayout(null);
setUndecorated(true);
setAutoRequestFocus(true);
new Thread(this).start();
generateBackground();
generateButton();
generateGif();
}
private void generateBackground() {
frame = new Background("sub_background.png");
setSize(frame.getWidth(), frame.getHeight());
setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
setLocationRelativeTo(null);
setLocation(this.getX(), this.getY() + 5);
setLayout(null);
setContentPane(frame);
}
private void generateGif() {
gifs = Utils.generateGifImages();
spinner = new JLabel(gifs[0]);
spinner.setBounds(70, 30, gifs[0].getIconWidth(), gifs[0].getIconHeight());
add(spinner);
}
private HoverableButton cancel;
public HoverableButton getCancelButton() {
return cancel;
}
private void generateButton() {
cancel = new HoverableButton(Settings.CANCEL_BUTTON, 75, 145);
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
/*
* TODO -
* stop the download in progress
*/
for (HoverableButton button : Loader.application.getPrimaryButtons()) {
button.setActive(true);
button.setVisible(true);
}
dispose();
}
});
add(cancel);
}
private int cycleCount;
private void cycleGif() {
if (spinner == null) {
return;
}
cycleCount++;
if (cycleCount > 7) {
cycleCount = 0;
}
spinner.setIcon(gifs[cycleCount]);
}
#Override
public void run() {
while (true) {
cycleGif();
try {
Thread.sleep(100L);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
In case it's needed, here's my usage of it. Most of the stuff can be ignored I'm sure, it's simply there to hide the four buttons while the download is in progress.
((HoverableButton) components[2]).addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
HoverableButton source = (HoverableButton) components[2];
if (source.isActive()) {
try {
Thread.sleep(500L);
} catch (Exception ex) {
ex.printStackTrace();
}
if (panel == null) {
panel = new DownloadFrame();
panel.setVisible(true);
} else {
panel.setVisible(true);
panel.getCancelButton().removeHighlight();
}
for (HoverableButton button : getPrimaryButtons()) {
button.setActive(false);
button.setVisible(false);
button.removeHighlight();
}
/*
* TODO -
* handle checking for updates / downloading updates
*/
}
}
});
However when you go to maximise the application again, the JDialog will be hidden, I'm assuming, behind the parent
Yes. When you create the JDialog, you need to specify the "owner" JFrame of the dialog in the constructor.
So you must create and make the JFrame and make the frame visible before you create the dialog.

Disable ok button on JOptionPane.dialog until user gives an input

I need the user to input a name and I want to disable the ok button until some input is given. How can I disable it... ?
JOptionPane allows you to supply a component as the message pane and the controls/options that can be displayed on it.
If you add the correct listeners to the message component, then you should be able to influence the controls that are used as options.
Take a look at JOptionPane.showOptionDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue)
Updated
For example...
public class TestOptionPane05 {
public static void main(String[] args) {
new TestOptionPane05();
}
protected JOptionPane getOptionPane(JComponent parent) {
JOptionPane pane = null;
if (!(parent instanceof JOptionPane)) {
pane = getOptionPane((JComponent)parent.getParent());
} else {
pane = (JOptionPane) parent;
}
return pane;
}
public TestOptionPane05() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JButton okay = new JButton("Ok");
okay.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane pane = getOptionPane((JComponent)e.getSource());
pane.setValue(okay);
}
});
okay.setEnabled(false);
final JButton cancel = new JButton("Cancel");
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane pane = getOptionPane((JComponent)e.getSource());
pane.setValue(cancel);
}
});
final JTextField field = new JTextField();
field.getDocument().addDocumentListener(new DocumentListener() {
protected void update() {
okay.setEnabled(field.getText().length() > 0);
}
#Override
public void insertUpdate(DocumentEvent e) {
update();
}
#Override
public void removeUpdate(DocumentEvent e) {
update();
}
#Override
public void changedUpdate(DocumentEvent e) {
update();
}
});
JOptionPane.showOptionDialog(
null,
field,
"Get",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
new Object[]{okay, cancel},
okay);
}
});
}
}
As far as I know this is impossible without overriding JOptionPane.
Try searching for swinglabs or jGoodies libraries for Java. They have built in type for the thing you need.
I need the user to input a name and I want to disable the ok button until some input is given.
wrong way to do it.
i.e. define 'what is a name' = can be anything.
so, what you're, in effect, trying to do is not accept an empty string,
and you do that as an error-check 'after' the OK button has been pressed.
if empty - pop-up error message/repeat input request/confirm cancel/whatever you want to do

Categories