简体   繁体   中英

Changing the Foreground Color of ArrowButton of JComboBox in nimbus LaF

I want to change the foreground color of ArrowButton of JComboBox for particular states. I have tried to override the default key values using the painter. but it is not working. Here is my Code

UIManager.getLookAndFeelDefaults().put("ComboBox:\"ComboBox.arrowButton\[Enabled].foregroundPainter", new ArrowPainter(new Color(255,255,255)));
UIManager.getLookAndFeelDefaults().put("ComboBox:\"ComboBox.arrowButton\"[MouseOver].foregroundPainter", new ArrowPainter(new Color(255,255,255)));

Could someone help me how to change the color?

Here is my ArrowPainter class

public class ArrowPainter implements Painter {
        private float leftWidth;

        private float topHeight;

        private float centerWidth;

        private float centerHeight;

        private float rightWidth;

        private float bottomHeight;

        private float leftScale;

        private float topScale;

        private float centerHScale;

        private float centerVScale;

        private float rightScale;

        private float bottomScale;

        private Color new_color;
         private Path2D path = new Path2D.Float();
         private Object[] componentColors;
         public ArrowPainter(Color new_color)
         {
             this.new_color = new_color;
         }
         @Override
            public void paint(Graphics2D g, Object c, int width, int height) {
                // TODO Auto-generated method stub
                paintForegroundEnabled(g);
            }
         public void paintForegroundEnabled(Graphics2D g) {
                path = decodePath5();
                g.setPaint(decodeGradient9(path));
                g.fill(path);

            }
        private Paint decodeGradient9(Shape s) {
            // TODO Auto-generated method stub

             Rectangle2D bounds = s.getBounds2D();
                float x = (float)bounds.getX();
                float y = (float)bounds.getY();
                float w = (float)bounds.getWidth();
                float h = (float)bounds.getHeight();
                return decodeGradient((1.0f * w) + x, (0.5f * h) + y, (0.0f * w) + x, (0.5f * h) + y,
                        new float[] { 0.0f,0.5f,1.0f },
                        new Color[] { new_color,
                                    decodeColor(new_color,new_color,0.5f),
                                    new_color});
        }
        private Color decodeColor(Color color1, Color color2,
                float midPoint) {
            // TODO Auto-generated method stub
             return new Color(deriveARGB(color1, color2, midPoint));
        }
        private int deriveARGB(Color color1, Color color2, float midPoint) {
            // TODO Auto-generated method stub
             int r = color1.getRed() +
                        Math.round((color2.getRed() - color1.getRed()) * midPoint);
                int g = color1.getGreen() +
                        Math.round((color2.getGreen() - color1.getGreen()) * midPoint);
                int b = color1.getBlue() +
                        Math.round((color2.getBlue() - color1.getBlue()) * midPoint);
                int a = color1.getAlpha() +
                        Math.round((color2.getAlpha() - color1.getAlpha()) * midPoint);
                return ((a & 0xFF) << 24) |
                        ((r & 0xFF) << 16) |
                        ((g & 0xFF) << 8) |
                        (b & 0xFF);
        }
        private Paint decodeGradient(float x1, float y1, float x2, float y2, float[] midpoints, Color[] colors) {
            // TODO Auto-generated method stub
            if (x1 == x2 && y1 == y2) {
                y2 += .00001f;
            }
            return new LinearGradientPaint(x1, y1, x2, y2, midpoints, colors);
        }
        private double decodeY(float y) {
            // TODO Auto-generated method stub
             if (y >= 0 && y <= 1) {
                    return y * topHeight;
                } else if (y > 1 && y < 2) {
                    return ((y-1) * centerHeight) + topHeight;
                } else if (y >= 2 && y <= 3) {
                    return ((y-2) * bottomHeight) + topHeight + centerHeight;
                } else {
                    throw new IllegalArgumentException("Invalid y");
                }
        }
        private double decodeX(float x) {
            // TODO Auto-generated method stub
             if (x >= 0 && x <= 1) {
                    return x * leftWidth;
                } else if (x > 1 && x < 2) {
                    return ((x-1) * centerWidth) + leftWidth;
                } else if (x >= 2 && x <= 3) {
                    return ((x-2) * rightWidth) + leftWidth + centerWidth;
                } else {
                    throw new IllegalArgumentException("Invalid x");
                }
        }
        private Path2D decodePath5() {
            // TODO Auto-generated method stub
            path.reset();
            path.moveTo(decodeX(0.9995915f), decodeY(1.3616071f));
            path.lineTo(decodeX(2.0f), decodeY(0.8333333f));
            path.lineTo(decodeX(2.0f), decodeY(1.8571429f));
            path.lineTo(decodeX(0.9995915f), decodeY(1.3616071f));
            path.closePath();
            return path;
        }

    }

The UIManager methods you're trying to use only work with the Nimbus look and feel. More info here: http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/_nimbusDefaults.html

The problem is that you aren't setting your look and feel to Nimbus anywhere.

This code works for me, also notice that this is an MCVE instead of an entire project with extraneous methods:

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.Painter;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;


public class Test {
    public static void main (String [] args) throws InvocationTargetException, InterruptedException{

        SwingUtilities.invokeAndWait(new Runnable(){
            public void run(){


                try {
                    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }
                } catch (Exception e) {
                    // If Nimbus is not available, you can set the GUI to another look and feel.
                }

                 UIManager.getLookAndFeelDefaults().put("ComboBox:\"ComboBox.arrowButton\"[Enabled].foregroundPainter", new MyPainter());
                 UIManager.getLookAndFeelDefaults().put("ComboBox:\"ComboBox.arrowButton\"[MouseOver].foregroundPainter", new MyPainter());


                 JComboBox comboBox = new JComboBox();
                 comboBox.addItem("one");
                 comboBox.addItem("two");
                 comboBox.addItem("three");


                 JFrame frame = new JFrame();
                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                 frame.add(comboBox);
                 frame.setSize(300, 300);
                 frame.setVisible(true);
            }
        });
    }

    public static class MyPainter implements Painter<Component>{

        @Override
        public void paint(Graphics2D g, Component object, int width, int height){
            g.setColor(Color.RED);
            g.fillRect(0, 0, width, height);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM