So I have a program that launches an input dialog when I click a button. What I need help on is that once I gather the information from the input dialog and they are gone, I press the Enter key and the input dialogs re-appear. Why?
Also, How can I have it so that if the input dialog is left empty, it comes out as an error and then repeats until it is not empty?
public static String fn;
public static String sn;
public void actionPerformed (ActionEvent e){
fn = JOptionPane.showInputDialog("What is your first name?");
sn = JOptionPane.showInputDialog("What is your second name");
//JOptionPane.showMessageDialog(null, "Welcome " + fn + " " + sn + ".", "", JOptionPane.INFORMATION_MESSAGE);
text.setText("Welcome " + fn + " " + sn + ".");
b.setVisible(false);
text.setVisible(true);
text.setBounds(140,0,220,20);
text.setHorizontalAlignment(JLabel.CENTER);
text.setEditable(false);
text.setBackground(Color.YELLOW);
writeToFile();
}
public BingoHelper(){
super("BINGO");
add(text);
text.setVisible(false);
add(b);
this.add(pnlButton);
pnlButton.setBackground(Color.BLUE);
//pnlButton.add(b);+
b.setVisible(true);
b.setBounds(145,145,145,20);
//b.setPreferredSize(new Dimension(150,40));
b.addActionListener(this);
b.setBackground(Color.GREEN);
rootPane.setDefaultButton(b);
}
When you call rootPane.setDefaultButton you are specifying the button which is activated by the Enter key.
To prevent a JOptionPane from closing when the input is not acceptable, create an actual JOptionPane instance, then create your own button and specify it as an option. The button's Action or ActionListener must call the JOptionPane's setValue method:
final JOptionPane optionPane = new JOptionPane("What is your first name?",
JOptionPane.QUESTION_MESSAGE);
optionPane.setWantsInput(true);
Action accept = new AbstractAction("OK") {
private static final long serialVersionUID = 1;
public void actionPerformed(ActionEvent event) {
Object value = optionPane.getInputValue();
if (value != null && !value.toString().isEmpty()) {
// This dismisses the JOptionPane dialog.
optionPane.setValue(JOptionPane.OK_OPTION);
}
}
};
Object acceptButton = new JButton(accept);
optionPane.setOptions(new Object[] { acceptButton, "Cancel" });
optionPane.setInitialValue(acceptButton);
// Waits until dialog is dismissed.
optionPane.createDialog(null, "First Name").setVisible(true);
if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(optionPane.getValue())) {
// User canceled dialog.
return;
}
String fn = optionPane.getInputValue().toString();
Related
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);
}
}
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 have written a program with two buttons for a Java class that I am taking. I now need to count and display the number of clicks each button gets. I have some code for counting clicks but am fairly certain that it is wrong.
The error I have is "identifier expected", how can I fix this?
Here is my updated code:
import java.awt.*;
import java.awt.event.*;
public class FinalProj1 extends Frame implements ActionListener,WindowListener {
FinalProj1() {
setTitle("Click Counter");
setSize(400,400);
show();
}
public static void main(String args[]) {
Frame objFrame;
Button objButton1;
Button objButton2;
TextField count = new TextField(20);
TextField count2 = new TextField(20);
Label objLabel;
Label objLabel2;
objFrame= new FinalProj1();
objButton1= new Button("Agree");
objButton2= new Button("Dissagree");
objLabel= new Label();
objLabel2= new Label();
objLabel2.setText("Mexican Food Is Better Than Chineese Food");
objButton1.setBounds(110,175,75,75);
objButton2.setBounds(190,175,75,75);
objLabel2.setBounds(80,95, 250,25);
objFrame.add(objButton2);
objFrame.add(objButton1);
objFrame.add(objLabel2);
objFrame.add(objLabel);
}
private int numClicks = 0;
private int numClicks2 = 0;
objButton1.addActionListener(this)
objButton2.addActionListener(this)
public void actionPerformed(ActionEvent e) {
numClicks++;
numClicks2++;
count.setText("There are " + numClicks + " who agree");
count2.setText("There are " + numClicks2 + " who dissagree");
}
}
The error he's having ("identifier expected") is specified in the previous question.
You're getting this error because these two lines of code are outside any method or initializer block:
objButton1.addActionListener(this)
objButton2.addActionListener(this)
Put them in your constructor after creating the two controls and you should be fine.
One approach is to have one actionListener for every button. Try this:
objButton1.addActionListener(myFirstActionListener)
objButton2.addActionListener(mySecondActionListener)
ActionListener myFirstActionListener = new ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
numClicks++;
}
}
ActionListener mySecondActionListener = new ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
numClicks2++;
}
}
First you should add the action listeners to each button,(explained above).
However,you are incrementing both counts whenever you press one of the two buttons,which is wrong.
So you should modify your action performed method to smthg like this
public void actionPerformed(ActionEvent e)
{
if(e.getSource().equals("Agree"))//if you push the button agree,increment only numClicks
numClicks++;
if(e.getSource().equal("Disagree"))//if you click on disagree,increment numClicks2
numClicks2++;
count.setText("There are " + numClicks + " who agree");
count2.setText("There are " + numClicks2 + " who dissagree");
}
EDIT-Btw,are you implementing the windows listener methods?You have to.
Jeroen's answer is correct for solving your compilation error, so definitely do that first before you proceed.
In regards to your actual counters, the problem you're having is that both your numClicks and numClicks2 variables are being incremented simultaneously whenever either objButton1 or objButton2 is clicked. This is because they are being handled by the same event handler method. You have two choices:
Option 1: let the single event handler method handle both clicks, but distinguish between the two, and only increment the relevant counter, like so:
public void actionPerformed(ActionEvent e){
if(e.getSource() == objButton1){
numClicks++;
} else {
numClicks++;
}
// the rest if your method
}
Option 2: specify separate event handlers for each button, something like this:
objButton1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
numClicks++;
// display your message to user
}
});
objButton2.addActionListener(new ActionListrner(){
public void actionPerformed(ActionEvent e){
numClicks2++;
// display your message to user;
}
});
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
PreventingButtonListener.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PreventingButtonListener extends JFrame implements ActionListener{
JTextField fld = new JTextField(5) ;
PreventingButtonListener(){
super("PreventingButtonListener") ;
setSize(300, 250) ;
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ;
setResizable(false) ;
fld.addFocusListener(
new FocusListener(){
public void focusGained(FocusEvent event) {}
public void focusLost(FocusEvent event) {
int i = (int) (Math.random() * 3) ;
switch(i){
case 0 :
System.out.println("random value : " + i);
fld.requestFocus() ;
break ;
case 1 :
System.out.println("random value : " + i);
i = (int) (Math.random() * 2) ;
if(i == 0){
System.out.println("JOptionPane not displayed, followed with button action.");
}else{
System.out.println("JOptionPane displayed, but button action not performed.");
JOptionPane.showMessageDialog(null, "Hello") ;
}
break ;
default :
System.out.println("random value : " + i);
System.out.println("Nothing to be done...");
break ;
}
}
}) ;
add(fld, "North") ;
JButton btn = new JButton("Hit me Repeatedly considering Note 1") ;
btn.addFocusListener(new FocusListener(){
public void focusGained(FocusEvent arg0) {
System.out.println("focus gained on button.");
}
public void focusLost(FocusEvent arg0) {
System.out.println("focus removed on button.");
}
}) ;
btn.addActionListener(this) ;
add(btn, "South") ;
String str = "Note 1 : Whenever, u click on button, and if the focus" + "\n" +
"after clicking is not in the textfield, then, plz" + "\n" +
"explicitly click in the JTextField." + "\n\n" +
"Note 2 : Kindly notice the output on cmd " + "\n" +
"and related focuses of GUI." + "\n\n" ;
JTextArea area = new JTextArea(str) ;
area.setEditable(false) ;
area.setWrapStyleWord(true) ;
area.setBackground(Color.LIGHT_GRAY) ;
add(new JScrollPane(area)) ;
setVisible(true) ;
}
public void actionPerformed(ActionEvent arg0) {
System.out.println("data of txtfld : >" + fld.getText() + "<");
}
public static void main(String[] args) {
new PreventingButtonListener() ;
}
}
the problem lies in the execution of the attached program???
The JOptionPane that you bring up will be modal, and therefore action will not be processed for any component in your app outside of that JOptionPane.
from the New Modality API article from Sun:
A dialog box can be either modeless or modal. A modal dialog box is one that blocks input to some other top-level windows in the application, except for any windows created with the dialog box as their owner. The modal dialog box captures the window focus until it is closed, usually in response to a button press. A modeless dialog box, on the other hand, sits off on the side and allows you to change its state while other windows have focus. The latter is often used for a toolbar window, such as what you might find in an image-editing program.
JOptionPane methods won't return until the dialog is closed so the action code can be written after the call.