NetBeans11.2中Java JFrame类变量赋值后跨类实例化打印异常
问题分析与解决方案
你的问题根源在于错误地将Swing组件声明为静态变量,并且在调用时创建了新的test实例,导致原有窗体的文本框状态被重置。让我一步步拆解问题并给出修复方案:
为什么会出现这种情况?
看你的test类代码,AFileTextField被声明为static:
private static javax.swing.JTextField AFileTextField;
同时getAtext()也是静态方法:
public static String getAtext(){ return AFileTextField.getText(); }
静态变量属于类本身,所有test实例共享同一个AFileTextField。当你在SomeFunccall()里执行new test()时,新实例的initComponents()方法会重新初始化这个静态的AFileTextField,把它的文本重置为默认值"jTextField1"(也就是你说的"File Path")。这就导致后续无论是静态调用test.getAtext()还是新实例调用,拿到的都是被重置后的默认值。
另外,创建新的test实例完全没必要——你已经有一个正在运行的窗体实例了,不需要再新建一个。
修复方案
我们需要做三个关键修改:
1. 移除组件和方法的static修饰符
Swing组件是属于窗体实例的,不应该是静态的。把AFileTextField和getAtext()的static去掉:
// 去掉static private javax.swing.JTextField AFileTextField; // 改为实例方法 public String getAtext(){ return AFileTextField.getText(); }
2. 将当前test实例传递给B类的方法
不要在OKBtnMouseClicked里创建新的B实例后直接调用SomeFunccall(),而是把当前的test窗体实例传进去,这样B类就能访问到正确的那个窗体的文本内容:
修改test类里的按钮点击事件:
private void OKBtnMouseClicked(java.awt.event.MouseEvent evt) { if(evt.getSource() == OKBtn){ // 把当前窗体实例this传递给B的方法 new B().SomeFunccall(this); } }
3. 修改B类的方法,接收test实例并调用实例方法
更新B类的SomeFunccall方法,接收test实例,然后调用它的实例方法getAtext():
public class B { public void SomeFunccall(test currentTestFrame) { // 直接使用传入的当前窗体实例获取文本 System.out.println(currentTestFrame.getAtext()); // 不要再创建新的test实例! // test tc = new test(); // 删掉这行 // System.out.println(tc.getAtext()); // 删掉这行 System.out.println(currentTestFrame.getAtext()); } }
修正后的完整代码
test类
package com.mycompany.test; import java.io.File; import javax.swing.JFileChooser; public class test extends javax.swing.JFrame { public test() { initComponents(); } @SuppressWarnings("unchecked") private void initComponents() { BrowseABtn = new javax.swing.JButton(); OKBtn = new javax.swing.JButton(); AFileTextField = new javax.swing.JTextField(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); BrowseABtn.setText("jButton1"); BrowseABtn.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { BrowseABtnMouseClicked(evt); } }); OKBtn.setText("jButton2"); OKBtn.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { OKBtnMouseClicked(evt); } }); AFileTextField.setText("jTextField1"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(157, 157, 157) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(AFileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(OKBtn) .addComponent(BrowseABtn))) .addContainerGap(172, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(55, 55, 55) .addComponent(BrowseABtn) .addGap(18, 18, 18) .addComponent(AFileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(51, 51, 51) .addComponent(OKBtn) .addContainerGap(115, Short.MAX_VALUE)) ); pack(); } private void BrowseABtnMouseClicked(java.awt.event.MouseEvent evt) { if(evt.getSource() == BrowseABtn){ JFileChooser fc = new JFileChooser(""); int returnVal = fc.showOpenDialog(BrowseABtn); if(returnVal == JFileChooser.APPROVE_OPTION){ File file = fc.getSelectedFile(); AFileTextField.setText(file.getPath()); AFileTextField.setEditable(false); } } } private void OKBtnMouseClicked(java.awt.event.MouseEvent evt) { if(evt.getSource() == OKBtn){ new B().SomeFunccall(this); } } // 改为实例方法,去掉static public String getAtext(){ return AFileTextField.getText(); } public static void main(String args[]) { try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(test.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(test.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(test.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(test.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } java.awt.EventQueue.invokeLater(() -> { new test().setVisible(true); }); } // 去掉static修饰符 private javax.swing.JTextField AFileTextField; private javax.swing.JButton BrowseABtn; private javax.swing.JButton OKBtn; }
B类
package com.mycompany.test; public class B { public void SomeFunccall(test currentTestFrame) { System.out.println(currentTestFrame.getAtext()); // 现在会打印正确的选中文件路径 // 移除创建新test实例的代码,避免重置状态 System.out.println(currentTestFrame.getAtext()); // 同样打印正确路径 } }
总结
- 永远不要把Swing组件声明为静态变量,每个窗体实例应该拥有自己的组件实例
- 当需要在其他类中访问当前窗体的状态时,直接传递当前窗体实例,而不是新建一个
- 实例方法用于访问实例的状态,静态方法只用于和类本身相关的操作
内容的提问来源于stack exchange,提问作者Kung Pao
相关产品推荐
相关产品推荐

