class GridPanel extends JPanel
の静的内部クラスToolSelectComboBox extends JComboBox
があります.2つの静的内部クラスToolSelectComboBoxModel implements ComboBoxModel
とToolSelectComboBoxRenderer implements ListCellRenderer
があります。パネルにはToolSelectComboBox
(TSCB)が表示され、そのコンストラクタはモデルを設定し、レンダラーは作成したカスタムモデルになります。ボックスは正しく作成され、モデルとレンダラーは正しく動作します。ListCellRendererのImageIconが遅い
ただし、レンダラーのgetListCellRendererComponent(...)
メソッドは、返されるJLabel
のImageIcon
を使用します。アイコンは正しくロードされますが、最初にコンボボックスをクリックすると、が正確に(または少なくとも非常に近くに)より少し遅れて読み込まれます。私はresult.setIcon(...)
コマンドの前と後のSystem.out.println
コマンドを追加すると、彼らはお互いに従ってください
- 除いそれは4kBのファイルで、このファイルのロード中にいくつかの遅れであることを前提としていますほぼ即座に。私は気づく
奇妙なことはprintln
コマンドは二回、かつて私は再びボックスをクリックし、アイコンの負荷を解雇されていることです。
親抽象クラスの単一のメソッドをオーバーライドする複数のクラスで動作するように設計されているので(iconへのパスを生成するために)、これがゆっくりと動作していることに気付いたとき、 TreeMap<Tool.ImageSize, ImageIcon>
(Tool
私はそれがImageIcon getIcon()
方法を有し作成インタフェースである。
すべてに単にgetIcon
コマンドでアイコンを検索から様々なサイズのアイコン格納するコードを変更した(16、32、及び64 PXは二乗)私の輸入品は順番にあります。
何か助けていただければ幸いです!
あまりにも多くのコードを投稿した場合はお詫び申し上げますが、わかりやすくしたいと思っていました。一方、理解するためにより多くのコードが必要な場合は、お気軽にお問い合わせください。
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
クラスが唯一持っている一つの方法(オーバーライドへ:
コード(コメントのようなテキストを「*
」で始まり、持っているすべての行は、Javadocタグだけでなく、めちゃめちゃアップコードを折りたたまれ) 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);
}
お返事ありがとうございます!別のスレッドで実行されている 'println'コマンドについてあなたが言っていることは意味があります。私はそれを考えなかった。しかし、イベントディスパッチスレッドは何ですか?ウィキペディアの記事は私には分かりません。私はかなりJavaに慣れていません(そしてC++には慣れていますが、これは私が聞いたことは転送の面倒です)ので、私の無知を赦してください。私は 'ImageIcon'を私の' TreeMap'に入れて、アイコンが自動的にロードされると仮定しました。これは当てはまりませんか?そうでない場合は、どうすればいいですか? 'loadImage()'は保護されています。 'getImage()'を使うべきですか? – wchargin
私は 'getImage()'を試しましたが、新しい 'Thread'内とデフォルトの' Thread'内の両方で遅延時間がまだ発生していました。私は何を提案しますか?私はただグラフィックスオブジェクトを作成し、それにアイコンをペイントする必要がありますか? – wchargin
はいImageIconを作成すると、画像がロードされるはずです。あなたのコードから、いつ、どのようにこれを行うのかは明らかではありません。ですから、GUIを作成して表示するとき、またはコンボボックスをクリックしたときにそれが起きるかどうかはわかりません。後者のようです。 EDTはEvent Dispatch Threadです。このスレッドでは、GUIに対するすべての更新が実行されます。詳細は、[同時実行の同時実行](http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html)を参照してください。 SSCCEには、プリロードされたときにアイコンが即座にレンダリングされることが示されています。 – camickr