If you look at the JColorChooser component, you'll realize that it is really just a tabbed pane with a color previewer below it. You can have as many chooser panels in it as you like. Let's take a brief look at a panel that can be added to a color chooser. We'll create a simple panel for selecting a shade of gray with one slider rather than pushing each slider for red, green, and blue to the same value. Figure 12-8 shows the resulting panel; its source code is presented here. // GrayScalePanel.java // A simple implementation of the AbstractColorChooserPanel class. This class // provides a slider and a text field for picking out a shade of gray. // import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.colorchooser.*; public class GrayScalePanel extends AbstractColorChooserPanel implements ChangeListener, ActionListener { JSlider scale; JTextField percentField; // Set up our list of grays. We'll assume we have all 256 possible shades, // and we'll do it when the class is loaded. static Color[] grays = new Color[256]; static { for (int i=0; i<256; i++) { grays[i] = new Color(i, i, i); } } public GrayScalePanel( ) { setLayout(new GridLayout(0, 1)); // Create the slider and attach us as a listener. scale = new JSlider(JSlider.HORIZONTAL, 0, 255, 128); scale.addChangeListener(this); // Set up our display for the chooser. add(new JLabel("Pick your shade of gray:", JLabel.CENTER)); JPanel jp = new JPanel( ); jp.add(new JLabel("Black")); jp.add(scale); jp.add(new JLabel("White")); add(jp); JPanel jp2 = new JPanel( ); percentField = new JTextField(3); percentField.setHorizontalAlignment(SwingConstants.RIGHT); percentField.addActionListener(this); jp2.add(percentField); jp2.add(new JLabel("%")); add(jp2); } // We did this work in the constructor, so we can skip it here. protected void buildChooser( ) { } // Make sure the slider is in sync with the other panels. public void updateChooser( ) { Color c = getColorSelectionModel( ).getSelectedColor( ); scale.setValue(toGray(c)); } protected int toGray(Color c) { int r = c.getRed( ); int g = c.getGreen( ); int b = c.getBlue( ); // Grab the luminance the same way GIMP does. return (int)Math.round(0.3 * r + 0.59 * g + 0.11 * b ); } // Pick a name for our tab in the chooser. public String getDisplayName( ) { return "Gray Scale"; } // No need for an icon public Icon getSmallDisplayIcon( ) { return null; } public Icon getLargeDisplayIcon( ) { return null; } // Finally, update the selection model as our slider changes. public void stateChanged(ChangeEvent ce) { getColorSelectionModel( ).setSelectedColor(grays[scale.getValue( )]); percentField.setText("" + (100-(int)Math.round(scale.getValue( ) / 2.55))); } public void actionPerformed(ActionEvent ae) { int val = 100 - Integer.parseInt(ae.getActionCommand( )); getColorSelectionModel( ).setSelectedColor(grays[(int)(val * 2.55)]); } } Figure 12-8. A custom chooser panel added directly to a JColorChooser objectHere's the application that produced the new chooser. The only real change is that we manually build the list of chooser panels for our chooser in the ColorPicker2 constructor: // ColorPicker2.java // A quick test of the JColorChooser dialog // import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.colorchooser.*; public class ColorPicker2 extends JFrame { JFrame parent; Color c; public ColorPicker2( ) { super("JColorChooser Test Frame"); setSize(200, 100); parent=this; final JButton go = new JButton("Show JColorChoser"); final Container contentPane = getContentPane( ); go.addActionListener(new ActionListener( ) { final JColorChooser chooser = new JColorChooser( ); boolean first = true; public void actionPerformed(ActionEvent e) { if (first) { first = false; GrayScalePanel gsp = new GrayScalePanel( ); chooser.addChooserPanel(gsp); } JDialog dialog = JColorChooser.createDialog(parent, "Demo 2", true, chooser, new ActionListener( ) { public void actionPerformed(ActionEvent e) { c = chooser.getColor( ); }}, null); dialog.setVisible(true); contentPane.setBackground(c); } }); contentPane.add(go); setDefaultCloseOperation(EXIT_ON_CLOSE); } public static void main(String args[]) { ColorPicker2 cp2 = new ColorPicker2( ); cp2.setVisible(true); } } |