本文介绍了如何仅显示 JColorChooser 的 HSV 框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这张图片中,您可以看到一个默认的 Java Swing 颜色选择器,JColorChooser:

In this image you can see a default Java Swing color chooser, JColorChooser:

我想要的只是红色方框中的颜色方块和垂直滑块:

What I want is just the color square and vertical slider as outlined in red:

我能够删除所有选项卡(色板、HSL 等)和预览,但无法删除所有滑块.我该怎么做?

I was able to remove all the tabs (Swatches, HSL, etc) and the preview, but I was unable to remove all the sliders. How can I do this?

推荐答案

好的,只是为了笑,我决定从头开始创建你想要的 JPanel,在一种视图控制器设置中连接它,因为这里的模型很简单——控制器中的一个颜色字段.要使用这个组件,你需要创建一个组件的实例,将它添加到你的 GUI 需要的地方,然后简单地向它添加一个 PropertyChangeListener 来监听它的 COLOR 属性:

OK, just for grins, I decided to create your desired JPanel from scratch, wiring it up in a kind of View-Controller set up, since the model here is trivial -- a Color field within the controller. To use this component you create an instance of the component, add it to your GUI where desired and simply add a PropertyChangeListener to it that listens to its COLOR property:

hsvChooserPanel.addPropertyChangeListener(HsvChooserPanel.COLOR, pce -> {
    Color c = (Color) pce.getNewValue();
    // do what you want with Color value, c, here
});

测试类:

版本 2:这允许使用任意 3 种 HSV 面板/条组合,或者条集中在色相、饱和度或值(此处为亮度)的组合.它使用一个枚举 ColorProperty,它有 3 个值,ColorProperty.HUE、ColorProperty.SATURATION 和 ColorProperty.BRIGHTNESS,并且在枚举项中计算如何创建颜色条和颜色方块 BufferedImages.欢迎评论:

Version 2: this allows use of any 3 of the HSV panel/bar combinations, either the one with the bar focused on Hue, or Saturation, or Value (here Brightness). It uses an enum, ColorProperty, that has 3 values, ColorProperty.HUE, ColorProperty.SATURATION, and ColorProperty.BRIGHTNESS, and has the calculations within the enum items themselves on how to create the color bar and the color square BufferedImages. Comments welcome:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestHsvChooser2 {
    // ***** choose which color panel / color bar you'd like to test:
    // private static final ColorProperty COLOR_PROP = ColorProperty.HUE;
    // private static final ColorProperty COLOR_PROP = ColorProperty.BRIGHTNESS;
    private static final ColorProperty COLOR_PROP = ColorProperty.SATURATION;

    private static void createAndShowGui() {
        HsvChooserPanel2 hsvChooserPanel = new HsvChooserPanel2(COLOR_PROP);

        JPanel testPanel = new JPanel();
        JPanel outerPanel = new JPanel(new BorderLayout());
        outerPanel.add(testPanel);
        outerPanel.setBorder(BorderFactory.createTitledBorder("Test Panel"));

        hsvChooserPanel.addPropertyChangeListener(HsvChooserPanel2.COLOR, pce -> {
            Color c = (Color) pce.getNewValue();
            testPanel.setBackground(c);
        });

        JPanel gridPanel = new JPanel(new GridLayout(0, 1, 10, 10));
        gridPanel.add(hsvChooserPanel);
        gridPanel.add(outerPanel);

        JFrame frame = new JFrame("HSV Chooser");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(gridPanel);
        frame.setResizable(false);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

整个shebang:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.event.SwingPropertyChangeSupport;

@SuppressWarnings("serial")
public class HsvChooserPanel2 extends JPanel {
    public static final String COLOR = "color";
    private static final int PREF_W = 180;
    private static final int PREF_H = PREF_W;
    private static final int PREF_W_CB = 20;
    private static final int GAP = 10;
    private MyColorPanel2 colorPanel = null;
    private MyColorBar2 colorBar = null;
    private InnerControl2 innerControl = null;

    public HsvChooserPanel2(ColorProperty colorProp) {
        colorPanel = new MyColorPanel2(PREF_W, PREF_H, colorProp);
        colorBar = new MyColorBar2(PREF_W_CB, PREF_H, colorProp);
        innerControl = new InnerControl2(this, colorPanel, colorBar);
        colorPanel.setColorPropertyValue(Color.RED); // !! magic value
        setLayout(new BorderLayout(GAP, GAP));
        setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
        add(colorPanel, BorderLayout.CENTER);
        add(colorBar, BorderLayout.LINE_END);

        // propagate COLOR changes in the inner controller
        // to this component's property change support
        innerControl.addPropertyChangeListener(COLOR, pce -> {
            firePropertyChange(COLOR, pce.getOldValue(), pce.getNewValue());
        });
    }


}
// listens for changes to both the color bar and the color panel
class InnerControl2 {
    private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);

    private HsvChooserPanel2 hsvChooser;
    private MyColorPanel2 colorPanel;
    private MyColorBar2 colorBar;
    private Color color; // This is all there is to the model, a "bound"
                         // property

    public InnerControl2(HsvChooserPanel2 hsvChooser, MyColorPanel2 colorPanel, MyColorBar2 colorBar) {
        this.hsvChooser = hsvChooser;
        this.colorPanel = colorPanel;
        this.colorBar = colorBar;

        // listen for changes
        colorPanel.addPropertyChangeListener(ColorPanelParent.CURSOR, new ColorPanelListener());
        colorBar.addPropertyChangeListener(ColorPanelParent.CURSOR, new ColorBarListener());
    }

    public Color getColor() {
        return color;
    }

    // classic setter method for a "bound" property
    public void setColor(Color color) {
        Color oldValue = this.color;
        Color newValue = color;
        this.color = color;
        // notify listeners of the change
        pcSupport.firePropertyChange(HsvChooserPanel2.COLOR, oldValue, newValue);
    }

    // allow outside classes the ability to listen
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        pcSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcSupport.removePropertyChangeListener(listener);
    }

    public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
        pcSupport.addPropertyChangeListener(name, listener);
    }

    public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
        pcSupport.removePropertyChangeListener(name, listener);
    }

    public HsvChooserPanel2 getHsvChooser() {
        return hsvChooser;
    }

    // inner listeners
    private class ColorPanelListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            Point p = colorPanel.getCursorP();
            Color c = colorPanel.getColor(p);
            colorBar.setColorPropertyValue(c);
            setColor(c); // this will fire the prop change
                                              // support
        }
    }

    private class ColorBarListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            // get hue from the color bar and use it to set the main hue
            // of the color panel
            Point p = colorBar.getCursorP();
            Color c = colorBar.getColor(p);
            colorPanel.setColorPropertyValue(c);
        }
    }
}
// parent of both color bar panel and color panel
@SuppressWarnings("serial")
abstract class ColorPanelParent extends JPanel {
    public static final String CURSOR = "cursor";
    private int prefW;
    private int prefH;
    private Point cursorP = new Point(0, 0);
    private BufferedImage img = null;
    private ColorProperty colorProperty;
    private boolean panel;

    public ColorPanelParent(int prefW, int prefH, ColorProperty colorProperty, boolean panel) {
        this.prefW = prefW;
        this.prefH = prefH;
        this.colorProperty = colorProperty;
        this.panel = panel;
        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(prefW, prefH);
    }

    public int getPrefH() {
        return prefH;
    }

    public int getPrefW() {
        return prefW;
    }

    public ColorProperty getColorProperty() {
        return colorProperty;
    }

    public BufferedImage getImg() {
        return img;
    }

    public Point getCursorP() {
        return cursorP;
    }

    public void setImg(BufferedImage img) {
        this.img = img;
        repaint();
    }

    public Color getColor(Point p) {
        Color c = null;
        if (getImg() != null) {
            int rgb = getImg().getRGB(p.x, p.y);
            c = new Color(rgb);
        }
        return c;
    }

    // when the main hue is changed, we have to create a new
    // background image to reflect the new main color
    public void setColorPropertyValue(Color color) {
        int w = getPrefW();
        int h = getPrefH();
        BufferedImage img = getColorProperty().createImage(color, w, h, panel);
        setImg(img);
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            g.drawImage(img, 0, 0, this);
        }
    }

    // change the cursor point and then
    // notify prop change support of changes
    private class MyMouse extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            mouseResponse(e);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            mouseResponse(e);
        }

        private void mouseResponse(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            if (!contains(e.getPoint())) {
                x = Math.max(0, x);
                x = Math.min(prefW - 1, x);
                y = Math.max(0, y);
                y = Math.min(prefH - 1, y);
            }
            Point oldValue = cursorP;
            cursorP = new Point(x, y);
            firePropertyChange(CURSOR, oldValue, cursorP);
            repaint();
        }
    }

}
// color bar on the right side of the HsvChooser JPanel.
// Controller action: Changing selection point on this JPanel
// will change the hue of the color panel
@SuppressWarnings("serial")
class MyColorBar2 extends ColorPanelParent {

    public MyColorBar2(int prefW, int prefH, ColorProperty colorProperty) {
        super(prefW, prefH, colorProperty, false);

        // create and set the background image
        setColorPropertyValue(Color.RED); // fix the magic number?
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // draws the background image

        // this draws a line at the cursor's location
        g.setXORMode(Color.WHITE);
        int y = getCursorP().y;
        g.drawLine(0, y, getPrefW(), y);
    }

}
// color panel on the left side of the HsvChooser JPanel.
// Controller action: Changing selection point on this JPanel
// will notify listeners of a new COLOR selection
@SuppressWarnings("serial")
class MyColorPanel2 extends ColorPanelParent {
    private static final int CURSOR_RADIUS = 8;

    public MyColorPanel2(int prefW, int prefH, ColorProperty colorProperty) {
        super(prefW, prefH, colorProperty, true);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // draws the background image

        // draws the cross hatch indicating color selection point
        g.setXORMode(Color.WHITE);
        int x = getCursorP().x;
        int y = getCursorP().y;
        int x1 = x - CURSOR_RADIUS;
        int y1 = y - CURSOR_RADIUS;
        int x2 = x + CURSOR_RADIUS;
        int y2 = y + CURSOR_RADIUS;
        g.drawLine(x1, y, x2, y);
        g.drawLine(x, y1, x, y2);
    }
}
enum ColorProperty {
    HUE {
        @Override
        public BufferedImage createImage(Color color, int w, int h, boolean panel) {
            BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

            if (panel) {
                int red = color.getRed();
                int green = color.getGreen();
                int blue = color.getBlue();
                // float array is HSB
                float hue = Color.RGBtoHSB(red, green, blue, null)[0]; 

                for (int i = 0; i < h; i++) {
                    for (int j = 0; j < w; j++) {
                        float s = ((float) j) / (float) w;
                        float b = (h - (float) i) / (float) h;
                        int rgb = Color.getHSBColor(hue, s, b).getRGB();
                        img.setRGB(j, i, rgb);
                    }
                }
            } else {
                for (int i = 0; i < h; i++) {
                    for (int j = 0; j < w; j++) {
                        float hue = (h - (float) i) / (float) h;
                        int rgb = Color.getHSBColor(hue, 1f, 1f).getRGB();
                        img.setRGB(j, i, rgb);
                    }
                }
            }
            return img;
        }
    },
    SATURATION {
        @Override
        public BufferedImage createImage(Color color, int w, int h, boolean panel) {
            BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            int red = color.getRed();
            int green = color.getGreen();
            int blue = color.getBlue();
            // float array is HSB
            float[] hsb = Color.RGBtoHSB(red, green, blue, null);

            return panel ? createPanelImg(w, h, img, hsb) : createBarImg(w, h, img, hsb);
        }

        private BufferedImage createBarImg(int w, int h, BufferedImage img, float[] hsb) {
            float hue = hsb[0];
            // float brightness = hsb[2];
            float brightness = 1f;
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    float saturation = (h - (float) i) / (float) h;
                    int rgb = Color.getHSBColor(hue, saturation, brightness).getRGB();
                    img.setRGB(j, i, rgb);
                }
            }
            return img;
        }

        private BufferedImage createPanelImg(int w, int h, BufferedImage img, float[] hsb) {
            float saturation = hsb[1]; 
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    float hue = ((float) j) / (float) w;
                    float b = (h - (float) i) / (float) h;
                    int rgb = Color.getHSBColor(hue, saturation, b).getRGB();
                    img.setRGB(j, i, rgb);
                }
            }            
            return img;
        }
    },
    BRIGHTNESS {
        @Override
        public BufferedImage createImage(Color color, int w, int h, boolean panel) {
            BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            int red = color.getRed();
            int green = color.getGreen();
            int blue = color.getBlue();
            // float array is HSB
            float[] hsb = Color.RGBtoHSB(red, green, blue, null);

            return panel ? createPanelImg(w, h, img, hsb) : createBarImg(w, h, img, hsb);
        }

        private BufferedImage createBarImg(int w, int h, BufferedImage img, float[] hsb) {
            float hue = hsb[0];
            // float saturation = hsb[1];
            float saturation = 1f;
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    float brightness = (h - (float) i) / (float) h;
                    int rgb = Color.getHSBColor(hue, saturation, brightness).getRGB();
                    img.setRGB(j, i, rgb);
                }
            }
            return img;
        }

        private BufferedImage createPanelImg(int w, int h, BufferedImage img, float[] hsb) {
            float brightness = hsb[2]; 
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    float hue = ((float) j) / (float) w;
                    float saturation = (h - (float) i) / (float) h;
                    int rgb = Color.getHSBColor(hue, saturation, brightness).getRGB();
                    img.setRGB(j, i, rgb);
                }
            }            
            return img;
        }
    };

    public abstract BufferedImage createImage(Color color, int w, int h, boolean panel);
}

这篇关于如何仅显示 JColorChooser 的 HSV 框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 08:45