首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何仅显示JColorChooser的HSV框?

如何仅显示JColorChooser的HSV框?
EN

Stack Overflow用户
提问于 2017-05-29 01:04:09
回答 4查看 1.5K关注 0票数 3

在此图像中,您可以看到默认的Java颜色选择器JColorChooser

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

我能够删除所有的选项卡(样本,HSL等)和预览,但我无法删除所有的滑块。我该怎么做?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-05-29 15:06:25

好的,只是为了好玩,我决定从头开始创建你想要的JPanel,把它连接到某种视图控制器中,因为这里的模型很简单--控制器中的一个颜色字段。要使用该组件,可以创建组件的实例,在需要的地方将其添加到GUI中,并向其添加一个监听其颜色属性的PropertyChangeListener:

代码语言:javascript
复制
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的计算。欢迎评论:

代码语言:javascript
复制
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());
    }
}

整个爆炸:

代码语言:javascript
复制
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());
        });
    }


}

代码语言:javascript
复制
// 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);
        }
    }
}

代码语言:javascript
复制
// 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();
        }
    }

}

代码语言:javascript
复制
// 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);
    }

}

代码语言:javascript
复制
// 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);
    }
}

代码语言:javascript
复制
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);
}
票数 3
EN

Stack Overflow用户

发布于 2017-05-29 04:16:00

查看一下javax.swing.colorchooser内部,就会发现ColorChooserComponentFactory使用ColorChooserPanel和合适的ColorModel子类创建了AbstractColorChooserPanel的子类。ColorChooserPanel将所需的部分保存为DiagramComponent的两个实例:左侧命名为diagram,右边命名为slider

与其从现有的ColorChooserPanel中删除组件,不如考虑只包含所需元素的https://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html#chooserpanel

代码语言:javascript
复制
class MyChooserPanel extends AbstractColorChooserPanel implements PropertyChangeListener {

    private final ColorModel model;
    private final DiagramComponent diagram;
    private final DiagramComponent slider;

    MyChooserPanel(ColorModel model) {
        this.model = model;
        this.diagram = new DiagramComponent(this.panel, true);
        this.slider = new DiagramComponent(this.panel, false);
    }
    …
}

当然,您将不得不重复一些(包)私有代码,但是结果就不会那么脆弱了。

票数 3
EN

Stack Overflow用户

发布于 2017-05-29 04:42:26

我的解决方案:

代码语言:javascript
复制
        colorChooser.setPreviewPanel(new JPanel());
        AbstractColorChooserPanel[] panels = colorChooser.getChooserPanels();
        for (AbstractColorChooserPanel accp : panels) {
            if(!accp.getDisplayName().equals("HSV")) {
                colorChooser.removeChooserPanel(accp);
            } 
        }
        JComponent current = (JComponent) colorChooser.getComponents()[0];
        while( !current.getClass().toString().equals( "class javax.swing.colorchooser.ColorChooserPanel" ) ){
            current = (JComponent) current.getComponents()[0]; 
        }
        for(Component jc : current.getComponents()){
            if(!jc.getClass().toString().equals( "class javax.swing.colorchooser.DiagramComponent" )){
                current.remove(jc);
            }
        }  

这消除了所有我不想要的东西,但我认为做一个定制的解决方案会更好。

我要试试垃圾桶看看它是否更好用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44233428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档