基于值Java Swing动态设置颜色 [英] Set Color dynamically based on value Java Swing

查看:548
本文介绍了基于值Java Swing动态设置颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Java Swing。我想根据我计算的双值显示颜色。

I am using Java Swing. I would like to display colors based on a double values which I compute.

编辑 - 我需要填充 Path2D 对象的颜色。目前,这是我做的

Edit - I need to fill the color of a Path2D object. Currently, this is how I do it

Path2D shape;
// some code here
g2d.setColor(Color.Red);
g2d.fill(shape);

现在我不想把颜色固定为 Color.Red ,但需要根据我计算的值来设置它。 double值可以是负数或正数。值越负,颜色越深。颜色不必是红色。

Now I do not want the color to be fixed as Color.Red but need to set it based on a value I compute. The double value can be negative or positive. The more negative the value is, the darker the color should be. The color need not be red. How can I do so?

推荐答案

您必须知道 double value。 (至少,这将使事情更容易理解)。在任何情况下,您都可以将 double 值转换为范围[0,1]。在许多情况下,做任何这样的标准化是有益的。

You have to know the possible range of the double values. (At least, this would make things easier to understand). In any case, you can transform your double value to be in the range [0,1]. And it's in many cases beneficial to do such a kind of normalization anyhow.

您可以创建一个方法

private static double normalize(double min, double max, double value) {
    return (value - min) / (max - min);
}

此方法会将min和max之间的任何 [0,1]。要将此规范化值映射到颜色,可以使用

This method will convert any "value" between min and max to a value in [0,1]. In order to map this normalized value to a color, you can use

private static Color colorFor(double value) {
    value = Math.max(0, Math.min(1, value));
    int red = (int)(value * 255);
    return new Color(red,0,0);
}

此方法将0.0和1.0之间的值转换为颜色:0.0为黑色,1.0为红色。

This method will convert a value between 0.0 and 1.0 into a color: 0.0 will be black, and 1.0 will be red.

因此,假设您在min和max之间有一个双重值,您可以将其映射为如下的颜色:

So assuming you have a double "value" between "min" and "max", you can map it to a color like this:

g2d.setColor(colorFor(normalize(min, max, value)));
g2d.fill(shape);

编辑:回复评论:我认为基本上有两个选项:

Reply to the comment: I think there are basically two options:


  • 您可以不断跟踪您到目前为止遇到的当前最小/最大值。

  • 或者,您可以使用S形函数将[-Infinity,+ Infinity]的间隔映射到间隔[0,1]。

第一个选项的缺点是以前与某种颜色相关联的值可能突然有不同的颜色。例如,假设您将区间[0,1]映射到颜色范围[黑色,红色]。现在你获得一个新的最大值,如100000.然后你必须调整你的范围,值0和1将不再有一个视觉差异:他们都将映射到黑色。

The first option has the disadvantage that values that have previously been associated with a certain color may suddenly have a different color. For example assume that you mapped the interval [0,1] to the color range [black, red]. Now you obtain a new maximum value like 100000. Then you have to adjust your range, the values 0 and 1 will no longer have a visual difference: They will both be mapped to 'black'.

第二个选项的缺点是,初始值的小差异不会对颜色产生显着影响,这取决于这些差异发生的范围。例如,您将无法在那里看到10000和10001之间的差异。

The second option has the disadvantage that small differences in the initial values will not have a noticable effect on the color, depending on the range in which these differences occur. For example, you will not be able to see a difference between 10000 and 10001 there.

所以你必须清楚你想要什么颜色映射和行为。

So you have to be clear about what color mapping and behavior you want.

但是,这里有一个使用S形函数将[-Infinity,+ Infinity]的间隔映射到间隔[0,1]的示例,到颜色:

However, here is an example that uses a sigmoidal function to map the interval of [-Infinity,+Infinity] to the interval [0,1], and this interval to a color:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


class ColorRange
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new ColorRangePanel());
        f.setSize(1000, 200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}


class ColorRangePanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;

        double values[] = {
            -1e3, -1e2, -1e1, -1, -0.5, 0.0, 0.5, 1, 1e1, 1e2, 1e3    
        };

        for (int i=0; i<values.length; i++)
        {
            double value = values[i];
            int w = getWidth() / values.length;
            int x = i * w;

            g.setColor(Color.BLACK);
            g.drawString(String.valueOf(value), x, 20);

            g.setColor(colorFor(value));
            g.fillRect(x, 50, w, 100);
        }
    }

    private static Color colorFor(double value) 
    {
        double v0 = value / Math.sqrt(1 + value * value); // -1...1
        double v1 = (1 + v0) * 0.5; // 0...1
        return colorForRange(v1);
    }    
    private static Color colorForRange(double value) 
    {
        value = Math.max(0, Math.min(1, value));
        int red = (int)(value * 255);
        return new Color(red,0,0);
    }    
}

这篇关于基于值Java Swing动态设置颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆