我对 JAVA 编码还很陌生。我尝试制作一个有趣的多功能应用程序,您可以在其中选择应用程序将使用 JComboBox 执行的操作。我的想法是让用户选择,然后决定如何使用 if()/else if()。但似乎 if 语句根本没有运行,因为它不会将您选择的选项打印到控制台,但 if() 语句中的代码不会运行。
主要课程:
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;
}
}
和第二个“选择”课程:
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
核心问题是,大多数 GUI 都是事件驱动的,也就是说,发生某些事情并且您对其做出响应。您正在尝试使用一种程序化工作流程,其中一个操作会执行另一个操作。
所以当你这样做时...
Choose choose = new Choose();
int userChose = choose.userChoice;
当您调用
choose.userChoice
时,该窗口甚至不会向用户显示,因此您将获得它的默认值,默认情况下初始化为 0
。
你应该已经看到了这个效果,因为
System.out.println
方法中的 actionPerformed
之前不会被调用 System.out.println("The variable is: " + userChose);
。
那么,解决办法是什么?嗯,很多。
您应该做的第一件事是查看如何制作对话框,特别是“模态”对话框。
模式对话框是一个特殊的窗口,当它可见时,当前的代码执行将不会继续,直到对话框关闭(黑魔法😉)。
作为一般准则,您应该避免从顶级容器(如
JFrame
和 JDialog
)进行扩展。它们本身就是复杂的组件,最好避免这些并发症。您也没有真正扩展该类的功能,它通常会将您锁定在单个用例中 - 如果您想在另一个 UI 的侧面板中显示选项,会发生什么情况?你必须重新编写代码🤨。
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();
}
}
}
这个类有一个很好的
static
帮助器,称为 showMenuOptions
,它将向用户显示模式对话框并返回用户选择的选项。
你可以使用这个类似...
int selectedOption = MenuPane.showMenuOptions();
System.out.println(selectedOption);
这会将选项呈现给用户,允许他们选择一个选项,当他们单击
Ok
时,将选择索引返回给您 - 请记住,现在索引为零 😉。
现在,虽然付出了很多努力,但收效甚微。相反,你可以做一些类似的事情...
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);
这将返回所选值的
String
,这可能没那么有用(或更难管理)。
我可能会想创建一个“菜单选项”类,它有一个易于比较的 id 和描述...
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;
}
}
然后使用它......
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());
这将允许您比较选项的
value
,这是一个 int
。
您还可以将概念扩展回
MenuPane
,通过构造函数播种 MenuOption
并返回选定的 MenuOption
而不是 int
。
然后,您可以扩展
MenuOption
概念以包含 execute
方法,该方法将实际执行选项的操作并具有一个独立的工作单元,根本不需要 if-else if
语句 - 但这是一个完全不同的主题 😉