1

I have the following problem: My method opens a JDialog with a bunch of buttons (only one in example code). I want to click a button and thereby choose an ImageIcon for my method to return. But the Method does not wait for me to click a button. It opens the window and then returns an empty ImageIcon.

public class Kartenauswahl {

    ImageIcon bandit;

    public ImageIcon auswahlfenster() {

        int bwidth = new Integer(150);
        int bheight = new Integer(225);

        bandit = new ImageIcon("cover/Bandit.jpe");
        bandit.setImage(bandit.getImage().getScaledInstance(bwidth,bheight,Image.SCALE_DEFAULT));

        final JDialog kartenwahl = new JDialog();
        kartenwahl.setTitle("Kartenwahl");
        kartenwahl.setSize(1500,1000);
        kartenwahl.setVisible(true);
        kartenwahl.setLayout(new FlowLayout());

        ImageIcon returnicon= new ImageIcon();
        final JButton b1 = new JButton(); //just to get the Icon out of the void loop





        JButton B1 = new JButton(bandit); //this is going to be the button I want to click to choose the ImageIcon which is returned
        B1.setContentAreaFilled(false);
        B1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {

                b1.setIcon(bandit);
                kartenwahl.dispose();
            }

        });

        kartenwahl.add(B1);

        returnicon = (ImageIcon) b1.getIcon();

        return returnicon;

    }
}

Question: can I bind the return statement to a condition? Like "only return after I clicked that Button B1"?

Keyur Potdar
  • 7,158
  • 6
  • 25
  • 40
Haerus
  • 11
  • 2
  • 1
    Thats the whole purpose of your actionevent. – Saltz Mar 26 '18 at 15:38
  • Is that a question? In that case the answer is Yes! – Haerus Mar 26 '18 at 15:41
  • Otherwise I don't understand what you are trying to say. If the ActionEvent delays the return, why doesn't my method work then? – Haerus Mar 26 '18 at 15:42
  • The eventhandler in your case: actionPerformed. Will only run when the user clicks the button that the evenhandler is lisining to (B1). Now i see you have a second button b1. And that is the button you are setting the icon for in your eventhandler. Maybe that is your problem? – Saltz Mar 26 '18 at 15:50
  • I can not return the ImageIcon directly from the EventHandler, since it is a void method. So I have to set it to an exterior ImageIcon. Since I can't access an exterior variable from a void method (at least that is the exception I got when I tried) I go the way over Button b1. By the time I send the ImageIcon to b1 and thereby the "returnicon" the method will have already returned the empty "returnicon". – Haerus Mar 26 '18 at 15:54
  • Ok i don't really understand why you're trying to pass along an image icon. Could you elaborate? – Saltz Mar 26 '18 at 16:00
  • I need the ImageIcon in another class to set it onto another button. It's a bit complicated :D I don't have enough reputation to chat, sadly, otherwise I could get into detail. Is there any way to return it after I initiate the event from the eventhandler? – Haerus Mar 26 '18 at 16:03
  • The thing you are describing sounds like a Dialog. A pop-up window that the user has to click before the code will continue. In your case a custom Dialog should do the trick. Check out this [question](https://stackoverflow.com/questions/789517/java-how-to-create-a-custom-dialog-box). – Saltz Mar 26 '18 at 16:06
  • All this happens in a JDialog. Is that different from a CustomDialog? The Dialog needs to contain around 26 Buttons of the size 150,225. A simple YES_NO_Option won't do. – Haerus Mar 26 '18 at 16:14
  • I have tried a ConfirmDialog, but it just puts the 26 Buttons underneath each other, so I can't see 24 of them. Can I align them in rows of 7 or 8? Code: final JComponent[] inputs = new JComponent[]{ B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B20, B21, B22, B23, B24, B25, B26, }; JOptionPane.showConfirmDialog(null, inputs, "Kartenwahl", JOptionPane.PLAIN_MESSAGE); – Haerus Mar 26 '18 at 17:04

1 Answers1

1

Hi sorry for the long wait. I have written an custom JDialog that should work for you.

public class CustomDialog extends JDialog {
    JButton[] buttons;
    ImageIcon selectedImageIcon;

    public CustomDialog() {
        setSize(500, 500);
        setLayout(new GridLayout(4, 6));
        ActionListener actionListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                selectedImageIcon = ((ImageIcon) ((JButton) e.getSource()).getIcon());
                dispose();
            }
        };
        buttons = new JButton[24];
        for(int i = 0; i < 24; i++) {
            buttons[i] = new JButton(new ImageIcon("path_to_your_image_file"));
            buttons[i].addActionListener(actionListener);
            add(buttons[i]);
        }
        setVisible(true);
    }

    public ImageIcon getSelectedImageIcon() {
        return selectedImageIcon;
    }
}

The initial size is not that important the GridLayout is. you mentioned that you would need 24 buttons so I created an grid with 4 rows and 6 columns. Then I create the buttons in a loop and adding the same Listener to set the selection icon with the icon of the pressed button. Afterwards I dispose the screen triggering an windowClosed event.

You could simply create this Dialog from your main class and wait for the response like so:

public class main {
    public static void main(String[] args) {
        CustomDialog customDialog = new CustomDialog();
        customDialog.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                ImageIcon icon = customDialog.getSelectedImageIcon();
                //do something with your icon
            }
        });
    }
}

Don't forget to mark this answer as correct if it fixes your problem. Have a good one!

Saltz
  • 413
  • 5
  • 18