Java JTable加载异常:View中创建为空,Main中可正常显示
问题分析与解决方案
首先,咱们直接揪出问题的核心:View构造方法执行的时机,早于你填充Bank数据的时机。
看你的Main代码:
View view = new View(); // 这里先创建View,会立刻执行View的构造方法 Bank b = new Bank(); // 这里才开始添加Person到Bank里 Person p = new Person("Name","Prenume", "id"); Person p1 = new Person("Name2","Prenume2", "id2"); b.addPerson(p); b.addPerson(p1); // 这时候才重新给view的personTbl赋值,用已经有数据的map view.personTbl = view.tablePers(b.mapper);
而View的构造方法里,你直接调用了personTbl = tablePers(b.mapper)——这时候b要么根本没初始化(会报空指针),要么b.mapper还是个空的HashMap,自然表格加载不到数据。而Main里后续重新赋值的表格才是有数据的,但构造时已经把空表格加到窗口里了,所以你看到的是空表。
解决方案1:给View添加一个初始化表格的方法,延迟加载数据
修改View类,去掉构造里的表格初始化逻辑,改成一个公开方法:
public class View { // 保留你的其他成员变量定义 JTable personTbl; JScrollPane sp; JFrame personFrame; JPanel persBtnsPan; JButton addPerson, editPerson, viewP; JFrame viewPers; JPanel viewPersPan; public View() { personFrame = new JFrame("Person"); personFrame.setLayout(new BorderLayout()); personFrame.setSize(400, 400); persBtnsPan = new JPanel(); viewPers = new JFrame("View Pers"); viewPers.setLayout(new BorderLayout()); viewPers.setSize(400, 400); viewPersPan = new JPanel(); // 只初始化按钮和窗口布局,不创建表格 addPerson = new JButton("add"); editPerson = new JButton("edit"); viewP = new JButton("view"); persBtnsPan.add(addPerson); persBtnsPan.add(editPerson); persBtnsPan.add(viewP); personFrame.add(persBtnsPan, BorderLayout.NORTH); // 先留空,等数据准备好再添加表格 } // 新增这个方法,用来在数据准备好后初始化表格 public void initPersonTable(HashMap<Person, ArrayList<Account>> map) { personTbl = tablePers(map); sp = new JScrollPane(personTbl); personFrame.add(sp, BorderLayout.CENTER); // 刷新窗口布局,确保表格显示 personFrame.revalidate(); personFrame.repaint(); } // 保留你的tablePers方法 public static <T> JTable tablePers(HashMap<Person, ArrayList<Account>> map) { DefaultTableModel model = new DefaultTableModel( new Object[] { "Nume", "Prenume", "CNP" }, 0); for (HashMap.Entry<Person, ArrayList<Account>> entry : map.entrySet()) { model.addRow(new Object[] { entry.getKey().getNume(), entry.getKey().getPrenume(), entry.getKey().getCnp() }); } return new JTable(model); } }
然后修改Main类,在数据填充完后调用这个方法:
public class App { public static void main( String[] args ) { View view = new View(); Bank b = new Bank(); Person p = new Person("Name","Prenume", "id"); Person p1 = new Person("Name2","Prenume2", "id2"); b.addPerson(p); b.addPerson(p1); // 数据准备好后,调用View的方法初始化表格 view.initPersonTable(b.mapper); view.personFrame.setVisible(true); } }
解决方案2:让View的构造方法接收已填充的HashMap(或Bank对象)
如果你希望View构造时就直接有表格,可以修改构造方法,让外部传入已经准备好的数据:
public class View { // 保留你的成员变量定义 JTable personTbl; JScrollPane sp; JFrame personFrame; JPanel persBtnsPan; JButton addPerson, editPerson, viewP; JFrame viewPers; JPanel viewPersPan; public View(HashMap<Person, ArrayList<Account>> personMap) { personFrame = new JFrame("Person"); personFrame.setLayout(new BorderLayout()); personFrame.setSize(400, 400); persBtnsPan = new JPanel(); viewPers = new JFrame("View Pers"); viewPers.setLayout(new BorderLayout()); viewPers.setSize(400, 400); viewPersPan = new JPanel(); addPerson = new JButton("add"); editPerson = new JButton("edit"); viewP = new JButton("view"); persBtnsPan.add(addPerson); persBtnsPan.add(editPerson); persBtnsPan.add(viewP); personFrame.add(persBtnsPan, BorderLayout.NORTH); // 现在传入的map已经有数据了,直接创建表格 personTbl = tablePers(personMap); sp = new JScrollPane(personTbl); personFrame.add(sp,BorderLayout.CENTER); } // 保留tablePers方法... public static <T> JTable tablePers(HashMap<Person, ArrayList<Account>> map) { DefaultTableModel model = new DefaultTableModel( new Object[] { "Nume", "Prenume", "CNP" }, 0); for (HashMap.Entry<Person, ArrayList<Account>> entry : map.entrySet()) { model.addRow(new Object[] { entry.getKey().getNume(), entry.getKey().getPrenume(), entry.getKey().getCnp() }); } return new JTable(model); } }
然后Main类里先准备好数据,再创建View:
public class App { public static void main( String[] args ) { Bank b = new Bank(); Person p = new Person("Name","Prenume", "id"); Person p1 = new Person("Name2","Prenume2", "id2"); b.addPerson(p); b.addPerson(p1); // 先准备好数据,再传入View构造 View view = new View(b.mapper); view.personFrame.setVisible(true); } }
额外注意点
- 你的View类里原来的
b变量应该是没有初始化的,直接调用b.mapper会抛出NullPointerException,这也是构造时表格为空的潜在原因之一。 - 尽量避免在构造方法里做过多的业务逻辑或依赖外部未初始化的数据,把数据加载和UI初始化分开,会让代码更健壮、更容易维护。
内容的提问来源于stack exchange,提问作者Siespi
相关产品推荐
相关产品推荐

