本文介绍在java swing应用中,当外部文件(如.txt或.procesador)动态增删时,如何让textautocompleter自动刷新建议列表,避免重启窗口才能生效的问题。核心在于避免一次性初始化,改用按需/事件驱动方式重载数据源。
在您当前的代码中,procesadorlistado 数组仅在 Registrar 构造方法中初始化一次:
File contenedorpro = new File(ubicacionpro); File[] procesadorlistado = contenedorpro.listFiles(); // ❌ 仅执行一次,后续变化不感知
因此,即使用户新增或删除 .procesador 文件,AutocompletarProcesador 始终持有旧快照,导致自动完成项“滞后”。
推荐两种稳定、低侵入的解决方案(任选其一):
在文本框 TProcesador1 获取焦点时重新扫描目录并重建自动完成器:
private void setupAutoCompleterOnFocus() {
TProcesador1.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
refreshAutoCompleter();
}
});
}
private void refreshAutoCompleter() {
String barra = File.separator;
String ubicacionpro = System.getProperty("user.dir") + barra + "Procesador" + barra;
File contenedorpro = new File(ubicacionpro);
if (!contenedorpro.exists() || !contenedorpro.isDirectory()) return;
File[] archivos = contenedorpro.listFiles((dir, name) -> name.toLowerCase().endsWith(".procesador"));
if (archivos == null) archivos = new File[0];
// ✅ 安全重建:先清空,再添加新项
AutocompletarProcesador.removeAllItems();
for (File f : archivos) {
String itemName = f.getName().replace(".procesador", "");
AutocompletarProcesador.addItem(itemName);
}
}并在 initComponents() 后调用:
public Registrar() {
initComponents();
setLocationRelativeTo(this);
setupAutoCompleterOnFocus(); // ✅ 注册焦点监听
refreshAutoCompleter(); // ✅ 首次加载(替代原 AutocompleterReg)
}? 优势:无需定时轮询,无性能开销;用户每次开始输入前已确保数据最新;完全兼容方向键选择、回车确认等交互逻辑。
若需毫秒级响应(如后台服务持续写入),可启用 Java NIO 的文件系统监听:
private WatchService watchService;
private void startDirectoryWatcher() {
try {
watchService = FileSystems.getDefault().newWatchService();
Path path = Paths.get(System.getProperty("user.dir"), "Procesador");
path.register(watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
// 启动监听线程(注意:应在非EDT线程中运行)
new Thread(() -> {
while (true) {
WatchKey key;
try {
key = watchService.take(); // 阻塞等待事件
} catch (InterruptedException e) { break; }
for (WatchEvent> event : key.pollEvents()) {
if (event.context() instanceof Path p &&
p.toString().toLowerCase().endsWith(".procesador")) {
SwingUtilities.invokeLater(this::refreshAutoCompleter); // 切回EDT更新UI
}
}
key.reset();
}
}, "ProcesadorWatcher").start();
} catch (IOException e) {
e.printStackTrace();
}
}⚠️ 注意事项:
✅ 总结:不要“静态缓存文件列表”,而要“动态获取+安全重建”。方案一足以覆盖绝大多数桌面应用场景,简洁、可靠、零副作用。