Как мне ждать ввода от GUI обратно к основному? - PullRequest
1 голос
/ 30 мая 2019

Я хочу иметь возможность передавать пользовательский ввод из моего графического интерфейса в один из моих классов.Однако ввод не передается и сразу проверяет оператор if.Как заставить программу ожидать ввода и проверять только после нажатия кнопки?

Основной класс

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

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 запускается какожидается.Тем не менее, первая печать отсутствует.Как бы я поступил так?Какие концепции или фрагменты кода мне не хватает?

EDIT1: добавлена ​​еще пара деталей, чтобы сделать программу воспроизводимой и полной.

EDIT2: сделать код более читабельным для более легкого понимания.

1 Ответ

1 голос
/ 30 мая 2019

В вашей программе есть некоторые изменения

  1. Удалить extends JFrame, как указано в моих комментариях выше, см. Расширяет JFrame по сравнению с созданием его внутри программы

  2. Поместите вашу программу в EDT, см. Пункт # 3 в этот ответ и метод main для примера того, как это сделать.

  3. Вы озадачены тем, как работает ActionListeners, они ждут, пока вы не выполните определенное действие в вашей программе (т.е. вы нажимаете кнопку Confirm), а затем что-то делаете. «Что-то» в вашей программе означает: распечатайте выбранный предмет и проверьте, является ли оно оружием, затем сделайте что-нибудь еще.

Таким образом, в этом случае вам не нужно возвращаться к main, чтобы продолжить работу с вашей программой, main служит только для инициализации приложения и ничего больше. Вам нужно думать в событиях, а не последовательно . Это сложная и самая важная часть.

Вам нужно изменить свою парадигму программирования из консольных приложений и do-while, чтобы все происходило последовательно, а не событиями, которые запускаются, когда пользователь что-то делает с вашим приложением.

Например:

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

Обратите внимание, что я удалил наследство, я не возвращаюсь назад к main и все еще печатаю выбранный предмет и проверяю, оружие это или нет.

Я также выхожу из приложения более безопасным способом.

Это пример вывода:

Weapon
It's a weapon!
Armor
Not a weapon
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...