I want to create a dialog with a checkbox and a combobox. This is what I have:
JCheckBox checkBox = new JCheckBox("My checkbox");
JLabel modeLabel = new JLabel("Select mode:");
String[] modes = {"A", "B", "C"};
JComboBox<String> modesComboBox = new JComboBox<>(modes);
JPanel modePanel = new JPanel(new FlowLayout());
modePanel.add(modeLabel);
modePanel.add(modesComboBox);
JPanel dialogPanel = new JPanel();
dialogPanel.setLayout(new BoxLayout(dialogPanel, BoxLayout.Y_AXIS));
dialogPanel.add(checkBox);
dialogPanel.add(modePanel);
JOptionPane.showMessageDialog(null, dialogPanel);
How do I determine whether the Close (i.e., "X") button or the OK button was clicked? I need to know which one of these two buttons caused the dialog to close.
Use JOptionPane.showConfirmDialog(Component,Object) (or overloaded equivalents) to get an int returned that reports yes, no or cancelled.
Calling showConfirmDialog..
Brings up a dialog with the options Yes, No and Cancel; with the title, Select an Option.
Parameters:
parentComponent - determines the Frame in which the dialog is displayed; if null, or if the parentComponent has no Frame, a default Frame is used
message - the Object to display
Returns:
an integer indicating the option selected by the user
Edit
On closer inspection, it becomes apparent this task needs both a confirmation dialog and an option dialog. Here is a complete example that reports the results of the user choices to the console.
import javax.swing.*;
public class OptionSelection {
public OptionSelection() {
int result;
String[] modes = {"A", "B", "C"};
result = JOptionPane.showOptionDialog(
null,
"Modes",
"Select mode",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
modes,
"B"
);
if (result == JOptionPane.CLOSED_OPTION) {
System.out.println("User canceled mode selection");
} else {
System.out.println("Result: " + modes[result]);
}
result = JOptionPane.showConfirmDialog(null,
"Are you now, or have you ever?",
"Declaration",
JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
System.out.println("User says YES!");
} else if (result == JOptionPane.NO_OPTION) {
System.out.println("User says NO!");
} else {
System.out.println("User canceled");
}
}
public static void main(String[] args) {
Runnable r = () -> new OptionSelection();
SwingUtilities.invokeLater(r);
}
}
Related
I see this has been asked multiple times and apologize in advance if I'm just missing something simple...
I've created a custom JDialog with the examples provided in the Java docs here and from a similar question asked here.
My main application is a JFrame that contains a JPanel with an array of JButtons that display various employee names. I've added a custom ActionListener to each JButton that calls the mentioned JDialog:
//inner class for handling user button pushes
private class UserButtonHandler implements ActionListener
{
//handle button event
#Override
public void actionPerformed(ActionEvent event)
{
statusDialog = new ChangeDialog(statusWindow);
statusDialog.setVisible(true);
statusDialog.setLocationRelativeTo(null);
//set title for dialog box
String dialogTitle = "Status change for " + event.getActionCommand();
statusDialog.setTitle(dialogTitle);
statNum = ((ChangeDialog) statusDialog).getInputStatus();
System.out.println("Current num is: " + statNum);
//statNum = statusDialog.getInputStatus();
}
}
Here is the class for the custom JDialog (ChangeDialog):
class ChangeDialog extends JDialog implements ActionListener, PropertyChangeListener
{
//create panel where users can modify their status
private final ChangePanel empStatusChangePanel;
//text of buttons in dialog
private String btnString1 = "OK";
private String btnString2 = "Cancel";
private String btnString3 = "Clear Time-Off";
private JOptionPane statusPane;
//determines message to return for user input
private int inputStatus;
public ChangeDialog(JFrame statusFrame)
{
empStatusChangePanel = new ChangePanel();
//create an array specifying the number
//of dialog buttons and their text
Object[] options = {btnString1, btnString2, btnString3};
//create the JOptionPane
statusPane = new JOptionPane(empStatusChangePanel,
JOptionPane.PLAIN_MESSAGE,
JOptionPane.YES_NO_CANCEL_OPTION,
null,
options,
options[0]);
//set contents of dialog
setContentPane(statusPane);
//handle window closing
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
//register event handler for changes in status pane state
statusPane.addPropertyChangeListener(this);
pack();
}
#Override
public void actionPerformed(ActionEvent e)
{
statusPane.setValue(btnString1);
}
#Override
public void propertyChange(PropertyChangeEvent e)
{
String prop = e.getPropertyName();
if (isVisible()
&& (e.getSource() == statusPane)
&& (JOptionPane.VALUE_PROPERTY.equals(prop)))
{
Object value = statusPane.getValue();
if (value == JOptionPane.UNINITIALIZED_VALUE)
{
//ignore reset
return;
}
//Reset the JOptionPane's value. If this is not done,
//then if the user presses the same button next time,
//no property change event will be fired
statusPane.setValue(JOptionPane.UNINITIALIZED_VALUE);
if(value.equals(btnString1)) //user clicked "OK"
{
//validation of user input
inputStatus = empStatusChangePanel.validateUserInput();
//handle validation results
switch (inputStatus)
{
case 0: //user input is good
JOptionPane.showMessageDialog(this, "Good input given");
dispose();
break;
case 1: //one (or both) of the date pickers are empty
JOptionPane.showMessageDialog(this, "PTO pickers can't be empty.",
"ERROR", JOptionPane.ERROR_MESSAGE);
break;
case 2:
case 3: //bad date range (start before end or visa-versa)
JOptionPane.showMessageDialog(this, "Bad date range.",
"ERROR", JOptionPane.ERROR_MESSAGE);
break;
case 99: //dates are equal
JOptionPane.showMessageDialog(this, "Single-day PTO");
dispose();
break;
}
}
else if(value.equals(btnString3)) //user clicked "Clear Input"
{
JOptionPane.showMessageDialog(this, "User clicked 'clear input");
//more processing should be done here
empStatusChangePanel.recycle();
//dispose();
}
else //user clicked "Cancel" or closed dialog
{
JOptionPane.showMessageDialog(this, "User closed status window");
dispose();
}
}
}
//returns value from user validation
public int getInputStatus()
{
return inputStatus;
}
}
I need to access the method getInputStatus from the custom dialog but each attempt I've tried comes back stating that:
getInputStatus is undefined for the type JDialog
I have looked at several other similar posts but feel that I'm missing something fundamental in trying to solve this problem (or I've been looking at the code too long).
Another thing that has me stumped (and why I left it in the first snippet) is that if I cast the method to the type ChangeDialog
statNum = ((ChangeDialog) statusDialog).getInputStatus();
It suddenly has access (this was a suggestion from Eclipse and doesn't make sense to me). Thanks again for any and all help.
That is how inheritance works, you have defined statusDialog as a JDialog reference and JDialog doesn't have a getInputStatus method.
To access the members of ChangeDialog, you have to define statusDialog as variable of ChangeDialog.
I am making a method that gives the user three choices and returns the one they click, right now the method kinda works I click one of the options and if I click the close button it returns the last clicked. I want to to make it so that the dialog closes when you click one of the options
public E drawThreeForDecision()
{
ArrayList<E> c = new ArrayList<E>();
Component[] options = new Component[3];
for (int iii = 0; iii < 3; iii++)
{
final int loop = iii;
c.add((E) drawCard());
JButton button = new JButton(new ImageIcon(((GameEntity) c.get(iii)).getEntityImage()));
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent arg0)
{
}
});
options[iii] = button;
}
JOptionPane pane = new JOptionPane("Please select a card", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION, null, options, options[0]);
JDialog dialog = pane.createDialog(null, "DECISION TIME!");
dialog.setVisible(true);;
if (pane.getValue() instanceof Integer)
return (E) pane.getValue();
return c.get(0);
}
If anyone can help me with this or suggest a better solution it would be greatly appreciated!
Try these:
dialog.setModal(true);
dialog.setVisible(true);
use dialog.dispose(); inside the actionPerformed() method.
I am using a JOptionPane and I want it to automatically close after a user has selected an option.
At present this is working but I still have to manually click the OK button to close the JOptionPane. Is there anyway I can close it when the checkbox is ticked
JPanel a1 = new JPanel();
a1.add(bubbleCheckBox);
a1.add(quickCheckBox);
a1.add(insertionCheckBox);
a1.add(selectionCheckBox);
// a1.add(mergeCheckBox);
arraySize=Integer.parseInt(JOptionPane.showInputDialog(null,"Enter number of elements would like to sort (Recommend max =30)"));
JOptionPane.showMessageDialog(null, a1, "Choose an algorithm to run", DEFAULT_OPTION);
}
public static void lockCheckboxes(JCheckBox a) throws IOException, InterruptedException {
if (a == insertionCheckBox) {
selectionCheckBox.setEnabled(false);
quickCheckBox.setEnabled(false);
bubbleCheckBox.setEnabled(false);
mergeCheckBox.setEnabled(false);
SortAnimator.setArraySize(arraySize);
SortAnimator animator = new SortAnimator(new InsertionSorter());
This is slightly complicated.
First, add an ActionListener to your JCheckBox's...
When this ActionListener is triggered, you need to find the window which contains the JCheckBox, you need to find the instance of the JOptionPane, call setValue and pass it JOptionPane.OK_OPTION then dispose of the dialog
Something like...
JPanel a1 = new JPanel();
JCheckBox bubbleCheckBox = new JCheckBox("Bubbble");
JCheckBox quickCheckBox = new JCheckBox("Quick");
JCheckBox insertionCheckBox = new JCheckBox("Insert");
JCheckBox selectionCheckBox = new JCheckBox("Select");
ActionListener al = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JCheckBox cb = (JCheckBox) e.getSource();
JOptionPane op = (JOptionPane) SwingUtilities.getAncestorOfClass(JOptionPane.class, cb);
if (op != null) {
op.setValue(JOptionPane.OK_OPTION);
}
SwingUtilities.getWindowAncestor(cb).dispose();
}
};
bubbleCheckBox.addActionListener(al);
quickCheckBox.addActionListener(al);
insertionCheckBox.addActionListener(al);
selectionCheckBox.addActionListener(al);
a1.add(bubbleCheckBox);
a1.add(quickCheckBox);
a1.add(insertionCheckBox);
a1.add(selectionCheckBox);
// a1.add(mergeCheckBox);
if (JOptionPane.showConfirmDialog(null, a1, "Choose an algorithm to run", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION) {
System.out.println("Yeah for me");
}
Personally, I'd use a JComboBox and just make the user select OK or Cancel
I was wondering how inputdialog returns value especially when there are also ok and cancel buttons.
Could somebody explain how does it manage to return value?
UPDATE:
Let me put it this way.
I want to create a dialog with 6 buttons and each button returns different value.
And i want it get that value like this:
String value = MyDialog.getValue(); // like showInputDialog
the problem is how do i return value on button press?
Now that I have a clearer understanding of your goal, I think instead of trying to emulate JOptionPane, it would be easier to just give each button a different actionCommand:
private JDialog dialog;
private String inputValue;
String showPromptDialog(Frame parent) {
dialog = new JDialog(parent, true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
// [add components to dialog here]
firstButton.setAction(new ButtonAction("Button 1", "first"));
secondButton.setAction(new ButtonAction("Button 2", "second"));
thirdButton.setAction(new ButtonAction("Button 3", "third"));
fourthButton.setAction(new ButtonAction("Button 4", "fourth"));
fifthButton.setAction(new ButtonAction("Button 5", "fifth"));
sixthButton.setAction(new ButtonAction("Button 6", "sixth"));
dialog.pack();
dialog.setLocationRelativeTo(parent);
inputValue = null;
dialog.setVisible(true);
return inputValue;
}
private class ButtonAction
extends AbstractAction {
private static final long serialVersionUID = 1;
ButtonAction(String text,
String actionCommand) {
super(text);
putValue(ACTION_COMMAND_KEY, actionCommand);
}
public void actionPerformed(ActionEvent event) {
inputValue = event.getActionCommand();
dialog.dispose();
}
}
From the Java tutorials
Object[] possibilities = {"ham", "spam", "yam"};
String s = (String)JOptionPane.showInputDialog(
frame,
"Complete the sentence:\n"
+ "\"Green eggs and...\"",
"Customized Dialog",
JOptionPane.PLAIN_MESSAGE,
icon,
possibilities,
"ham");
//If a string was returned, say so.
if ((s != null) && (s.length() > 0)) {
setLabel("Green eggs and... " + s + "!");
return;
}
You might like to familiarise yourself with the section on "Getting the User's Input from a Dialog"
You should also familiarise yourself with the Java Docs on the same subject
Also, right now whenever I click the 'X" button on top right, the dialog boxes behaves as if I clicked OK (on messages) or YES (on questions). When the user clicks the X, I want DO_Nothing.
In the code below, when i click on the X on the dialog box, it pops out the 'eat!'. Apparently, the X is acting as 'YES' Option, which it should not.
int c =JOptionPane.showConfirmDialog(null, "Are you hungry?", "1", JOptionPane.YES_NO_OPTION);
if(c==JOptionPane.YES_OPTION){
JOptionPane.showMessageDialog(null, "eat!", "Order",JOptionPane.PLAIN_MESSAGE);
}
else {JOptionPane.showMessageDialog(null, "ok cool", "Order",JOptionPane.PLAIN_MESSAGE);}
Changed to show how to ignore the cancel button on Dialog box per OP clarification of question:
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();
dialog.setVisible(true);
int c = ((Integer)pane.getValue()).intValue();
if(c == JOptionPane.YES_OPTION) {
JOptionPane.showMessageDialog(null, "eat!", "Order",JOptionPane.PLAIN_MESSAGE);
}
else if (c == JOptionPane.NO_OPTION) {
JOptionPane.showMessageDialog(null, "ok cool", "Order",JOptionPane.PLAIN_MESSAGE);
}
You can't do what you want through the usual JOptionPane.show* methods.
You have to do something like this:
public static int showConfirmDialog(Component parentComponent,
Object message, String title, int optionType)
{
JOptionPane pane = new JOptionPane(message, JOptionPane.QUESTION_MESSAGE,
optionType);
final JDialog dialog = pane.createDialog(parentComponent, title);
dialog.setVisible(false) ;
dialog.setLocationRelativeTo(parentComponent);
dialog.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
dialog.setModal(true);
dialog.setVisible(true) ;
dialog.dispose();
Object o = pane.getValue();
if (o instanceof Integer) {
return (Integer)o;
}
return JOptionPane.CLOSED_OPTION;
}
The line that actually disables the close button is:
dialog.setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);