Java SWT中的动态颜色应如何分配和处置?

Java SWT中的动态颜色应如何分配和处置?,java,colors,swt,Java,Colors,Swt,我有时需要在SWT中动态生成颜色。以一个视图为例,该视图以不同于红-绿的颜色显示0-1之间的分数。可能存在其他具有不同颜色的类似视图: class ScoreView { private Canvas canvas; private List<Item> items = new ArrayList<Item>(); public ScoreView(Composite parent) { canvas = new Canvas(p

我有时需要在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();
    }
}
类分数视图{
私人帆布;
私有列表项=新的ArrayList();
公共ScoreView(复合父级){
画布=新画布(父级,SWT.NONE);
addPaintListener(新的PaintListener(){
公共无效paintControl(PaintEvent事件){
GC=event.GC;
int x=0;
用于(项目:项目){
int shade=(int)(item.getScore()*255.0);
颜色=新颜色(Display.getCurrent(),shade,255 shade,0);
总承包商.立根背景(颜色);
填充矩形(x,0,50,50);
x+=50;
}
}
});
}
公共无效集合项(列表项){
这个项目=项目;
canvas.redraw();
}
}
在SWT中,您应该始终释放资源。发件人:

颜色包含必须分配和释放的操作系统资源。因此,有必要处理您创建的每种颜色

那么,处理颜色的最佳方法是什么

发件人:

如果您在一个小部件中使用图形资源,例如widget.setFont(font),通常最好在释放它们所使用的小部件时清理这些资源,这样您就可以在小部件上挂接一个dispose侦听器

因此,我可以跟踪我分配的每种颜色,并将它们放置在画布或外壳上的
DisposeListener
中。但从同一个环节:

当程序退出时,操作系统释放程序的所有资源。为什么不依靠这个呢?操作系统资源不是无限的。如果您的程序无法释放不再需要的资源,则可能会耗尽资源。它还可能导致其他程序耗尽资源。因此,等待程序退出以释放资源通常是个坏主意

看起来我没有得到任何东西,因为即使颜色被处理,它们也会在退出时被处理(视图将持续程序的生命周期)

我认为我不能在
PaintListener
中直接处理颜色,因为它们在显示时仍被GC使用,因此我是否必须记住正在使用的颜色,并在下一次绘制调用中处理它们(如果在该调用中没有再次使用)

如果我能做到这一点,如果只有几种颜色可用,还有另一个问题。由于颜色分配的顺序,我可以渲染许多深浅的红色,然后用完颜色,而不能显示任何深浅的绿色。那么,在这种情况下,是否最好在程序开始时预先分配一系列我可能需要的颜色(比如调色板)?我应该分配多少,按什么顺序分配?那就意味着永远不要丢弃这些颜色


还有,有没有办法知道在任何时候有多少种颜色可用?其他正在运行的程序是否会减少可用颜色的数量?

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
作为
项中的属性
。当分数更改时,处理现有的
shadeColor
并创建新的
shareColor
。Dispose
shareColor
项被释放/删除时。

Eclipse RCP通过全局

通过使用它,您可以避免在应用程序启动时预先分配资源。 当您需要一个资源时,您可以在全局注册表中查询它。 如果它不可用,则在全局注册表中分配并注册它

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);
}

资源将在应用程序退出时解除分配。

除了前面的答案之外,您还可以使用系统颜色。这些颜色不需要处理

您可以通过以下方式访问它们:

有关可用颜色的列表,请转到:


您可以使用以
SWT.COLOR\uu

开头的任何内容。知道不应该只处理
COLOR
可能是件好事。你应该用同样的方法处理。
Display display = Display.getCurrent();
Color blue = display.getSystemColor(SWT.COLOR_BLUE);