【发布时间】:2011-09-11 17:15:58
【问题描述】:
我有一个class GridPanel extends JPanel,带有一个静态内部类ToolSelectComboBox extends JComboBox,它又具有两个静态内部类ToolSelectComboBoxModel implements ComboBoxModel 和ToolSelectComboBoxRenderer implements ListCellRenderer。面板显示ToolSelectComboBox (TSCB),其构造函数将其模型和渲染器设置为我创建的自定义模型。盒子创建正确,其模型和渲染器工作正常。
但是,渲染器的getListCellRendererComponent(...) 方法在它返回的JLabel 上使用ImageIcon。图标已正确加载,但是,当我第一次单击组合框(每次运行时)时,图像需要 完全(或至少非常接近) 超过一秒的时间来加载.我会假设这是加载文件的一些延迟,除了
- 这是我本地文件系统上的一个 4kB 文件
- 当我在
result.setIcon(...)命令之前和之后添加System.out.println命令时,它们几乎立即相互跟随。
我注意到的奇怪之处在于println 命令被触发两次,一次是在我单击框时触发,另一次是在图标加载时触发。
还可能值得注意的是,由于它旨在与覆盖父抽象类的单个方法的多个类一起使用(以生成图标的路径),当我注意到它工作缓慢时,我改变了代码从简单地使用 getIcon 命令检索图标到将各种大小的图标(16、32 和 64 px 平方)存储在 TreeMap<Tool.ImageSize, ImageIcon> 中(其中 Tool 是我创建的具有 ImageIcon getIcon() 的界面方法。
我所有的导入都井井有条。
任何帮助将不胜感激!
如果我发布了太多代码,我深表歉意,但我想确保它是可以理解的。另一方面,如果您需要更多代码才能理解,请不要犹豫。
代码(所有以“*”开头并带有类似注释文本的行都是折叠的 JavaDoc 标记,而不仅仅是乱码):
public class GridPanel extends JPanel {
public static class ToolSelectComboBox extends JComboBox {
// Combo box model `ToolSelectComboBoxModel` snipped
* A renderer for the {@link ToolSelectComboBoxModel}. This may
public static class ToolSelectComboBoxRenderer implements
ListCellRenderer {
* The default renderer. Only the icon and text are modified.
protected DefaultListCellRenderer d = new DefaultListCellRenderer();
@Override
public Component getListCellRendererComponent(final JList list,
final Object value, final int index,
final boolean isSelected, final boolean cellHasFocus) {
if (!ToolSelectComboBoxModel.class.isInstance(list.getModel())) {
throw new IllegalStateException(
"Cannot use a ToolSelectComboBoxRenderer on any list model type other than ToolSelectComboBoxModel.");
}
final JLabel result = (JLabel) d.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
result.setText(null);
if (value != null) {
result.setIcon(((Tool) value)
.getIcon(Tool.IconSize.SIZE_32PX));
}
return result;
}
}
public ToolSelectComboBox() {
setModel(new ToolSelectComboBoxModel());
((ToolSelectComboBoxModel) getModel()).add(new CircleTool()); // shown below
setRenderer(new ToolSelectComboBoxRenderer());
}
}
* Create the panel.
public GridPanel() {
setLayout(new BorderLayout(0, 0));
final ToolSelectComboBox toolSelectComboBox = new ToolSelectComboBox();
add(toolSelectComboBox, BorderLayout.NORTH);
final SquareGrid squareGrid = new SquareGrid(); // another class; this works fine
add(squareGrid, BorderLayout.CENTER); // irrelevant to problem
}
}
CircleTool 类只有一种方法(覆盖AbstractTool 的抽象方法以获取图像path),并且由于该方法有效(它可以很好地获取路径,它只是加载缓慢的图标),我没有包含这个类。
AbstractTool 类:
public abstract class AbstractTool implements Tool {
/**
* A {@link TreeMap} to map the icon sizes to their icons.
*/
protected final TreeMap<Tool.IconSize, ImageIcon> map = new TreeMap<Tool.IconSize, ImageIcon>();
/**
* Constructs the tool and sets up the {@linkplain #map}.
*/
public AbstractTool() {
for (final Tool.IconSize size : Tool.IconSize.values()) {
System.out.println("Putting value for " + size);
map.put(size,
new ImageIcon(Tool.class.getResource(getImagePath(size))));
}
}
@Override
public ImageIcon getIcon(final IconSize size) {
return map.get(size);
}
/**
* Gets the image path for the given image size.
*
* @param size
* the size
* @return the image path
*/
protected abstract String getImagePath(Tool.IconSize size);
}
【问题讨论】:
标签: java performance jcombobox imageicon listcellrenderer