How to close a JDialog through JButtons - java

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.

Related

JOptionPane Dialog Determine if Close Button was Clicked

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);
}
}

How to get the source of multiple JButtons in action listener?

I'm coding a memory matching game using pictures and a JButton array, but I've run into a problem when I try to compare two buttons that were clicked. How do you store the index of/get the index of the second button? All of my buttons in the button array are linked to the same actionListener but e.getSource() will only get the first button clicked, as far as I'm aware. I'd really appreciate some help. (I didn't want to paste in my entire code, because that's a lot, so I'm just putting in parts I think are relevant):
public DisplayMM(ActionListener e)
{
setLayout(new GridLayout(6, 8, 5, 5));
JButton[] cards = new JButton[48]; //JButton board
for(int x = 0; x < 48; x++) //initial setup of board
{
cards[x] = new JButton();
cards[x].addActionListener(e);
cards[x].setHorizontalAlignment(SwingConstants.CENTER);
cards[x].setPreferredSize(new Dimension(75, 95));
}
private class e implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
for(int i = 0; i < 48; i++)
{
if((e.getSource())==(cards[i]))//1st button that was clicked
{
cards[i].setIcon(new ImageIcon(this.getClass().getResource(country[i])));
currentIndex = i;
}
}
//cards[i].compareIcons(currentIndex, secondIndex);
}
}
Also, in my Panel class, I attempted to do something similar, but ended up moving it to the Display class because Panel didn't have access to the button array.
//Panel
public void actionPerformed(ActionEvent e)
{
/*every 2 button clicks it does something and decreases num of tries*/
noMatchTimer = new Timer(1000, this);
noMatchTimer.setRepeats(false);
JButton source = (JButton)e.getSource();
guess1 = source.getText(); //first button clicked
numGuess++; //keeps track of number of buttons clicked
JButton source2 = (JButton)e.getSource();
guess2 = source2.getText();
numGuess++;
if(numGuess == 1)
display.faceUp(cards, array, Integer.parseInt(e.getSource()));
else
display.compareIcons(guess1, guess2);
if(tries != 12 && count == 24)
{
displayWinner();
}
}
You can give your ActionListener class private fields, even if it's an anonymous inner class, and one of those fields can be a reference to the last button pushed. Set it to null after the 2nd button is pushed and you'll always know if the button press is for the first or second button.
e.g.,
class ButtonListener implements ActionListener {
private JButton lastButtonPressed = null;
#Override
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
if (lastButtonPressed == null) {
// then this is the first button
lastButtonPressed = source;
} else {
// this is the 2nd button
if (source == lastButtonPressed) {
// the dufus is pushing the same button -- do nothing
return;
} else {
// compare source and lastButtonPressed to see if same images (icons?)
// if not the same, use a Timer to hold both open for a short period of time
// then close both
lastButtonPressed = null;
}
}
}
}

Java how to assign id to button and retrieve them?

I'm getting stuck while building a forum like application which has a vote button.
I have vote up and vote down button for each content which are automatically generated. I want this button to only display the up and down arrow but not any text or label.. how can i find out which button is pressed?
Automated content..
ImageIcon upvote = new ImageIcon(getClass().getResource("vote_up.png"));
ImageIcon downvote = new ImageIcon(getClass().getResource("vote_down.png"));
JButton vote_up = new JButton(upvote);
JButton vote_down = new JButton(downvote);
vote_up.addActionListener(voting);
vote_down.addActionListener(voting);
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
//What to do here to find out which button is pressed?
}
};
any help is appreciated.
public void a(){
int crt_cnt = 0;
for(ClassA temp : listofClassA)
{
b(crt_cnt);
crt_cnt++;
}
}
public void b(crt_cnt){
//draw button
}
As from above, I have multiple vote_up and vote_down button created by the b function, how can i differentiate which crt_cnt is the button from?
There are multiple ways you might achieve this
You could...
Simply use the source of the ActionEvent
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up) {
//...
} else if (...) {
//...
}
}
};
This might be okay if you have a reference to the original buttons
You could...
Assign a actionCommand to each button
JButton vote_up = new JButton(upvote);
vote_up.setActionCommand("vote.up");
JButton vote_down = new JButton(downvote);
vote_down .setActionCommand("vote.down");
//...
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if ("vote.up".equals(e.getActionCommand())) {
//...
} else if (...) {
//...
}
}
};
You could...
Take full advantage of the Action API and make indiviual, self contained actions for each button...
public class VoteUpAction extends AbstractAction {
public VoteUpAction() {
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("vote_up.png")));
}
#Override
public void actionPerformed(ActionEvent e) {
// Specific action for up vote
}
}
Then you could simply use
JButton vote_up = new JButton(new VoteUpAction());
//...
Which will configure the button according to the properties of the Action and will trigger it's actionPerformed method when the button is triggered. This way, you know 100% what you should/need to do when the actionPerformed method is called, without any doubts.
Have a closer look at How to Use Actions for more details
You can detect by using the method getSource() of your EventAction
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up ) {
// vote up clicked
} else if (e.getSource() == vote_down){
// vote down clicked
}
}
};
hey thanks for all the help and assistance! I've finally got it! I solved it by
assigning a text on the button, +/- for vote up or down, followed by the content id which i required, then change the font size to 0
vote.setText("+"+thistopic.content.get(crt_cnt).get_id());
vote.setFont(heading.getFont().deriveFont(0.0f));
after that i could easily trace which button is pressed by comparing to the
actionEvent.getActionCommand()
which return the text on the button!
I would wrap the JButton similar to this:
JButton createMyButton(final JPanel panel, final String text,
final boolean upOrDown, final int gridx, final int gridy) {
final JButton button = new JButton();
button.setPreferredSize(new Dimension(80, 50));
final GridBagConstraints gbc = Factories.createGridBagConstraints(gridx,
gridy);
panel.add(button, gbc);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
myActionPerformed(text, upOrDown);
}
});
return button;
}
You could use an int instead of the text, if more convenient.

Closing JOptionPane after input option selected

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

show a new jframe on another jframe close event

I have 2 jframes(assume A and B) and when I close a one jframe(A) I need to show other jframe(B) I have a clue that I need to override defaultClosingOperation but I have no idea how to do that.any help would be appreciated .. thank you all.
You can add a Windows Listener to your frame.
WindowListener myExitListener = new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
int confirmation = JOptionPane.showOptionDialog(jframe1, "Open frame2", "Open frame2", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
if (confirmation == 0) {
//open jframe2 here
}
}
};
jframe1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
jframe1.addWindowListener(myExitListener);

Categories

Resources