Gradient problems in Java
Asked Answered
C

5

13

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?

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

And the mainclass aswell:

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

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....

What the gradient should look like

What the gradient actually looks like for some

Thanks Jamie

EDIT: 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?

Cecilia answered 6/12, 2012 at 17:7 Comment(9)
Hmmm... My indentation in the code is not showing up in the code box? sorry! do you know how to fix it?Cecilia
Also, consider posting a minimal code example that demonstrates your problem, an SSCCE. This will allow us to run your code and modify it and perhaps even correct it. Please read the link before replying as it supplies many important details on the SSCCE requirements.Schild
AFAIK this is the minimum code... there is no extra code for any other components. Unfortunatly the Main method is missing and the settingsparser but I can just replace the parser with the default values I actually cant see the indentation in the code. Why should you not use tabs?Cecilia
Done :D well I included MainLauncher as I wouldn't know how to intregrate them, but should that be a problem?Cecilia
I've made some changes and have gotten your code to work, sort of, but it doesn't demonstrate the problem that you're complaining about.Schild
hmmm... well, are you using JRE6 like me? Machines with JRE7 cause the problem I think. I will post a screenshot of what it should ook like colour wiseCecilia
@J_mie6: I have placed a 500 rep bounty on this question to learn more about this problem and see if better solutions exist.Schild
j_mie6: I need your help -- who should get the bonus. I'm leaning towards Nick RippeSchild
I agree with you, Sorry I took so long to answer, had problems with my account :DCecilia
D
7

The problem with the code is this line:

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

should be this:

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:

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

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.

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

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);
    }
}
Divers answered 10/12, 2012 at 17:41 Comment(5)
Nimbus has own Painter, to check my link in answer by (@Hovercraft Full Of Eels), did you have got some issue with that....Publicness
@Publicness He seems to be avoiding the Painter issue by directly painting the gradient. Another solution would be to deal with the Nimbus Painters...Divers
@Tom I've added SSCCE code that shows both versions side by side (with the black line and without).Divers
I've noticed some strange things with the Demo I posted here: If you either 1) full screen the window or 2) set the window size differently before the initial paint -> Both sides will paint properly until you shrink the window down to its minimum size again. Could have to do with Tom's answer and Direct3D Pipeline, but it doesn't seem to behave as the article indicates.Divers
Thanks for the good answer! I leaned away from using the 2 shades of yellow to form the gradient because users in the program can change the colour. By having it my way they have to pick 1 colour and use a slider to change the whiteness at the top (hence iDegreeWhite) Thanks all the same!Cecilia
S
10

Here is my version of your code as an 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);
   }
}

But again this doesn't demonstrate your problem. I'm guessing though that your problem is one of using transparent backgrounds with Swing GUI where painting artifacts are not corrected fully. If so, please read what Rob Camick has to say about this on his blog: Backgrounds With Transparency

Schild answered 6/12, 2012 at 17:44 Comment(11)
I really difficult to explain the problem. For my on my computer it's perfect. but when I use it on my laptop or on my colleges computers (both with JRE7) it looks different. And so I can't show the problem because it doesn't occur for some people but when it does occur it is always there...Cecilia
@J_mie6: But will it occur with this minimal code above? or must you have changing components sitting on top of this background. In other words, have you shown that this SSCCE above reproduces the problem? Or is more needed?Schild
I will go and check it on a machine that has the problem.Cecilia
yup, that code causes the problem... see my screenshot above.Cecilia
@J_mie6: hm... I see your problem in your post above (1+ for all your efforts!), but since I can't reproduce your problem on my system, I'm having difficulty figuring out why it's not working. Have you looked at Rob Camick's blog on backgrounds with transparency? that might help you out.Schild
I took a look but wasn't it talking about setOpaque() method? and it seems like I complied with it. I will have another look... I just don't understand why the JRE7 ones produce the bad gradient. Would you think it would work if I made it so the project will default to the JRE6 build on those computers?Cecilia
Ok, so 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 chnaged something with how transparency in gradients work. Thanks for all your help!Cecilia
@J_mie6: I wish I knew the answer, but it will take a more knowledgeable person than myself to answer this. Thank you for accepting my answer, but I did not in fact answer this, and so you might wish to "un-accept" my answer and see if anyone else can give a better solution. I am considering offering a bounty if need be in a day or two if no good answer comes by. Lord knows I have rep to spare, and might as well "spend" it.Schild
@j_mie6: You're welcome. I am very interested in the solution as well!Schild
@Hovercraft Full Of Eels, Pete please see my post here about RepaintManager (will be deleted), I'm sure that Painter has (for Nimbus implemented low level GPU whatever, there are diametral quality diff betweens Metal and Nimbus)Publicness
Thanks mKorbel -- but don't delete it. I'll have to study all bits of info in a few days.Schild
D
7

The problem with the code is this line:

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

should be this:

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:

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

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.

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

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);
    }
}
Divers answered 10/12, 2012 at 17:41 Comment(5)
Nimbus has own Painter, to check my link in answer by (@Hovercraft Full Of Eels), did you have got some issue with that....Publicness
@Publicness He seems to be avoiding the Painter issue by directly painting the gradient. Another solution would be to deal with the Nimbus Painters...Divers
@Tom I've added SSCCE code that shows both versions side by side (with the black line and without).Divers
I've noticed some strange things with the Demo I posted here: If you either 1) full screen the window or 2) set the window size differently before the initial paint -> Both sides will paint properly until you shrink the window down to its minimum size again. Could have to do with Tom's answer and Direct3D Pipeline, but it doesn't seem to behave as the article indicates.Divers
Thanks for the good answer! I leaned away from using the 2 shades of yellow to form the gradient because users in the program can change the colour. By having it my way they have to pick 1 colour and use a slider to change the whiteness at the top (hence iDegreeWhite) Thanks all the same!Cecilia
O
6

My guess is that it's about the 'graphics pipeline' that's being used on the different computers.

Java has several different pipelines, here is some information about them.

On my computer I can use the X11 pipeline, or the OpenGL pipeline. With the X11 pipeline the darkness occurs; on OpenGL, it doesn't.

On Windows you can choose from 3 different pipelines, and even then (looking at the link above), there can be differences.

I can't immediately imagine what's the configuration your school has, and why it's different, but you can try to investigate.

You might want to file this difference as a bug.

Orethaorferd answered 9/12, 2012 at 19:14 Comment(0)
P
2

I have got fatamorgana, I'm sure that GradientPaint is darker and darker and darker, phaaa crazy eye illusion, brrrr

//https://mcmap.net/q/854870/-gradient-problems-in-java/13806210#comment18995490_13806210

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class MainLauncher {

    private JFrame window = new JFrame();

    public MainLauncher() {
        GradientPane pane = new GradientPane();
        pane.setLayout(new GridLayout(6, 4, 15, 15));
        for (int i = 1; i <= 24; i++) {
            pane.add(createButton(i));
        }
        pane.setOpaque(false);
        window.add(pane);
        RepaintManager.setCurrentManager(new RepaintManager() {

            @Override
            public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
                Container con = c.getParent();
                while (con instanceof JComponent) {
                    if (!con.isVisible()) {
                        return;
                    }
                    if (con instanceof GradientPane) {
                        c = (JComponent) con;
                        x = 0;
                        y = 0;
                        w = con.getWidth();
                        h = con.getHeight();
                    }
                    con = con.getParent();
                }
                super.addDirtyRegion(c, x, y, w, h);
            }
        });
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setLocationByPlatform(true);
        window.setSize(400, 300);
        //window.pack();
        window.setVisible(true);
    }

    private JButton createButton(final int text) {
        JButton button = new JButton(Integer.toString(text));
        return button;
    }

    class GradientPane extends JPanel {

        private static final long serialVersionUID = 1L;
        private final int h = 150;
        private BufferedImage img = null;
        private BufferedImage shadow = new BufferedImage(1, h, BufferedImage.TYPE_INT_ARGB);

        public GradientPane() {
            paintBackGround(new Color(150, 250, 150));
        }

        public void paintBackGround(Color g) {
            Graphics2D g2 = shadow.createGraphics();
            g2.setPaint(g);
            g2.fillRect(0, 0, 1, h);
            g2.setComposite(AlphaComposite.DstIn);
            g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h, new Color(0.1f, 0.8f, 0.8f, 0.5f)));
            g2.fillRect(0, 0, 1, h);
            g2.dispose();
        }

        @Override
        public void paintComponent(Graphics g) {
            if (img == null || img.getWidth() != getWidth() || img.getHeight() != getHeight()) {
                img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
            }
            Graphics2D g2 = img.createGraphics();
            super.paintComponent(g2);
            Rectangle bounds = this.getVisibleRect();
            g2.scale(bounds.getWidth(), -1);
            g2.drawImage(shadow, bounds.x, -bounds.y - h, null);
            g2.scale(1, -1);
            g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h, null);
            g2.dispose();
            g.drawImage(img, 0, 0, null);
        }
    }

    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();
        }
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                MainLauncher ml = new MainLauncher();
            }
        });
    }
}
Publicness answered 10/12, 2012 at 22:36 Comment(0)
C
2

As Nick pointed out, the problem is that you are using transparent black rather than transparent white. So the translucent colours are a shade between white and black.

Try replacing with this line in your code:

GradientPaint pGradient = new GradientPaint(0, 0, new Color(255, 255, 255, iDegreeWhite), 0, getHeight(), new Color(255, 255, 255, iDegreeBlack));
Casing answered 11/12, 2012 at 15:9 Comment(1)
It's actually really interesting - the only time you don't see the streak is when the first and second color match. So this answer works correctly, but if the first color was black instead, you'd get a white streak. Could we get some consistency here??? (Yeah, I'm looking at you Oracle)Divers

© 2022 - 2024 — McMap. All rights reserved.