4

SWT で色を動的に生成する必要がある場合があります。赤緑の異なる色で 0 ~ 1 のスコアを表示するビューの例を見てみましょう。異なる色の同様のビューが他にもある場合があります。

class ScoreView {
    private Canvas canvas;
    private List<Item> items = new ArrayList<Item>();

    public ScoreView(Composite parent) {
        canvas = new Canvas(parent, SWT.NONE);

        canvas.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent event) {
                GC gc = event.gc;

                int x = 0;
                for(Item item:items) {
                    int shade = (int)(item.getScore() * 255.0);

                    Color color = new Color(Display.getCurrent(), shade, 255-shade, 0);
                    gc.setBackground(color);
                    gc.fillRectangle(x, 0, 50, 50);
                    x += 50;
                }
            }
        });
    }

    public void setItems(List<Item> items) {
        this.items = items;
        canvas.redraw();
    }
}

SWT では、常にリソースを解放する必要があります。http://www.eclipse.org/articles/Article-SWT-Color-Model/swt-color-model.htmから:

色には、割り当てて解放する必要がある OS リソースが含まれています。このため、作成したすべての色を破棄する必要があります。

では、色を処分する最良の方法は何ですか?

http://www.eclipse.org/articles/swt-design-2/swt-design-2.htmlから:

ウィジェットでグラフィック リソースを使用している場合 (widget.setFont(font) など)、使用されているウィジェットが破棄されたときにこれらをクリーンアップするのが最善の方法であることが多いため、ウィジェットで破棄リスナーをフックできます。 .

そのため、割り当てたすべての色を追跡DisposeListenerし、キャンバスまたはシェルに配置できます。しかし、同じリンクから:

プログラムが終了すると、オペレーティング システムはプログラムのすべてのリソースを解放します。なぜこれだけに頼らないのですか?オペレーティング システムのリソースは無限ではありません。プログラムが不要になったリソースを解放しない場合、リソースが不足する可能性があります。また、他のプログラムのリソースが不足する可能性もあります。したがって、リソースを解放するためにプログラムが終了するまで待つことは、一般的には悪い考えです。

色は破棄されますが、終了時に破棄されるため、何も得られなかったようです(ビューはプログラムの存続期間中続きます)。

PaintListener色が表示されている間、それらはまだGCによって使用されているため、色を直接破棄できないと思います。使用されている色を覚えておき、次のペイント呼び出しでそれらを破棄する必要があります。その通話で再び使用されていませんか?

私がそれを管理したとしても、利用可能な色が数個しかない場合は、さらに別の問題があります. 色が割り当てられる順序のため、多くの赤の色合いをレンダリングした後、色が不足し、緑の色合いを表示できなくなりました。その場合、プログラムの開始時に必要になる可能性のある色の範囲を事前に割り当てたほうがよいでしょうか (パレットなど)。何個、どのような順序で割り当てる必要がありますか? それは、これらの色を決して処分しないことを意味します。

また、いつでも何色が利用できるかを知る方法はありますか? 他の実行中のプログラムは、利用可能な色の数を奪いますか?

4

3 に答える 3

5

Eclipse RCPは、グローバルColorRegistryを介してこれを処理します。

これを使用することで、アプリケーションの起動時にリソースを事前に割り当てる必要がなくなります。リソースが必要な場合は、グローバルレジストリにリソースを照会します。利用できない場合は、割り当ててグローバルレジストリに登録します。

private static final String SHADE = "shadedcolor";

Color color = null;
if (!JFaceResources.getColorRegistry().hasValueFor(SHADE)) {
    color = new Color(Display.getCurrent(), shade, 255-shade, 0);
    JFaceResources.getColorRegistry().put(SHADE, color);
} else {
    color = JFaceResources.getColorRegistry().get(SHADE);
}

リソースは、アプリケーションの終了時に割り当てが解除されます。

于 2012-11-16T10:40:09.263 に答える
3

前の回答に加えて、システム カラーを使用できます。これらの色は破棄する必要はありません。

を呼び出してアクセスできますDisplay#getSystemColor(int)

Display display = Display.getCurrent();
Color blue = display.getSystemColor(SWT.COLOR_BLUE);

使用可能な色のリストについては、SWT の Javadoc にアクセスしてください。

で始まるものは何でも使用できますSWT.COLOR_

于 2012-11-16T11:39:14.713 に答える
1

メソッドではpaintControl、色を作成し、使用し、廃棄します。

Color color = new Color(Display.getCurrent(), shade, 255-shade, 0);
gc.setBackground(color);
gc.fillRectangle(x, 0, 50, 50); // this call renders it then you can dispose the color
color.dispose();

このアプローチの問題は、リソースの作成/破棄が高価な操作であることです。そのため、キャッシュする必要があります。

shadeColorのプロパティとして作成することをお勧めしますItem。スコアが変更されたら、既存のものを破棄shadeColorして新しい を作成しますshareColor。が廃棄/除去されshareColorた場合に廃棄します。Item

于 2012-11-16T07:32:01.850 に答える