首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SWT中的动态颜色应该如何分配和处理?

SWT中的动态颜色应该如何分配和处理?
EN

Stack Overflow用户
提问于 2012-11-16 02:55:26
回答 3查看 2.3K关注 0票数 4

有时,我需要在SWT中动态生成颜色。以一个视图为例,该视图以不同的颜色显示红绿色的0-1之间的分数。可能还有其他不同颜色的类似视图:

代码语言:javascript
运行
复制
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(字体)--通常最好在小部件被释放时清除这些资源,这样就可以在小部件上挂载一个dispose监听器.

因此,我可以跟踪我分配的每一种颜色,并在画布或外壳上的DisposeListener中释放它们。但从同样的联系来看:

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

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

我想我不能直接在PaintListener中处理颜色,因为它们在显示时仍然被GC使用,所以如果在那个调用中没有再次使用它们,那么我必须记住正在使用的颜色并在下一个画图调用中处理它们吗?

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

另外,有没有办法知道在任何时候有多少种颜色可用?其他运行程序是否会删除可用的颜色数?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-16 10:40:09

Eclipse通过全局ColorRegistry来处理这个问题。

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

代码语言:javascript
运行
复制
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);
}

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

票数 5
EN

Stack Overflow用户

发布于 2012-11-16 11:39:14

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

您可以通过调用Display#getSystemColor(int)来访问它们

代码语言:javascript
运行
复制
Display display = Display.getCurrent();
Color blue = display.getSystemColor(SWT.COLOR_BLUE);

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

您可以使用以SWT.COLOR_开头的任何东西。

票数 3
EN

Stack Overflow用户

发布于 2012-11-16 07:32:01

paintControl方法中,创建颜色,使用它并处理它。

代码语言:javascript
运行
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13409687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档