1

I want to be able to pass user input from my GUI to one of my classes. However, the input is not passed over and immediately checks the if statement. How do I get program to wait for the input and only checks after the button is clicked?

Main class

public class MainTest {
    public static void main(String[] args) {
        String weaponCategory;
        //Create Java GUI
        GUITest window = new GUITest();

        if(window.getCategory() != "")
        {
            System.out.println("test");
        }
    }

}

GUITest class

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GUITest implements ActionListener{

    private JFrame frmInventorysystem;
    private JPanel frameBottom;
    private JComboBox equipList;
    private String category = "";
    private JButton confirmBtn, cancelBtn;

    /**
     * Create the application.
     */
    public GUITest() 
    {       
        frmInventorysystem = new JFrame();
        frmInventorysystem.setTitle("InventorySystem");
        frmInventorysystem.setBounds(100, 100, 450, 300);
        frmInventorysystem.getContentPane().setLayout(new BorderLayout(0, 0));

        frmInventorysystem.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /*JFrame inside another JFrame is not recommended. JPanels are used instead.
        * Creating a flow layout for the bottom frame
        */
        frameBottom = new JPanel();
        frameBottom.setLayout(new FlowLayout());

        //creates comboBox to find out which of the three items player is looking to insert
        String[] weaponCategories = {"Weapon", "Armor", "Mod"};
        equipList = new JComboBox(weaponCategories);
        frmInventorysystem.getContentPane().add(equipList, BorderLayout.NORTH);

        //Converting BorderLayout.south into a flow layout
        frmInventorysystem.getContentPane().add(frameBottom, BorderLayout.SOUTH);

        confirmBtn = new JButton("Confirm");
        confirmBtn.addActionListener(this);

        frameBottom.add(confirmBtn);

        cancelBtn = new JButton("Cancel");
        cancelBtn.addActionListener(this);
        frameBottom.add(cancelBtn);

        frmInventorysystem.setVisible(true);
    }

    public void actionPerformed(ActionEvent e)
    {
        //creates new windows to sort equipment when confirmBtn is clicked
        if(e.getSource() == confirmBtn) 
        {
            if(equipList.getSelectedItem().equals("Weapon"))
            {
                //GUIWeaponCategory weapon = new GUIWeaponCategory();
                category = equipList.getSelectedItem().toString();
            }
        }
        //Exits when cancelBtn is clicked
        if(e.getSource() == cancelBtn)
        {
            System.exit(0);
        }
    }

    public String getCategory()
    {
        return category;
    }

    public void setCategory(String a)
    {
        category = a;
    }
}

GUITest launches as expected. However, the first println is missing. How would I go about doing this? What concepts or pieces of code am I missing?

EDIT1: Added a couple more details to make the program reproducible and complete.

EDIT2: Making the code more readable for easy understanding.

PredictableBeaco
  • 97
  • 1
  • 1
  • 8
  • *"How do I wait for the input from the GUI back to main?"* Make the GUI a modal dialog. General tip: For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson May 30 '19 at 11:43
  • Thanks. I'll try and look into it. And thanks for pointing it out, will try and implement your comment into future questions. – PredictableBeaco May 30 '19 at 11:56
  • So.. `private JFrame frmInventorysystem;` I'm thinking you have yet to change that to something like `private JDialog dlgInventorysystem;`? – Andrew Thompson May 30 '19 at 12:55
  • 2
    BTW: See [What is the XY problem?](http://meta.stackexchange.com/q/66377) It seems to have a 'bad code smell' to be trying to combine a GUI with command line input or output. – Andrew Thompson May 30 '19 at 13:01
  • Sorry that was the original code to flesh out the question. Additionally, the code was something I've thought of and decided to just go for it. The code is terrible, but it's something that I can fix later. I just needed to get it working first. – PredictableBeaco May 30 '19 at 13:14
  • 3
    *"The code is terrible, but it's something that I can fix later"* Huh.. how that reads in my head is *"I want you all to make a hack so my broken code works"*. The thing is, the hack would take longer, and still be less effective, than tossing that code out and starting again with a modal dialog. Unsurprising as it may seem, few people worth listening to are keen to do that. There are lots of people here asking questions. The ones most likely to get attention and a solution are those who appreciate our time is important to us, and can 'pick up the ball & run with it'. Good luck with that. – Andrew Thompson May 30 '19 at 14:06
  • I just realized what you meant. I'll try and fix the code over the next minutes to make it clearer. – PredictableBeaco May 30 '19 at 15:06
  • 1
    I have an answer mentioning the same as @AndrewThompson about mixing 2 code paradigms (Console + GUI), you can read it [here](https://stackoverflow.com/questions/41904362/multiple-joptionpane-input-dialogs/41904856#41904856) and it also provides an example on using `JDialogs` as well as some other useful tips – Frakcool May 30 '19 at 15:43
  • Your code works perfectly fine for me. What is the error you have? Only concerns are to remove the `extends JFrame` part, read [extends JFrame or create it inside of class](https://stackoverflow.com/questions/22003802/extends-jframe-vs-creating-it-inside-the-program) and that you're not placing the program on the EDT (see linked answer above) – Frakcool May 30 '19 at 15:56
  • Sorry, I was too busy cleaning up the code(see above) that I accidentally changed what made the not work in the first place. It's fixed now. The goal was to basically to get the getCategory() method to work in the main() method. But since I've been told to get start looking up JDialog and modality, I've been reading on that. – PredictableBeaco May 30 '19 at 16:03
  • 1) You compare Strings with `.equals(...)` and not with `==` 2) What are you trying to do? That print should be inside the `if(equipList.getSelectedItem() == "Weapon")` part on your `actionPerformed` – Frakcool May 30 '19 at 16:05
  • 1. Okay. Will change that in my code now. 2. The goal was to show that the print is never executed, and therefore shows that the if statement in the main is checked immediately and ignored because it's false. – PredictableBeaco May 30 '19 at 16:14

1 Answers1

1

There are some changes to make on your program

  1. Remove extends JFrame as stated in my comments above, see Extends JFrame vs. creating it inside the program

  2. Place your program on the EDT, see point #3 on this answer and the main method for an example on how to do that.

  3. You're confused about how the ActionListeners work, they wait until you perform certain action in your program (i.e. you press Confirm button) and then do something. "Something" in your program means: Print the selected item and check if it's a weapon then, do something else.

So, in this case, you don't need to return back to main to continue with your program, main only serves to initialize your application and nothing else. You need to think in the events and not in a sequential way. That's the tricky and most important part.

You need to change your programming paradigm from console applications and do-while that everything happens in a sequential manner rather than events that are triggered when the user does something with your application.

For example:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GUITest implements ActionListener {
    private JFrame frmInventorysystem;
    private JPanel frameBottom;
    private JComboBox equipList;
    private JButton confirmBtn, cancelBtn;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new GUITest()); //Java 8+ if using an earlier version check the point #2 in this answer and modify the code accordingly.
    }

    /**
     * Create the application.
     */
    public GUITest() {
        frmInventorysystem = new JFrame();
        frmInventorysystem.setTitle("InventorySystem");
        frmInventorysystem.setBounds(100, 100, 450, 300);
        frmInventorysystem.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmInventorysystem.getContentPane().setLayout(new BorderLayout(0, 0));

        /*
         * JFrame inside another JFrame is not recommended. JPanels are used instead
         * Creating a flow layout for the bottom frame
         */
        frameBottom = new JPanel();
        frameBottom.setLayout(new FlowLayout());

        // creates comboBox to find out which of the three items player is looking to
        // insert
        String[] weaponCategories = { "Weapon", "Armor", "Mod" };
        equipList = new JComboBox(weaponCategories);
        frmInventorysystem.getContentPane().add(equipList, BorderLayout.NORTH);

        // Converting BorderLayout.south into a flow layout
        frmInventorysystem.getContentPane().add(frameBottom, BorderLayout.SOUTH);

        confirmBtn = new JButton("Confirm");
        confirmBtn.addActionListener(this);

        frameBottom.add(confirmBtn);

        cancelBtn = new JButton("Cancel");
        cancelBtn.addActionListener(this);
        frameBottom.add(cancelBtn);

        frmInventorysystem.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        // creates new windows to sort equipment when confirmBtn is clicked
        if (e.getSource() == confirmBtn) {
            String category = equipList.getSelectedItem().toString(); //Get the selected category
            doSomething(category); //Pass it as a parameter
        }
        // Exits when cancelBtn is clicked
        if (e.getSource() == cancelBtn) {
            frmInventorysystem.dispose();
        }
    }

    // Do something with the category
    private void doSomething(String selectedEquipment) {
        System.out.println(selectedEquipment);
        if (selectedEquipment.equals("Weapon")) {
            System.out.println("It's a weapon!"); //You can open dialogs or do whatever you need here, not necessarily a print.
        } else {
            System.out.println("Not a weapon");
        }
    }
}

Notice that I removed inheritance, I'm not returning back to main and still printing the selected item and checking if it's a weapon or not.

I also exit the application in a safer way.

This is a sample output:

Weapon
It's a weapon!
Armor
Not a weapon
Frakcool
  • 10,915
  • 9
  • 50
  • 89