Java GUI中按Rank排序GuitarTab对象及导航搜索问题排查
问题修复方案
一、排序算法修复
原sortRnkLwToHi存在语法错误、逻辑冗余和UI干扰问题,修复后的代码如下:
// 按rank从低到高排序,仅负责排序逻辑,不处理UI public void sortRnkLwToHi() { // 直接使用类内的myTablatures数组,无需参数传递 int hiSubscript = numberEntries - 1; // 用实际条目数,而非数组长度,避免空元素干扰 for (int a = 0; a < hiSubscript; a++) { // 冒泡排序优化:每轮后末尾a个元素已排好序,无需再比较 for (int b = 0; b < hiSubscript - a; b++) { // 比较相邻元素的rank,交换位置 if (myTablatures[b].rank > myTablatures[b + 1].rank) { GuitarTab temp = myTablatures[b]; myTablatures[b] = myTablatures[b + 1]; myTablatures[b + 1] = temp; } } } // 排序完成后重置当前导航位置到第一个条目 currentTabEntry = 1; shwEntry(currentTabEntry); }
修复点说明:
- 移除第二个for循环后的多余分号,确保比较逻辑在循环内执行
- 去掉方法参数的冗余赋值,直接使用类内维护的
myTablatures数组 - 用实际条目数
numberEntries替代数组长度,避免数组中空元素引发空指针 - 优化冒泡排序的内层循环边界,减少无效比较
- 排序过程中不再触发UI刷新,仅在排序完成后统一刷新第一个条目
二、导航逻辑调整
要实现“启用排序时按rank顺序导航”的需求,需区分原顺序和排序后的顺序,建议维护一个导航用的索引列表:
- 新增两个成员变量:
private List<Integer> navigationIndices; // 存储导航用的数组索引 private boolean isSortedMode = false; // 标记是否启用排序模式
- 初始化导航索引列表:
// 在初始化或新增条目后调用 private void initNavigationIndices() { navigationIndices = new ArrayList<>(); for (int i = 0; i < numberEntries; i++) { navigationIndices.add(i); } }
- 排序时更新导航索引列表(替代直接修改原数组,避免破坏原插入顺序):
public void sortRnkLwToHi() { initNavigationIndices(); // 按rank排序索引列表 Collections.sort(navigationIndices, (i1, i2) -> Integer.compare(myTablatures[i1].rank, myTablatures[i2].rank) ); isSortedMode = true; currentTabEntry = 1; shwEntry(currentTabEntry); }
- 修改导航按钮的事件逻辑(以nextBtn为例):
public void nextBtnActionPerformed(ActionEvent e) { if (currentTabEntry >= numberEntries) { return; // 已经是最后一个条目,不操作 } currentTabEntry++; // 根据是否启用排序,获取对应的数组索引 int actualIndex = isSortedMode ? navigationIndices.get(currentTabEntry - 1) : currentTabEntry - 1; shwEntryByIndex(actualIndex); } // 新增按索引显示条目的方法,替代原shwEntry(int entryNum) private void shwEntryByIndex(int index) { GuitarTab tab = myTablatures[index]; tabNameFld.setText(tab.tabName); eTxtFld.setText(tab.eString); bTxtFld.setText(tab.bString); gTxtFld.setText(tab.gString); dTxtFld.setText(tab.dString); aTxtFld.setText(tab.aString); lowETxtFld.setText(tab.lowEString); rankFld.setText(String.valueOf(tab.rank)); }
- 复选框切换排序模式的逻辑:
public void sortCheckboxActionPerformed(ActionEvent e) { JCheckBox checkbox = (JCheckBox) e.getSource(); isSortedMode = checkbox.isSelected(); if (isSortedMode) { sortRnkLwToHi(); } else { initNavigationIndices(); // 恢复原顺序 currentTabEntry = 1; shwEntry(currentTabEntry); } }
三、搜索无响应问题排查与修复
搜索无响应通常是事件绑定缺失或搜索逻辑错误导致:
- 检查搜索按钮的事件绑定:
确保在UI初始化时给searchBtn添加了ActionListener,例如:
searchBtn.addActionListener(this::searchBtnActionPerformed);
- 实现搜索逻辑(以按tabName模糊搜索为例):
public void searchBtnActionPerformed(ActionEvent e) { String searchKeyword = searchFld.getText().trim(); if (searchKeyword.isEmpty()) { return; } // 遍历所有条目,查找匹配项 for (int i = 0; i < numberEntries; i++) { GuitarTab tab = myTablatures[i]; if (tab.tabName.toLowerCase().contains(searchKeyword.toLowerCase())) { // 找到匹配项后显示,并更新当前导航位置 currentTabEntry = i + 1; if (isSortedMode) { // 如果是排序模式,找到该条目在导航列表中的位置 currentTabEntry = navigationIndices.indexOf(i) + 1; } shwEntryByIndex(i); return; // 找到第一个匹配项后显示,若要显示所有可改为收集列表 } } // 未找到匹配项的提示 JOptionPane.showMessageDialog(this, "未找到匹配的吉他谱"); }
额外优化点
原saveBtnActionPerformed中的数组插入逻辑存在bug,for (i = 0; i >= currentTabEntry + 1; i--)循环条件永远不成立,导致无法插入到正确位置,修复插入逻辑:
if (currentTabEntry <= numberEntries - 1) { // 从后往前移动元素,腾出插入位置 for (i = numberEntries - 1; i >= currentTabEntry; i--) { myTablatures[i] = myTablatures[i - 1]; } }
内容的提问来源于stack exchange,提问作者smouvfox805
相关产品推荐
相关产品推荐

