У меня есть class GridPanel extends JPanel
со статическим внутренним классом ToolSelectComboBox extends JComboBox
, который в свою очередь имеет два статических внутренних класса ToolSelectComboBoxModel implements ComboBoxModel
и ToolSelectComboBoxRenderer implements ListCellRenderer
.На панели отображается ToolSelectComboBox
(TSCB), конструктор которого устанавливает свою модель и средство визуализации в качестве созданных мной пользовательских.Ящик создан правильно, и его модели и средства визуализации работают правильно.
Однако метод Renderer getListCellRendererComponent(...)
использует ImageIcon
для JLabel
, который он возвращает.Значок загружен правильно, но при первом нажатии на поле со списком (при каждом запуске) для изображения требуется точно (или, по крайней мере, очень близко к) , чуть больше секунды для загрузки.Я бы предположил, что это некоторая задержка в загрузке файла, за исключением того, что
- Это файл размером 4 КБ в моей локальной файловой системе
- Когда я добавляю команды
System.out.println
до и послеresult.setIcon(...)
, они следуют друг за другом почти мгновенно.
Странно, что я замечаю, что команды println
запускаются дважды , один раз, когда я нажимаюи снова при загрузке иконки.
Также стоит отметить, что это разработано для работы с несколькими классами, которые переопределяют один метод родительского абстрактного класса (для генерации пути к иконке).Когда я заметил, что это работает медленно, я изменил код с простого извлечения значка с помощью команды getIcon
на хранение значков различных размеров (16, 32 и 64 px в квадрате) в TreeMap<Tool.ImageSize, ImageIcon>
(где * 1030)* это интерфейс, который я создал и который имеет метод 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);
}