IntelliJ中Java GUI无法显示并报NumberFormatException错误求助
Java GUI程序启动异常排查与修复
在IntelliJ中运行Java GUI程序时,窗口无法显示,10秒后自动关闭,并抛出NumberFormatException异常。
错误日志
/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=49311:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath OverervingFiguren/target/classes presentatie.FiguurGUI Exception in thread "main" java.lang.NumberFormatException: For input string: "" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:678) at java.base/java.lang.Integer.parseInt(Integer.java:786) at presentatie.FiguurGUI.<init>(FiguurGUI.java:21) at presentatie.FiguurGUI.main(FiguurGUI.java:66) Process finished with exit code 1
错误指向代码第21行:int x = Integer.parseInt(TextxCoordinaat.getText());,第66行是frame.setContentPane(new FiguurGUI().FiguurGUI);。
原代码(presentatie.FiguurGUI类)
package presentatie; public class FiguurGUI { private JTextField TextxCoordinaat; int x = Integer.parseInt(TextxCoordinaat.getText()); private JTextField TextyCoordinaat; int y = Integer.parseInt(TextyCoordinaat.getText()); private JComboBox<Kleur> comboKleur; Kleur kleur = Kleur.valueOf((String) comboKleur.getSelectedItem()); private JComboBox<Kleur> comboKleurRand; Kleur kleurRand = Kleur.valueOf((String) comboKleurRand.getSelectedItem()); private JRadioButton cirkelRadioButton; private JRadioButton vierkantRadioButton; private JButton voegToeButton; private JButton undoButton; private JSpinner SpinDikteRand; int dikteRand = (int) SpinDikteRand.getValue(); private JTextField Textgrootte; double grootte = Double.parseDouble(Textgrootte.getText()); private JPanel FiguurGUI; private JTextField TextOutput; private ArrayList<String> outputLijst = new ArrayList<>(); public FiguurGUI() { voegToeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (cirkelRadioButton.isSelected()) { Cirkel cirkel = new Cirkel(new Punt(x, y), grootte, kleur, kleurRand, dikteRand); outputLijst.add(cirkel.toString()); System.out.println("cirkel!!!"); } if (vierkantRadioButton.isSelected()) { Vierkant vierkant = new Vierkant(new Punt(x, y), grootte, kleur, kleurRand, dikteRand); outputLijst.add(vierkant.toString()); System.out.println("vierkant!!!"); } else { throw new IllegalArgumentException("Kies uit cirkel of vierkant"); } TextOutput.setText(outputLijst.toString()); } }); } public static void main(String[] args) { JFrame frame = new JFrame("FiguurGUI"); frame.setContentPane(new FiguurGUI().FiguurGUI); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(740, 440); frame.setVisible(true); } }
问题根源
- 组件未初始化就读取值:类成员变量(如
x、y、grootte等)在类加载阶段直接调用组件的getText()、getValue()方法,但此时GUI组件(如TextxCoordinaat、SpinDikteRand)还未完成初始化(若使用IntelliJ Form Designer,组件绑定是在构造函数执行后完成的),导致获取到空字符串或null,触发NumberFormatException。 - 缺少输入验证:即使组件初始化完成,用户未输入内容时直接转换也会抛出异常。
修复方案
- 将变量初始化移到事件触发时:不要在类成员声明阶段读取组件值,而是在用户点击按钮(
voegToeButton)时再获取并转换。 - 添加输入验证逻辑:转换前检查输入是否为空或格式合法,避免异常。
- 确保组件正确绑定:如果使用Form Designer,确认
FiguurGUI面板已正确关联到类,所有组件变量已完成注入。
修改后的代码示例
package presentatie; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; public class FiguurGUI { private JTextField TextxCoordinaat; private JTextField TextyCoordinaat; private JComboBox<Kleur> comboKleur; private JComboBox<Kleur> comboKleurRand; private JRadioButton cirkelRadioButton; private JRadioButton vierkantRadioButton; private JButton voegToeButton; private JButton undoButton; private JSpinner SpinDikteRand; private JTextField Textgrootte; private JPanel FiguurGUI; private JTextField TextOutput; private ArrayList<String> outputLijst = new ArrayList<>(); public FiguurGUI() { voegToeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { // 在按钮点击时才获取并转换输入值 int x = Integer.parseInt(TextxCoordinaat.getText().trim()); int y = Integer.parseInt(TextyCoordinaat.getText().trim()); Kleur kleur = Kleur.valueOf((String) comboKleur.getSelectedItem()); Kleur kleurRand = Kleur.valueOf((String) comboKleurRand.getSelectedItem()); int dikteRand = (int) SpinDikteRand.getValue(); double grootte = Double.parseDouble(Textgrootte.getText().trim()); if (cirkelRadioButton.isSelected()) { Cirkel cirkel = new Cirkel(new Punt(x, y), grootte, kleur, kleurRand, dikteRand); outputLijst.add(cirkel.toString()); System.out.println("cirkel!!!"); } else if (vierkantRadioButton.isSelected()) { Vierkant vierkant = new Vierkant(new Punt(x, y), grootte, kleur, kleurRand, dikteRand); outputLijst.add(vierkant.toString()); System.out.println("vierkant!!!"); } else { JOptionPane.showMessageDialog(FiguurGUI, "请选择圆形或正方形"); return; } TextOutput.setText(outputLijst.toString()); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(FiguurGUI, "输入格式错误,请检查坐标、尺寸等数值输入"); } catch (IllegalArgumentException ex) { JOptionPane.showMessageDialog(FiguurGUI, ex.getMessage()); } } }); } public static void main(String[] args) { JFrame frame = new JFrame("FiguurGUI"); frame.setContentPane(new FiguurGUI().FiguurGUI); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(740, 440); frame.setVisible(true); } }
额外说明
- 移除了类成员中提前初始化的变量,改为在事件方法内临时获取,避免组件未初始化的问题。
- 添加
try-catch块捕获异常,并通过弹窗提示用户错误信息,程序不会直接崩溃。 - 调整了单选按钮的判断逻辑为
else if,避免同时满足两个条件时执行两次逻辑。
内容的提问来源于stack exchange,提问作者Simon Devisch
相关产品推荐
相关产品推荐

