Java Swing如何在删除数据后无需重建即可刷新JDialog内容
解决方案
第一步:修改自定义JDialog(MyFavoriteCoctails类)
把盛放鸡尾酒卡片的面板提取为成员变量,新增独立的刷新方法,复用列表渲染逻辑,不需要每次更新都重建整个弹窗:
public class MyFavoriteCoctails extends JDialog { // 把盛放鸡尾酒的面板提为成员变量 private JPanel panelForCocktails; private JFrame myFrame; public MyFavoriteCoctails(JFrame myFrame) { this.myFrame = myFrame; setLocationRelativeTo(myFrame); maker(); } private void maker() { setModal(true); setTitle("My Favorite Cocktails"); setResizable(false); setLayout(new BorderLayout()); // 顶部固定标题区域只初始化一次,无需重复渲染 JPanel panelOnTop = new JPanel(new BorderLayout()); JLabel favCocktailLabel = new JLabel("My Favorite Cocktails"); favCocktailLabel.setFont(new Font("Sans Serif", Font.PLAIN, 150)); favCocktailLabel.setForeground(Color.red); panelOnTop.setBorder(BorderFactory.createMatteBorder(5, 5, 5, 5, Color.red)); panelOnTop.add(favCocktailLabel, BorderLayout.CENTER); panelOnTop.setBackground(Color.white); this.add(panelOnTop, BorderLayout.NORTH); // 初始化列表容器 panelForCocktails = new JPanel(); this.add(panelForCocktails, BorderLayout.CENTER); // 首次加载列表 refresh(); pack(); } // 新增刷新列表的公共方法,删除数据后直接调用即可更新界面 public void refresh() { // 清空原有所有鸡尾酒卡片 panelForCocktails.removeAll(); // 重新加载最新的收藏列表 List<Coctail> list = SingleObject.getfavCoctailList(); int row; if ((list.size() % 5) != 0) { row = list.size() / 5 + 1; } else { row = list.size() / 5; } panelForCocktails.setLayout(new GridLayout(row, 5)); for (int i = 0; i < list.size(); i++) { panelForCocktails.add(new CocktailJPanelForFavorites(list.get(i).getId(), list.get(i).getImg(), list.get(i).getName(), list.get(i), this, myFrame)); } // 触发容器重新计算布局+重绘,让改动实时显示 panelForCocktails.revalidate(); panelForCocktails.repaint(); // 调整弹窗大小适配更新后的内容 pack(); } }
第二步:修改删除事件监听逻辑(DeleteFavorite类)
删除原有销毁旧弹窗、新建弹窗的代码,直接调用弹窗的刷新方法即可:
@Override public void actionPerformed(ActionEvent e) { SingleObject obj = SingleObject.getInstance(); List<Coctail> list = SingleObject.getfavCoctailList(); List<Coctail> favcoctailList = list; int len = favcoctailList.size(); if (favcoctailList != null) { for (int i = 0; i < len; i++) { if ((favcoctailList.get(i).getId().toString().trim().equals(coctail.getId().toString().trim()))) { favcoctailList.remove(i); break; } } } System.out.println(favcoctailList); obj.make(favcoctailList); // 直接调用刷新方法,无需销毁重建弹窗 ((MyFavoriteCoctails)dialog).refresh(); }
实现原理
- Swing容器内的组件发生增删后,必须调用
revalidate()触发容器重新计算布局、repaint()触发界面重绘,改动才能实时显示在界面上 - 把列表渲染逻辑抽为独立的
refresh方法,复用固定的弹窗结构,仅更新动态变化的列表区域,性能更高、体验更流畅
内容的提问来源于stack exchange,提问作者Tzonatan Rotsi
相关产品推荐
相关产品推荐

