3

I'm trying to create a JFrame including a JPanel containing only the stuff necessary to choose a RGB color. I've been messing around with JColorChooser, AbstractColorChooserPanel and ColorModel, reading Oracle tutorials, but I didn't get to understand how to develop exactly what I want. I've even downloaded OpenJDK source to fetch the source codes of these classes, but still nothing. What I want to get is this:

What I want

The Alpha stuff should disappear and the color code field should be set to invisible but keep working so I can retrieve the code when the "Yes" button is clicked (within an actionPerformed method, I guess). As well it'd be a nice addition to override the paintComponent method.

Thanks in advance.

EDIT: This is how I get what I currently have (the above photo, without the 'Paint'-edits):

for (final AbstractColorChooserPanel accp : panels) {
  if (accp.getDisplayName().equals("RGB")) {
    JOptionPane.showOptionDialog(Main.frame, accp,
    "Color selection tool", JOptionPane.OK_OPTION,
    JOptionPane.QUESTION_MESSAGE, null, null, 0);
  }
}

EDIT2: By far, I've now been able to get to delete the alpha stuff, but I can't yet get to 'find' the label and field showing the Color Code, so they keep showing and, additionally, since I can't access the field, I can't access the color code:

achieved

This is with this code:

package edu.utils;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Array;
import java.lang.reflect.Field;

import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.WindowConstants;
import javax.swing.colorchooser.AbstractColorChooserPanel;

import edu.io.local.Log;

public final class RGBColorChooserPanel extends JDialog implements ActionListener {

private final JColorChooser jCC;
private final JPanel        panel;
private String              colorCode;

public RGBColorChooserPanel(final String title) {
super(edu.Main.frame);
this.setTitle(title);
this.jCC = new JColorChooser();
this.modifyJColorChooser();
this.panel = new JPanel() {
    @Override
    protected void paintComponent(final Graphics g) {
    final Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    final GradientPaint gp = new GradientPaint(0, 0, Color.BLUE, 0, this.getHeight(),
            Color.BLACK);

    g2d.setPaint(gp);
    g2d.fillRect(0, 0, this.getWidth(), this.getHeight());

    super.paintComponent(g);
    }
};
this.panel.add(this.jCC);
this.panel.setOpaque(false);
this.jCC.setOpaque(false);
this.jCC.setPreviewPanel(new JPanel());
this.jCC.setColor(120, 20, 57);
this.add(this.panel, BorderLayout.CENTER);
this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
this.pack();

final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation((screenSize.width - this.getWidth()) / 2,
        (screenSize.height - this.getHeight()) / 2);
this.setResizable(false);
this.setVisible(true);
}

@Override
public void actionPerformed(final ActionEvent e) {
// TODO Auto-generated method stub

}

private void modifyJColorChooser() {
final AbstractColorChooserPanel[] panels = this.jCC.getChooserPanels();
for (final AbstractColorChooserPanel accp : panels) {
    if (!accp.getDisplayName().equals("RGB")) {
    this.jCC.removeChooserPanel(accp);
    }
}

final AbstractColorChooserPanel[] colorPanels = this.jCC.getChooserPanels();
final AbstractColorChooserPanel cp = colorPanels[0];

Field f = null;
try {
    f = cp.getClass().getDeclaredField("panel");
} catch (NoSuchFieldException | SecurityException e) {
    Log.log(e);
}
f.setAccessible(true);

Object colorPanel = null;
try {
    colorPanel = f.get(cp);
} catch (IllegalArgumentException | IllegalAccessException e) {
    Log.log(e);
}

Field f2 = null;
try {
    f2 = colorPanel.getClass().getDeclaredField("spinners");
} catch (NoSuchFieldException | SecurityException e4) {
    Log.log(e4);
}
f2.setAccessible(true);
Object rows = null;
try {
    rows = f2.get(colorPanel);
} catch (IllegalArgumentException | IllegalAccessException e3) {
    Log.log(e3);
}

final Object transpSlispinner = Array.get(rows, 3);
Field f3 = null;
try {
    f3 = transpSlispinner.getClass().getDeclaredField("slider");
} catch (NoSuchFieldException | SecurityException e) {
    Log.log(e);
}
f3.setAccessible(true);
JSlider slider = null;
try {
    slider = (JSlider) f3.get(transpSlispinner);
} catch (IllegalArgumentException | IllegalAccessException e2) {
    Log.log(e2);
}
slider.setVisible(false);
Field f4 = null;
try {
    f4 = transpSlispinner.getClass().getDeclaredField("spinner");
} catch (NoSuchFieldException | SecurityException e1) {
    Log.log(e1);
}
f4.setAccessible(true);
JSpinner spinner = null;
try {
    spinner = (JSpinner) f4.get(transpSlispinner);
} catch (IllegalArgumentException | IllegalAccessException e) {
    Log.log(e);
}
spinner.setVisible(false);
Field f5 = null;
try {
    f5 = transpSlispinner.getClass().getDeclaredField("label");
} catch (NoSuchFieldException | SecurityException e1) {
    Log.log(e1);
}
f5.setAccessible(true);
JLabel label = null;
try {
    label = (JLabel) f5.get(transpSlispinner);
} catch (IllegalArgumentException | IllegalAccessException e) {
    Log.log(e);
}
label.setVisible(false);

Field f6 = null;
try {
    f6 = transpSlispinner.getClass().getDeclaredField("value");
} catch (NoSuchFieldException | SecurityException e1) {
    Log.log(e1);
}
f6.setAccessible(true);
float value = 0;
try {
    value = (float) f6.get(transpSlispinner);
} catch (IllegalArgumentException | IllegalAccessException e) {
    Log.log(e);
}
}
}

PS: I know about the weirdness of the exception handling, but I need to manage exceptions per-statement, so please no complaints on that.

Boann
  • 48,794
  • 16
  • 117
  • 146
  • 5
    Have a look at http://stackoverflow.com/questions/12026767/java-7-jcolorchooser-disable-transparency-slider – Cyrille Ka Mar 05 '13 at 15:31
  • Using reflection as suggested in the first reply looks like a hard way to get such a simple thing. If that's the quickest way, I think Oracle should seriously think about redesigning the JColorChooser class. Anyway, I think I can get something from that. I'll edit my post with the final code if I get to it. – Jorge Antonio Díaz-Benito Mar 05 '13 at 15:45
  • Your better option is [*Creating a Custom Chooser Panel*](http://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html#chooserpanel) by extending `AbstractColorChooserPanel`. – trashgod Mar 05 '13 at 16:19
  • @trashgod I told I already was working with Oracle tutorials and even with the source. Obviously, I saw that tutorial you link to, and my first option of course was extending AbstractColorChooserPanel. However, the "class extending AbstractColorChooserPanel" that the example you link to shows is completely useless. Everybody knows how to add four buttons with icons. But I don't think dealing with color pickers is that common, so I don't know how to construct the Panel. I'll give another try to OpenJDK trying to see where the RGB tab of a normal JColorChooser is initialized, though. – Jorge Antonio Díaz-Benito Mar 05 '13 at 18:06
  • @CyrilleKarmann Please it would be very nice if you could take a look to my EDIT2 and check if you know how to access the field and label I'm missing (see the EDIT2 for further explanation). – Jorge Antonio Díaz-Benito Mar 05 '13 at 18:07
  • 1
    @JorgeAntonioDíaz-Benito: I think I understand your point. I don't have a complete example; I've tried to elaborate [here](http://stackoverflow.com/a/15235247/230513). – trashgod Mar 05 '13 at 22:23
  • Looks like a very nice approach. No time to test it out, though (you know, customer prefers bad but today rather than tomorrow well). I already adopted as an alternative a JPanel with sliders and a label in which the current built color is shown. But I'll keep the link to have a further look at it later, thanks. – Jorge Antonio Díaz-Benito Mar 06 '13 at 02:06

1 Answers1

5

Your best option is Creating a Custom Chooser Panel by extending AbstractColorChooserPanel. The tutorial example, while elementary, is a useful guide to installation and usage. A complete implementation of your sketch is beyond the scope of SO; but among the many extant examples, this one and this one seem worth closer examination. This related Q&A may also offer some insight.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045