if() will not run in JAVA

142 views Asked by At

I'm pretty new to coding in JAVA. I tried to make a fun multifunctional app where you can select what the app will do with a JComboBox. My idea was to let the user choose and then decide what to do with a if()/else if(). But it seems like the if statement isn't running at all because nothing it will print out to the console which option you chose but the code in the if() statement will not run.

The main class:

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;
import java.io.File;
import javax.sound.sampled.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.Color;

public class Main {

    public static void main(String[] args) throws UnsupportedAudioFileException, IOException, LineUnavailableException{

        int finalRoll;

        Scanner scanner = new Scanner(System.in);

        Random random = new Random();

        File file = new File("/Users/eelien/IdeaProjects/TheBestProgramEver/src/rick-roll-with-no-ads.wav");
        AudioInputStream audioStream = AudioSystem.getAudioInputStream(file);
        Clip clip = AudioSystem.getClip();
        clip.open(audioStream);

//        JFrame frame = new JFrame();

//        ImageIcon image = new ImageIcon("/Users/eelien/IdeaProjects/TheBestProgramEver/src/logo.png");



        Choose choose = new Choose();

        int userChose = choose.userChoice;


//        System.out.println("The variable is: " + userChose);

                if(userChose == 1) {
                    double num1 = Double.parseDouble(JOptionPane.showInputDialog(null, "Enter number 1:"));
                    double num2 = Double.parseDouble(JOptionPane.showInputDialog(null, "Enter number 2:"));

                    JOptionPane.showMessageDialog(null, addition(num1, num2));
                }

                else if (userChose == 2) {
                    String name = JOptionPane.showInputDialog(null, "Enter the humans name:");
                    int age = Integer.parseInt(JOptionPane.showInputDialog(null , "enter the humans age:"));
                    double weight = Double.parseDouble(JOptionPane.showInputDialog(null, "Enter the humans weight:"));
                    double height = Double.parseDouble(JOptionPane.showInputDialog(null, "Enter the humans height:"));

                    Human human = new Human(name, age, weight, height);

                    JOptionPane.showMessageDialog(null, "Your Human has a name: " + name + ", is  " + age + " years old, weights " + weight + "kg and is " + height + " cm tall");
                } else if (userChose == 3) {

                    finalRoll = random.nextInt(6)+1;

                    JOptionPane.showMessageDialog(null, finalRoll);

                } else if (userChose == 4) {
                        clip.start();
                    System.out.println("(Press any key on your keyboard and then ENTER to stop.)");
                    String response = scanner.next();

                } else if (userChose == 5) {

                    MyFrame frame = new MyFrame();


                } else if (userChose == 6) {
                    while (true) {
                        JOptionPane.showMessageDialog(null, "Your computer has a virus!!");
                    }
                }

    }


    static double addition(double num1, double num2)  {

         double total = num1 + num2;
         return total;
    }
}

and the 2nd "Choose" class:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLOutput;
import javax.swing.*;


public class Choose extends JFrame implements ActionListener{

    public int userChoice;
    JComboBox comboBox;
    Choose() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new FlowLayout());

        String[] options = {""};
        comboBox = new JComboBox(options);
        comboBox.addActionListener(this);


        // BTW ADDING THE OPTIONS IN THIS STUPID WAY IS INTENTIONAL

        comboBox.insertItemAt("Addition of 2 numbers in a GUI", 1 );
        comboBox.insertItemAt("Human Constructor in a GUI", 2 );
        comboBox.insertItemAt("Roll a dice in a GUI", 3);
        comboBox.insertItemAt("Play a song", 4);
        comboBox.insertItemAt("Window launcher", 5);
        comboBox.insertItemAt("Enter JOptionPane", 6);

        this.add(comboBox);
        this.pack();
        this.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == comboBox); {
            userChoice = (int) comboBox.getSelectedIndex();
            System.out.println("The user chose number: " + userChoice);

        }
    }
}

Here's a video if it helps: https://imgur.com/a/8VkXmGb
1

There are 1 answers

5
MadProgrammer On

The core problem is, most GUI's are event driven, that is, something happens and your respond to it. You're trying to use a procedural workflow where one action proceeds another.

So when you do...

Choose choose = new Choose();
int userChose = choose.userChoice;

the window won't even have been displayed to the user when you call choose.userChoice, so you will get it's default value, which is initialised to 0 by default.

You should have seen this effect, as the System.out.println in the actionPerformed method won't have been called before System.out.println("The variable is: " + userChose);.

So, what's the solution? Well, many.

The first thing you should do is check out How to Make Dialogs, in particular, "modal" dialogs.

A modal dialog is a special window in that, when made visible, the current code execution won't continue until the dialog is closed (black magic ).

As a general guide line, you should avoid extending from top level containers like JFrame and JDialog. They are, in of themselves, complicated components, best to avoid those complications. You're also not really extending the functionality of the class and it generally locks you into a single use case - what happens if you want to display the options in side panel of another UI? You'd have to re-write the code .

public static class MenuPane extends JPanel {
    private JComboBox comboBox;

    public MenuPane() {
        this.setLayout(new GridBagLayout());
        comboBox = new JComboBox(
                new String[] {
                    "Addition of 2 numbers in a GUI",
                    "Human Constructor in a GUI",
                    "Roll a dice in a GUI",
                    "Play a song",
                    "Window launcher",
                    "Enter JOptionPane"
                });

        // This will default the combobox's selected value to be
        // empty
        comboBox.setSelectedIndex(-1);

        add(comboBox);
    }

    public int getSelectedValue() {
        return comboBox.getSelectedIndex();
    }

    public static int showMenuOptions() {
        MenuDialog menuDialog = new MenuDialog();
        return menuDialog.show();

    }

    protected static class MenuDialog {
        private int selectedOption = -1;
        private JDialog dialog;

        public MenuDialog() {
            dialog = new JDialog();
            dialog.setModal(true);

            MenuPane menuPane = new MenuPane();
            dialog.add(menuPane);

            JButton okButton = new JButton("Ok");
            JButton cancelButton = new JButton("Cancel");

            JPanel actionsPane = new JPanel(new GridBagLayout());
            actionsPane.add(okButton);
            actionsPane.add(cancelButton);

            dialog.add(actionsPane, BorderLayout.SOUTH);

            okButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    selectedOption = menuPane.getSelectedValue();
                    dialog.dispose();
                }
            });
            cancelButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    dialog.dispose();
                }
            });

            dialog.pack();
            dialog.setLocationRelativeTo(null);
        }

        public int getSelectedOption() {
            return selectedOption;
        }

        public int show() {
            dialog.setVisible(true);
            return getSelectedOption();
        }
    }
}

This class has a nice static helper called showMenuOptions which will display a modal dialog to the user and return the user's selected options.

You could use this something like...

int selectedOption = MenuPane.showMenuOptions();
System.out.println(selectedOption);

This would present the options to the user, allow them to select an option and when they click Ok, return the selection index to you - just remember, this would be zero index now .

Now, that's a lot of work for, arguably, little gain. You could, instead, just do something like...

String option = (String) JOptionPane.showInputDialog(
        null, 
        "Make a selection", 
        "Options", 
        JOptionPane.PLAIN_MESSAGE, 
        null, 
        new String[] {
                "Addition of 2 numbers in a GUI",
                "Human Constructor in a GUI",
                "Roll a dice in a GUI",
                "Play a song",
                "Window launcher",
                "Enter JOptionPane"
            }, 
        null
);
System.out.println(option);

This would return String of the selected value, which might not be that useful (or more difficult to manage).

I might be tempted to, instead, create a "menu option" class which had a easy to compare id and a description...

public class MenuOption {
    private int value;
    private String description;

    public MenuOption(int value, String description) {
        this.value = value;
        this.description = description;
    }

    public int getValue() {
        return value;
    }

    @Override
    public String toString() {
        return description;
    }        
}

And then use it something like...

MenuOption option = (MenuOption) JOptionPane.showInputDialog(
        null, 
        "Make a selection", 
        "Options", 
        JOptionPane.PLAIN_MESSAGE, 
        null, 
        new MenuOption[] {
                new MenuOption(1, "Addition of 2 numbers in a GUI"),
                new MenuOption(2, "Human Constructor in a GUI"),
                new MenuOption(3, "Roll a dice in a GUI"),
                new MenuOption(4, "Play a song"),
                new MenuOption(5, "Window launcher"),
                new MenuOption(6, "Enter JOptionPane")
            }, 
        null
);
System.out.println(option.getValue());

This would allow you to compare the option's value instead, which is an int.

You could also expand the concept back to the MenuPane, seeding the MenuOptions via the constructor and returning the selected MenuOption instead of an int.

You could then expand MenuOption concept to included a execute method which would actually perform the actions for the option and have a self contained unit of work, no need for if-else if statements at all - but's a whole other topic

Runnable example...

import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        // Option #1
        //int selectedOption = MenuPane.showMenuOptions();
        //System.out.println(selectedOption);

        // Option #2
        //String option = (String) JOptionPane.showInputDialog(
        //        null, 
        //        "Make a selection", 
        //        "Options", 
        //        JOptionPane.PLAIN_MESSAGE, 
        //        null, 
        //        new String[] {
        //                "Addition of 2 numbers in a GUI",
        //                "Human Constructor in a GUI",
        //                "Roll a dice in a GUI",
        //                "Play a song",
        //                "Window launcher",
        //                "Enter JOptionPane"
        //            }, 
        //        null
        //);
        //System.out.println(option);

        // Option #3
        MenuOption option = (MenuOption) JOptionPane.showInputDialog(
                null,
                "Make a selection",
                "Options",
                JOptionPane.PLAIN_MESSAGE,
                null,
                new MenuOption[]{
                    new MenuOption(1, "Addition of 2 numbers in a GUI"),
                    new MenuOption(2, "Human Constructor in a GUI"),
                    new MenuOption(3, "Roll a dice in a GUI"),
                    new MenuOption(4, "Play a song"),
                    new MenuOption(5, "Window launcher"),
                    new MenuOption(6, "Enter JOptionPane")
                },
                null
        );
        System.out.println(option.getValue());
    }

    public class MenuOption {
        private int value;
        private String description;

        public MenuOption(int value, String description) {
            this.value = value;
            this.description = description;
        }

        public int getValue() {
            return value;
        }

        @Override
        public String toString() {
            return description;
        }
    }

    public static class MenuPane extends JPanel {
        private JComboBox comboBox;

        public MenuPane() {
            this.setLayout(new GridBagLayout());
            comboBox = new JComboBox(
                    new String[]{
                        "Addition of 2 numbers in a GUI",
                        "Human Constructor in a GUI",
                        "Roll a dice in a GUI",
                        "Play a song",
                        "Window launcher",
                        "Enter JOptionPane"
                    });

            comboBox.setSelectedIndex(-1);

            add(comboBox);
        }

        public int getSelectedValue() {
            return comboBox.getSelectedIndex();
        }

        public static int showMenuOptions() {
            MenuDialog menuDialog = new MenuDialog();
            return menuDialog.show();

        }

        protected static class MenuDialog {
            private int selectedOption = -1;
            private JDialog dialog;

            public MenuDialog() {
                dialog = new JDialog();
                dialog.setModal(true);

                MenuPane menuPane = new MenuPane();
                dialog.add(menuPane);

                JButton okButton = new JButton("Ok");
                JButton cancelButton = new JButton("Cancel");

                JPanel actionsPane = new JPanel(new GridBagLayout());
                actionsPane.add(okButton);
                actionsPane.add(cancelButton);

                dialog.add(actionsPane, BorderLayout.SOUTH);

                okButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        selectedOption = menuPane.getSelectedValue();
                        dialog.dispose();
                    }
                });
                cancelButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        dialog.dispose();
                    }
                });

                dialog.pack();
                dialog.setLocationRelativeTo(null);
            }

            public int getSelectedOption() {
                return selectedOption;
            }

            public int show() {
                dialog.setVisible(true);
                return getSelectedOption();
            }
        }
    }
}