Java中的梯度问题 [英] Gradient problems in Java

查看:146
本文介绍了Java中的梯度问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的程序中,我希望在JFrame上有一个半透明的白色到透明渐变,以覆盖黄色背景。这工作正常,它需要是白色到透明,因为我的程序设置如何为用户工作。然而,当我把程序带入大学(JRE7到我的JRE6)时,渐变变为白色到黑色然后透明......直到你开始增加白色的不透明度就没那么糟了......无论如何我可以解决这个问题吗?

In my program I wanted to have a translucent white to transparent gradient on my JFrame to overlay a yellow background. This works fine and it needs to be a white to transparent because of how my settings for the program work for the user. However, when I take the program into college (JRE7 to my JRE6) the gradient goes white to blackish then transparent... It isn't so bad until you start to increase the opacity of the white colour... is there anyway I can fix this?

这里是我的JFrame代码顶部的相关代码。

here is the relevant code from the top of my JFrame code.

public class DictionaryGUI extends JFrame
{   
    protected JPanel pGradientPane;

    //Interface gradient specification
    private Color pInterfaceColour = new Color(255, 245, 62);
    protected int iDegreeWhite = 180
    protected int iDegreeBlack = 0

    DictionaryGUI(int iWidth, int iHeight)
    {
        /*General definitions*/
        super(String.format("French Verb Conjugator - Version %s", MainLauncher.version));
        setSize(iWidth, iHeight);
        new Menu(this);

        this.iWidth = iWidth;    
        this.iHeight = iHeight;

        getContentPane().setBackground(pInterfaceColour);
        pGradientPane = new JPanel(new GridBagLayout())
        {
            private static final long serialVersionUID = 1L;

            protected void paintComponent(Graphics pGraphics) 
            {
                Graphics2D pGraphicsGradientRender = (Graphics2D) pGraphics;
                pGraphicsGradientRender.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                GradientPaint pGradient = new GradientPaint(0, 0, new Color(255, 255, 255, iDegreeWhite), 0, getHeight(), new Color(0, 0, 0, iDegreeBlack));
                pGraphicsGradientRender.setPaint(pGradient);
                pGraphicsGradientRender.fillRect(0, 0, getWidth(), getHeight());
                super.paintComponent(pGraphics);
            }
        };
        pGradientPane.setOpaque(false);
        pGradientPane.setPreferredSize(new Dimension(iWidth - 16, iHeight - 62));
        /*components added to pGradientPane here!*/
        add(pGradientPane);
    }

以及主要类别:

public class MainLauncher
{
    static int iHeight = 400;
    static int iWidth = 730;
    static String version = "0A3B6";

    public static void main(String[] args)
    {
    try 
    {
        for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
        {
            if ("Nimbus".equals(info.getName()))
            {
                UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (Exception e) {e.printStackTrace();}
    DictionaryGUI window = new DictionaryGUI(iWidth, iHeight);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setLocationByPlatform(true);
    window.setVisible(true);
}

JRE6和JRE7之间有什么区别吗?我应该将底色变成白色吗? (是黑色的,人们想要让底部的颜色变暗。)

Is it just some difference between JRE6 and JRE7? should I make the bottom colour to white aswell? (was black incase people want to darken the colour at the bottom.)

如果有人需要它我可以发布一些截图....

I can post some screenshots tommorrow if anybody needs them....

谢谢
Jamie

Thanks Jamie

编辑:
我更改了渐变中的第二种(透明)颜色白色,它解决了问题。但是,我仍然不清楚为什么透明的黑色在中间显示出来?它必须与JRE7有关,因为它发生的地方......也许它们改变了渐变中透明度的工作方式。有人知道如何在保持颜色变黑的同时消除这个问题吗?

I changed the second (transparent) colour in the gradient to white and it fixes the problem. However, I am still troubled to why the transparent black colour shows through in the middle? it must be something to do with JRE7 because thats where it occurs... maybe they changed something with how transparency in gradients work. Does anybody know how to eliminate this problem while keeping the colour black?

推荐答案

代码的问题是这一行:

GradientPaint pGradient = new GradientPaint(0, 0, new Color(255, 255, 255, iDegreeWhite), 0, getHeight(), new Color(0, 0, 0, iDegreeBlack));

应为:

GradientPaint pGradient = new GradientPaint(0, 0, new Color(255, 255, 255, iDegreeWhite), 0, getHeight(), new Color(255, 245, 62, iDegreeWhite));

回顾你的问题,我发现你基本上找到了解决方案 - 但它有点不同。原因如下:

Looking back at your question, I see you've basically found the solution - but it's a little different. Here's why:

在渐变中混合颜色时,混合颜色的所有方面:RBGA

When blending the colors in the gradient, your blending all aspects of the color: RBGA

你看,直到你达到完整的第二种颜色,你将黑色混合到颜色渐变中,并且混合不会达到完全透明度。因此,在页面的20%左右,你将拥有这种颜色:204,204,204,144(白色为80%,黑色为20%,不透明度为56%)。

You see, until you reach the full second color, you are mixing black into the color gradient and that mix won't be at the full transparency. So 20% of the way down the page, you'll have this color: 204,204,204,144 (that's 80% white, 20% black, and 56% opaque).

最简单的解决方案是在不使用半透明时完全避免半透明 - 只需将顶部的浅黄色混合到底部的深黄色即可。这样也需要更少的资源。

The easiest solution is to avoid translucency completely if you're not using it - just blend from the light yellow at the top to the dark yellow at the bottom. It takes less resources this way too.

但是由于你使用透明度,我提供的解决方案也使用透明度。您将使用一致的透明度从白色到黄色混合。

But since you're using transparency, the solution I've provided uses transparency as well. You'll be blending from the white to the yellow using a consistent transparency.

如果你从白色到白色(透明)混合,你将遇到与以前只有白色相同的问题(由于它是其中一种颜色,因此不太明显你正在使用):渐变将有一个白色的条纹,直到第二种颜色达到完全透明。

If you blend from white to white (transparent), you'll have the same problem as before only with white (which will be less noticeable since it's one of the colors you're using): The gradient will have a white "streak" until the second color reaches full transparency.

至于为什么它在不同的JVM上的作用不同,我我猜Oracle可能已经改变了alpha的混合方式。更好的alpha支持似乎是他们已经研究了一段时间的东西,这是朝着这个方向迈出的合乎逻辑的一步。我在这个声明中没有任何证据 - 它只是基于我在alpha中看到的其他变化(如透明窗口)。

As far as why it acts different on different JVMs, I'd guess that Oracle may have changed the way alpha's are blended. Better alpha support seems to be something they've been working on for a while, and this is a logical step in that direction. I don't have any proof on this statement though - it's just based on other changes I've seen with alpha's (like transparent windowing).

编辑
此SSCCE演示了问题和解决方案:

EDIT This SSCCE demos both the problem and the solution:

import java.awt.*;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;


public class TransparencyDemo extends Box{

    protected JPanel pGradientPane;

    //Interface gradient specification
    private Color pInterfaceColour = new Color(255, 245, 62);
    protected int iDegreeWhite = 180;
    protected int iDegreeBlack = 0;

    public TransparencyDemo() {
        super(BoxLayout.X_AXIS);
        setOpaque(true);

        //Incorrect Solution
        pGradientPane = new JPanel(new GridBagLayout())
        {
            private static final long serialVersionUID = 1L;

            protected void paintComponent(Graphics pGraphics) 
            {
                Graphics2D pGraphicsGradientRender = (Graphics2D) pGraphics;
                pGraphicsGradientRender.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                GradientPaint pGradient = new GradientPaint(0, 0, new Color(255, 255, 255, iDegreeWhite), 0, getHeight(), new Color(0, 0, 0, iDegreeBlack));
                pGraphicsGradientRender.setPaint(pGradient);
                pGraphicsGradientRender.fillRect(0, 0, getWidth(), getHeight());
                super.paintComponent(pGraphics);
            }
        };
        pGradientPane.setOpaque(false);
        add(pGradientPane);

        //Correct Solution
        JPanel pGradientPane2 = new JPanel(new GridBagLayout())
        {
            private static final long serialVersionUID = 1L;

            protected void paintComponent(Graphics pGraphics) 
            {
                Graphics2D pGraphicsGradientRender = (Graphics2D) pGraphics;
                pGraphicsGradientRender.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                GradientPaint pGradient = new GradientPaint(0, 0, new Color(255, 255, 255, iDegreeWhite), 0, getHeight(),  new Color(255, 245, 62, iDegreeWhite));
                pGraphicsGradientRender.setPaint(pGradient);
                pGraphicsGradientRender.fillRect(0, 0, getWidth(), getHeight());
                super.paintComponent(pGraphics);
            }
        };
        pGradientPane2.setOpaque(false);
        add(pGradientPane2);


        setBackground(pInterfaceColour);

    }

    public static void main(String[] args){
        try {
             for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                   UIManager.setLookAndFeel(info.getClassName());
                   break;
                }
             }
          } catch (Exception e) {
             e.printStackTrace();
          }

        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TransparencyDemo());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

这篇关于Java中的梯度问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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