我的用例如下:我想要一个组合框,它在每次打开时刷新的目录中显示过滤的文件列表。我还希望组合框中显示的字符串是没有目录或扩展名的文件名(它们是我不想向用户公开的实现细节)。
我已经实现了ComboBoxModel
如下:
public class XMLComboModel extends DefaultComboBoxModel<Path> implements PopupMenuListener {
public static final String EXT = ".xml";
private final Path directory;
public XMLComboModel(String pathName) {
this.directory = Paths.get(pathName);
populateModel();
}
public Path getSelectedPath() {
return (Path) getSelectedItem();
}
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
populateModel();
}
private void populateModel() {
removeAllElements();
try {
Files.newDirectoryStream(directory, "*" + EXT).forEach(this::addElement);
if (getSelectedPath() != null) {
for (int i = 0; i < getSize(); i++) {
if (getElementAt(i).compareTo(getSelectedPath()) == 0)
setSelectedItem(getElementAt(i));
}
}
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
PopupMenuListener
为了清楚起见,我省略了一些方法。
这工作正常,只是它在组合框中显示完整路径,这不是我想要的。我认为定制路径显示的最简单方法是定制渲染器。我尝试了这个:
comboBox.setRenderer(new BasicComboBoxRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
Path path = (Path) value;
String fileName = path.getFileName().toString().replace(EXT, "");
Component component = super.getListCellRendererComponent(list, fileName, index,
isSelected, cellHasFocus);
return component;
}
});
不幸的是,这不起作用。它正确显示截断的文件名,但现在setSelectedItem
使用 theString
而不是 the Path
- 这有道理但不会匹配模型中的路径。
我的选择似乎是:
BasicComboBoxRenderer
标签中的文本以外的功能。setSelectedItem
在模型中覆盖以查找具有给定文件名的路径。其中第二个更容易实现:
@Override
public void setSelectedItem(Object item) {
for (int i = 0; i < getSize(); i++) {
if (super.getElementAt(i).equals(Paths.get(item.toString()))) {
super.setSelectedItem(super.getElementAt(i));
return;
}
}
}
但这似乎很笨重,因为我已经Path
从模型中传递了一个,最好能Path
回来。我是否缺少一种更简单的方法来实现这一目标?
但现在使用字符串而不是路径调用 setSelectedItem
渲染器与组合框模型的其他方法无关。
如果要将Path
对象传递给setSelectedItem(...)
方法,则需要确保Path
对象实现该equals(...)
方法,以便模型可以选择正确的Path
.
然后只需创建自定义渲染器来显示Path
您想要显示的对象的任何部分。
找回 Path 就好了。
如果您的模型包含 Path 对象,则该getSelectedItem()
方法将返回一个 Path 对象。您需要将其转换为路径,或使用您的getSelectedPath()
方法。
所以你不需要覆盖 DefaultComboBoxModel 的任何方法,只需要添加getSelectedPath()
方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句