Execute SQL Statements while JDialog visible? - java

I am saving A JTable to my SQL Database. No problems with that. However, I wanted to make some kind of dialog that stays on the screen while data from the database is being loaded. I used a JDialog with a JOptionPane:
final JOptionPane pane = new JOptionPane("Loading", JOptionPane.INFORMATION_MESSAGE,
JOptionPane.DEFAULT_OPTION, null, new Object[] {}, null);
final JDialog dialog = new JDialog();
dialog.setTitle("Loading");
dialog.setModal(true);
dialog.setContentPane(pane);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
Now, I want the dialog to close as soon as my SQL Statement is executed, however as it seems the dialog keeps the Statement from being executed, as the thread is blocked by it apparently. So, how do I execute my SQL statements while the Dialog is showing and then closes itself after the statement is executed?

I guess you can add a propertchange listener to your code.
Found a similar question: [Java Swing - Close JDialog from external Thread1
Answer in that post is as follows:
Stopping Automatic Dialog Closing
By default, when the user clicks a JOptionPane-created button, the
dialog closes. But what if you want to check the user's answer before
closing the dialog? In this case, you must implement your own property
change listener so that when the user clicks a button, the dialog does
not automatically close.
DialogDemo contains two dialogs that implement a property change
listener. One of these dialogs is a custom modal dialog, implemented
in CustomDialog, that uses JOptionPane both to get the standard icon
and to get layout assistance. The other dialog, whose code is below,
uses a standard Yes/No JOptionPane. Though this dialog is rather
useless as written, its code is simple enough that you can use it as a
template for more complex dialogs.
Besides setting the property change listener, the following code also
calls the JDialog's setDefaultCloseOperation method and implements a
window listener that handles the window close attempt properly. If you
do not care to be notified when the user closes the window explicitly,
then ignore the bold code.
final JOptionPane optionPane = new JOptionPane(
"The only way to close this dialog is by\n"
+ "pressing one of the following buttons.\n"
+ "Do you understand?",
JOptionPane.QUESTION_MESSAGE,
JOptionPane.YES_NO_OPTION);
final JDialog dialog = new JDialog(frame,
"Click a button",
true);
dialog.setContentPane(optionPane);
dialog.setDefaultCloseOperation(
JDialog.DO_NOTHING_ON_CLOSE);
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
setLabel("Thwarted user attempt to close window.");
}
});
optionPane.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (dialog.isVisible()
&& (e.getSource() == optionPane)
&& (prop.equals(JOptionPane.VALUE_PROPERTY))) {
//If you were going to check something
//before closing the window, you'd do
//it here.
dialog.setVisible(false);
}
}
});
dialog.pack();
dialog.setVisible(true);
int value = ((Integer)optionPane.getValue()).intValue();
if (value == JOptionPane.YES_OPTION) {
setLabel("Good.");
} else if (value == JOptionPane.NO_OPTION) {
setLabel("Try using the window decorations "
+ "to close the non-auto-closing dialog. "
+ "You can't!");
}

Related

What is the equivalent of the DialogResult property from WindowsForms in Java SWING's JFrames?

I'm writing an application in Java using the Java Swing library and am looking for a functionality equivalent to these lines of code from C# using WindowsForms:
MyDialog form = new MyDialog();
form.showDialog();
if (form.DialogResult == DialogResult.OK)
doSomething();
I haven't been able to find an equivalent functionality for JFrames in Java.
The code I'm working on is the following:
LoginFrame loginFrame = new LoginFrame(CONTROLLER);
loginFrame.setVisible(true);
The previous 2 lines of code launch a log-in window where the user can input his e-mail and password. Said window displays 2 buttons: OK and CANCEL. After the window has closed, I'm interested in knowing which one of the 2 buttons the user has pressed.
What is the standard way of doing this in Java Swing with JFrames?
You can set ActionListener to your buttons. There's many ways.
Anonymous Action Listener
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent actionEvent) {
if(e.getSource() == button1) {
//if clicks the first button
} else if (e.getSource() == button2) {
//if clicks the second button
}
}
});
Class that implements Action Listener (best option for maintenance issues)
class CheckButtonActionListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent actionEvent) {
if(e.getSource() == button1) {
//if clicks the first button
} else if (e.getSource() == button2) {
//if clicks the second button
}
}
}
and, set the class to your JButton:
CheckButtonActionListener checker = new CheckButtonActionListener();
button.addActionListener(checker);
or:
button1.addActionListener(new CheckButtonActionListener();
An application will have a single JFrame as the main window.
If you need child window you would use a JDialog. A JDialog is like a JFrame. You need to code all the logic and handle all the button events yourself
A JOptionPane is a pre-packaged JDialog that give you some default functionality.
You can create a simple JOptionPane with multiple input fields with code something like:
JTextField firstName = new JTextField(10);
//firstName.addAncestorListener( new RequestFocusListener() );
JTextField lastName = new JTextField(10);
Object[] msg = {"First Name:", firstName, "Last Name:", lastName};
int result = JOptionPane.showConfirmDialog(
frame,
msg,
"Enter Name",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.YES_OPTION)
{
System.out.println(firstName.getText() + " : " + lastName.getText());
}
else
{
System.out.println("Canceled");
}
One problem with the above is that focus will be on the buttons, not the text field. You can fix this problem by using the Request Focus Listener
If you don't like the layout of the components in the option pane then you will need to create a custom panel with your components and add the panel to the OptionPane.
You should also check out the section from the Swing tutorial on Making Dialogs. This section and the tutorial is general will give you Swing basics as your transition from C#.

How can I make a text field lose focus before application quits?

I have an application with a JFrame containing text fields. When text in a field is modified, and the field gets a focusLost event, it immediately writes its contents to an external database.
However, if the user quits the application while a field is still focused, the focusLost message is not sent and the modified data is not saved.
How can I force the loss of focus on a field, perhaps in a windowClosing method in my WindowListener? I tried using requestFocusInWindow() in that method, but it did not help.
Why not just call the same method that writes the contents to the external database from within the windowClosing method of your window listener?
#Override
public void windowClosing(WindowEvent e) {
// call write to DB method
System.exit(0);
}
Another way of going about it:
Change the setDefaultCloseOperation of the JFrame to DO_NOTHING_ON_CLOSE, and show a confirmation dialog when the user wants to close the window. The dialog will receive focus, triggering the focusLost method on the textfield's FocusListener.
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int result = JOptionPane
.showConfirmDialog(null, "Are you sure?",
"Confirm exit", JOptionPane.YES_NO_OPTION);
if(result == 0) {
System.exit(0);
}
}
}
});
(Note: If you go with this method, be sure you don't exit in the middle of writing to the DB.)
Pending a better answer that may be forthcoming from someone more experienced that I am, here's what I'm doing.
In my windowClosing() method in my WindowListener, I put:
dispatchEvent(new FocusEvent(getFocusOwner(), FocusEvent.FOCUS_LOST));

Pressing Yes/No on embedded JOptionPane has no effect

I'm trying to add an exit confirmation check to JFrame but I want the dialog to be undecorated. I've figured I need to use custom JDialog and custom JOptionPane.
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
JDialog dialog = new JDialog();
dialog.setUndecorated(true);
JOptionPane pane = new JOptionPane("Are you sure that you want to exit?",
JOptionPane.QUESTION_MESSAGE,JOptionPane.YES_NO_OPTION);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); //I don't even know if this line does anything
dialog.setContentPane(pane);
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
System.out.println("Next Line"); //this line does not work.
}
});
The dialog appears exactly as I wanted but clicking yes or no does nothing. Dialog does not disappear and I couldn't find a way to check which button is clicked. "Next Line" is never printed to console .
Embedding JOptionPane on its own isn't enough. You need to register a callback for the Yes and No button presses and handle them appropriately. This can be done by overriding the setValue() method
JOptionPane pane = new JOptionPane(
"Are you sure that you want to exit?",
JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION) {
#Override
public void setValue(Object newValue) {
if (newValue == Integer.valueOf(JOptionPane.YES_OPTION)) {
System.out.println("yes");
} else if ( newValue == Integer.valueOf(JOptionPane.NO_OPTION)) {
System.out.println("no");
}
}
};
Read the section from the Swing tutorial on How to Make Dialogs for working examples of using a JOptionPane.
If you really want to add a JOptionPane to your own JDialog, then read the JOptionPane API for a basic example of how to check which button was selected.

Prevent Window close if it forced via Windows taskbar -> Close

How can I detect the java window closing if it was forced by clicking on windows taskbar -> close window?
I've found that the window to close receives the WINDOW_CLOSING event which is possible to process by adding windowListener. But in this case window would being closed anyway. Is there any way to prevent the window closing?
You can set the default close operation to DO_NOTHING_ON_CLOSE and ask the user for a confirmation instead. It's a pretty common practice even if you want to close the frame through the X button, key combination (i.e.: ALT + F4) or any method to close a window:
JFrame frame = new JFrame("Welcome!");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int option = JOptionPane.showConfirmDialog(null, "Do you really want to exit?");
if (option == JOptionPane.OK_OPTION) {
e.getWindow().dispose();
}
}
});
To prevent window closing you should call
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)
on your JFrame instance and then implement your alternative closing procedure via windowListener.

How to disable X on dialog boxes?

Is there a way to disable all X on dialog boxes?
I can accomplish this on one by doing:
JOptionPane pane = new JOptionPane("Are you hungry?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
JDialog dialog = pane.createDialog("Title");
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
} });
dialog.setContentPane(pane);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.pack();
But the problem is thst I have to apply this to other 20-40 dialog boxes which will be time consuming..
So I was wondering just how you can do one line of code to make the fonts bigger on all the Dialog boxes (shown below), is there a way to for the X disable feature.
UIManager.put("OptionPane.messageFont",
new FontUIResource(new
Font("ARIAL",Font.BOLD,30)));
JDialog method setDefaultCloseOperation works just like JFrame's:
http://download.oracle.com/javase/6/docs/api/javax/swing/JDialog.html#setDefaultCloseOperation(int)
Neither will do this for all frames, it will just do it for the instance it is set on. If you want to apply to all your dialogs you need to do one of the following:
Call this every time you construct a dialog.
Extend JDialog and have it set the default for you, then use that new class.
Create a factory method that will construct a dialog with this default set. Then call this method whenever you need a new dialog.
You need to add a windowListener but also set the default close operation for the dialog.
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
if (someConditionIsMet) {
dispose();
}
}
});
Rather than disable a control, you should remove it. Users shouldn't see an "X" button and then have it not behave like they expect.
See:
Dialog.setUndecorated() for a single dialog
JDialog.setDefaultLookAndFeelDecorated() to provide a hint for future dialogs
Why not just create a custom class that extends the JDialog setting your desired close behavior in the constructor?
class NoCLoseDialog extends JDialog {
NoCloseDialog(){
addWindowListener(new WindowAdaptor(){
// ... Close behavior ...
});
}
}
Crtl+F Replace JDialog with NoCloseDialog ...

Categories