class GridPanel extends JPanel
静的内部クラスを持つToolSelectComboBox extends JComboBox
、があり、これには2つの静的内部クラスToolSelectComboBoxModel implements ComboBoxModel
とがありToolSelectComboBoxRenderer implements ListCellRenderer
ます。パネルにはToolSelectComboBox
(TSCB)が表示され、そのコンストラクターはモデルとレンダラーを私が作成したカスタムのものに設定します。ボックスは正しく作成され、そのモデルとレンダラーは正しく機能します。
ただし、レンダラーのgetListCellRendererComponent(...)
メソッドは、それが返すImageIcon
onを使用します。JLabel
アイコンは正しく読み込まれますが、(実行ごとに)コンボボックスを初めてクリックすると、画像の読み込みに1秒強かかります(または少なくとも非常に近くなります) 。これはファイルのロードに多少の遅れがあると思いますが、
- これは私のローカルファイルシステム上の4kBファイルです
System.out.println
コマンドの前後にコマンドを追加するとresult.setIcon(...)
、それらはほぼ瞬時に相互に続きます。
私が気付いた奇妙なことは、println
コマンドが2回起動されることです。1回はボックスをクリックしたとき、もう1回はアイコンが読み込まれたときです。
これは、親抽象クラスの単一のメソッドをオーバーライドする複数のクラスで動作するように設計されているため(アイコンへのパスを生成するため)、動作が遅いことに気付いたときに、コードを次のように変更したことにも注意してください。getIcon
さまざまなサイズのアイコン(16、32、および64ピクセルの2乗)を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
}
}
このクラスにはメソッドが1つしかなく(の抽象メソッドCircleTool
をオーバーライドして画像パスを取得する)、メソッドが機能するため(パスが正常に取得されるため、読み込みが遅いアイコンにすぎません)、このクラスは含めていません。AbstractTool
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);
}