ImageIcon медленно в ListCellRenderer
-
28-10-2019 - |
Вопрос
У меня есть код class GridPanel extends JPanel
со статическим внутренним классом ToolSelectComboBox extends JComboBox
, который, в свою очередь, имеет два статических внутренних класса ToolSelectComboBoxModel implements ComboBoxModel
и ToolSelectComboBoxRenderer implements ListCellRenderer
. На панели отображается код ToolSelectComboBox
(TSCB), конструктор которого устанавливает его модель и средство визуализации как созданные мной пользовательские. Блок создан правильно, его модели и рендеры работают правильно.
Однако метод getListCellRendererComponent(...)
средства визуализации использует код ImageIcon
в возвращаемом коде JLabel
. Значок загружен правильно, но, когда я в первый раз щелкаю поле со списком (при каждом запуске), изображение загружается ровно (или, по крайней мере, очень близко к) чуть больше секунды. . Я бы предположил, что это некоторое отставание в загрузке файла, за исключением того, что
- Это файл размером 4 КБ в моей локальной файловой системе.
- Когда я добавляю команды
System.out.println
до и после командыresult.setIcon(...)
, они почти мгновенно следуют друг за другом.
Странная вещь, которую я заметил, заключается в том, что команды println
запускаются дважды : один раз, когда я щелкаю поле, и еще раз, когда загружается значок.
Также стоит отметить, что, поскольку он предназначен для работы с несколькими классами, которые переопределяют один метод родительского абстрактного класса (для создания пути к значку), когда я заметил, что это работает медленно, я изменил код от простого извлечения значка с помощью команды getIcon
до сохранения значков различного размера (в квадрате 16, 32 и 64 пикселей) в коде TreeMap<Tool.ImageSize, ImageIcon>
(где Tool
- это созданный мной интерфейс с методом ImageIcon getIcon()
.
Весь мой импорт в порядке.
Любая помощь приветствуется!
Прошу прощения, если я опубликовал слишком много кода, но я хотел убедиться, что он понятен. С другой стороны, если вам потребуется больше кода для понимания, не стесняйтесь спрашивать.
Код (все строки, начинающиеся с "*
" и содержащие текст в виде комментариев, являются свернутыми тегами JavaDoc, а не просто испорченным кодом):
У класса CircleTool
есть только один метод (для переопределения абстрактного метода AbstractTool
для получения изображения path ) и, поскольку метод работает (он получает путь нормально, это просто значок, который загружается медленно) , Я не включил этот класс.
Класс AbstractTool
:
Решение
но при первом щелчке по полю со списком (при каждом запуске) загрузка изображения занимает чуть больше секунды. Я бы предположил, что это некоторое отставание в загрузке файла
Это тоже мое предположение.
<цитата>за исключением того, что когда я добавляю команды System.out.println до и после команды result.setIcon (...), они почти мгновенно следуют друг за другом
Когда вы нажимаете на поле со списком, весь код запускается в EDT, что означает, что каждый значок будет загружаться последовательно.
Однако System.out.println () работает в отдельном потоке, поэтому он отображается немедленно.
Решение - загружать значки при запуске программы. То есть всякий раз, когда вы определяете / добавляете значки на свою карту, вы должны прочитать их в это время. Вы можете сделать это в отдельном потоке, чтобы не блокировать отображение графического интерфейса.
Изменить:
Вот простой SSCCE, который отображает значки в поле со списком:
родовое словоЕсли вам нужна дополнительная помощь, вы должны опубликовать свой SSCCE , демонстрирующий проблему.