Java Swing issue - Using color palette

2019-01-12 08:33发布

问题:

I have a problem here - I have a hexadecimal value being stored in a textfield after I have selected a color (using JColorChooser). What I would like to do is display the name of the color in another textfield right beside the one with the hexadecimal value, but I am unsure as to how to get the color name? I am including my code, maybe someone can give me some useful hints:

public class Main extends JComponent implements Accessible {
    public ColorSelectionModel selectionModel;
    public static final String SELECTION_MODEL_PROPERTY = "selectionModel";
    public JColorChooser chooser;
    public Color color;

    public void process() {
        JFrame frame;
        JButton button;
        final JTextField text1, text2;

        // Initialize variables
        chooser = new JColorChooser();
        frame = new JFrame();
        JPanel panel = new JPanel();
        button = new JButton("Show color Palette");
        text1 = new JTextField(20);
        text2 = new JTextField(20);

        // Setup UI
        frame.add(panel);
        panel.add(button);
        panel.add(text1);
        panel.add(text2);
        panel.add(chooser)
        chooser.setVisible(false);

        button.setLocation(800, 600);
        button.setActionCommand("");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                color = chooser.showDialog(chooser, "SHOW THE COLOR",
                        chooser.getColor());
                {
                    if (color != null) {
                        String hex = Integer.toHexString(color.getRGB() & 0xffffff);
                        hex = "#" + hex;
                        text1.setText(hex);
                    }
                }
            }
        });

        frame.setVisible(true);
        frame.setSize(1000, 800);
    }

    public static void main(String[] argv) {
        // Run the code
        Main m1 = new Main();
        m1.process();
    }
}

回答1:

I achieved this by Java Reflection : (works for static final Color defined in java.awt.Color)

Here is my code :

public static String getNameReflection(Color colorParam) {
        try {
            //first read all fields in array
            Field[] field = Class.forName("java.awt.Color").getDeclaredFields();
            for (Field f : field) {
                String colorName = f.getName();
                Class<?> t = f.getType();
                // System.out.println(f.getType());
                // check only for constants - "public static final Color"
                if (t == java.awt.Color.class) {
                    Color defined = (Color) f.get(null);
                    if (defined.equals(colorParam)) {
                        System.out.println(colorName);
                        return colorName.toUpperCase();
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("Error... " + e.toString());
        }
        return "NO_MATCH";
    }

Source : http://ganeshtiwaridotcomdotnp.blogspot.com/2011/12/java-reflection-getting-name-of-color.html



回答2:

RGB is not a very best color model to work with in this situation. HSB would be more appropriate.

  1. Convert RGB to HSB:

    float[] hsb = Color.RGBtoHSB(red, green, blue, null);
    
  2. Detect color:

    String color;
    
    if (hsb[0] >= 0.0 && ksb[0] <= 0.1) {
        color = "Red";
    } else if (hsb[0] > 0.1 && ksb[0] <= 0.25) {
        color = "Orange";
    } else if (hsb[0] > 0.25 && ksb[0] <= 0.35) {
        color = "Yellow";
    } ...
    


回答3:

For a fixed palette, an enum is a reasonable choice, shown in context here:

private enum Hue {

    Cyan(Color.cyan), Magenta(Color.magenta), Yellow(Color.yellow),
    Red(Color.red), Green(Color.green), Blue(Color.blue);

    private final Color color;

    private Hue(Color color) {
        this.color = color;
    }

    public Color getColor() {
        return color;
    }
}

For a variable palette, you need to define a data structure that relates color and name, such as Map<Color, String>. You may also want to look at How to Use Color Choosers: Creating a Custom Chooser Panel. Finally, you may want to consider using existing, standard color names.



回答4:

I found this thread via mKorbel's link to my Interactive Color Wheel. The applet includes a Java port and extension of Chirag Mehta's Name That Color Javascript library. Since I eventually added the ability to have multiple color name dictionaries, I removed the actual hex/name pairs from the source code and added them as properties files. You only need the first two files if all you want is Chirag's color name dictionary (a mishmash of several smaller dictionaries).

  • http://r0k.us/source/NTC.java
  • http://r0k.us/source/cnd_ntc.properties
  • http://r0k.us/source/cnd_crayola.properties
  • http://r0k.us/source/cnd_resene2010.properties
  • http://r0k.us/source/cnd_w3c.properties

NTC.java is written with a main() method so that it can be tested standalone in a command shell:

>java us.r0k.ntc.NTC 28f369
>  #0BDA51, Malachite, false

The first value is the closest hex to the desired hex, second is the color name for that value, and third indicates that no exact match was found.

You can also specify a second parameter, the name of the color name dictionary (which defaults to "cnd_ntc.properties").



回答5:

public void updateChooser() {
    Color color = getColorFromModel();
    if (Color.red.equals(color)) {
        redCrayon.setSelected(true);
    } else if (Color.yellow.equals(color)) {
        yellowCrayon.setSelected(true);
    } else if (Color.green.equals(color)) {
        greenCrayon.setSelected(true);
    } else if (Color.blue.equals(color)) {
        blueCrayon.setSelected(true);
    }
}

Check On http://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html#chooserpanel