Java中的梯度问题

J_m*_*ie6 13 java swing gradient nimbus

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

这是我的JFrame代码顶部的相关代码.

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);
    }
Run Code Online (Sandbox Code Playgroud)

还有主要类别:

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);
}
Run Code Online (Sandbox Code Playgroud)

这只是JRE6和JRE7之间的一些区别吗?我应该将底色变成白色吗?(是黑色的,因为人们想要使底部的颜色变暗.)

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

渐变应该是什么样子

对于某些人来说梯度实际上是什么样的

谢谢杰米

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

Hov*_*els 10

这是我的代码版本作为sscce:

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

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

}

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

      getContentPane().setBackground(pInterfaceColour);
      pGradientPane = new JPanel() {
         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);
   }
}
Run Code Online (Sandbox Code Playgroud)

但这再次证明了你的问题.我猜你的问题是使用Swing GUI的透明背景,其中绘画工件没有完全纠正.如果是这样,请在他的博客上阅读Rob Camick对此的评论:透明度背景


Nic*_*ppe 7

代码的问题是这一行:

GradientPaint pGradient = new GradientPaint(0, 0, new Color(255, 255, 255, iDegreeWhite), 0, getHeight(), new Color(0, 0, 0, iDegreeBlack));
Run Code Online (Sandbox Code Playgroud)

应该这样:

GradientPaint pGradient = new GradientPaint(0, 0, new Color(255, 255, 255, iDegreeWhite), 0, getHeight(), new Color(255, 245, 62, iDegreeWhite));
Run Code Online (Sandbox Code Playgroud)

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

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

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

最简单的解决方案是如果你不使用它,就完全避免半透明 - 只需将顶部的浅黄色混合到底部的深黄色即可.这种方式也需要更少的资源.

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

如果你从白色到白色(透明)混合,你将遇到与以前一样的问题(由于它是你正在使用的颜色之一,它将不那么明显):渐变会有一个白色的"条纹"直到第二种颜色达到完全透明.

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

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 6

我猜测它是关于在不同计算机上使用的"图形管道".

Java有几个不同的管道,这里有一些关于它们的信息.

在我的计算机上,我可以使用X11管道或OpenGL管道.使用X11管道时会出现黑暗; 在OpenGL上,它没有.

在Windows上,您可以从3种不同的管道中进行选择,即便如此(查看上面的链接),也可能存在差异.

我不能立刻想象你的学校有什么配置,为什么它有所不同,但你可以尝试调查.

您可能希望将此差异归档为错误.