1

I am in the process of translating a python/Qt GUI application into Java/Swing. The original application beautifully updates the scene color continuously as the user drags the sliders in a QColorDialog. How can I get a similar effect in a JColorChooser? All the examples I have found update the color only when the user clicks the "Apply" or "OK" button. Is there a mechanism for listening to continuous color changes in a JColorChooser as my user drags, say, the "Red" slider?

// How can I listen to every color adjustment?
// (i.e. not just when the user presses "Apply" or "OK"?)
ActionListener actionListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent arg0) {
        System.out.println("color changed");
    }
};
Dialog colorDialog = JColorChooser.createDialog(ColorChannelWidget.this,
        "Select color for channel 3",
        false, // not modal
        new JColorChooser(Color.pink),
        actionListener, actionListener);
colorDialog.setVisible(true);

Edit:

The colors I will be changing are in a dynamically generated OpenGL scene. Not, say, a static image.

Christopher Bruns
  • 9,160
  • 7
  • 46
  • 61
  • You would have to hack into `JColorChooser` for that! – Extreme Coders Feb 24 '13 at 15:08
  • @ExtremeCoders: `JColorChooser` is designed to allow [*Creating a Custom Chooser Panel*](http://docs.oracle.com/javase/tutorial/uiswing/components/colorchooser.html#chooserpanel). – trashgod Feb 24 '13 at 15:17
  • I believe my answer remains valid whichever the target is. It provides a hook for continuously being notified of selected color changes in the color chooser. The fact that you target a JPanel or a OpenGL 3D scene is a different aspect of your problem. Or am I missing something here? – Guillaume Polet Feb 24 '13 at 15:39
  • The brief answer to this question is that I needed to keep a handle to that new JColorChooser, so I could then getSelectionModel().addChangeListener(...) on it. – Christopher Bruns Feb 24 '13 at 15:48
  • @Guillaume My edit was in response to trashgod's answer. Not sure why you thought it was directed at you. – Christopher Bruns Feb 24 '13 at 15:50
  • Because he referenced me in his answer. Never mind ;-) Good luck in your implementation. Cheers. – Guillaume Polet Feb 24 '13 at 18:08
  • @GuillaumePolet: Apologies for sowing confusion; your `ChangeListener` example is +1 cogent. ChristopherBruns: Adding the [tag:opengl] tag might also be appropriate. – trashgod Feb 24 '13 at 18:27
  • @trashgod Re: OpenGL tag: My question and the accepted answer are not specific to OpenGL. Perhaps if there were a tag not-just-static-images... :) – Christopher Bruns Feb 24 '13 at 20:32
  • @ChristopherBruns: Thanks for commenting; sorry for the extended colloquy; I defer to you. – trashgod Feb 24 '13 at 23:50

2 Answers2

4

You will need to create your own instance of JColorChooser and JDialog so that you can attach a ChangeListener to the ColorSelectionModel of the JColorChooser.

Here is a small demo code that shows how to perform such operations:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TestColorChooser {

    protected void initUI() {
        JFrame frame = new JFrame(TestColorChooser.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JPanel panel = new JPanel() {
            @Override
            public java.awt.Dimension getPreferredSize() {
                return new Dimension(400, 400);
            };
        };
        final JButton button = new JButton("Click me to change color");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Window parentWindow = SwingUtilities.windowForComponent(button);
                final JColorChooser chooser = new JColorChooser(panel.getBackground());
                chooser.getSelectionModel().addChangeListener(new ChangeListener() {

                    @Override
                    public void stateChanged(ChangeEvent e) {
                        panel.setBackground(chooser.getColor());
                    }
                });
                JDialog dialog = new JDialog(parentWindow);
                dialog.add(chooser);
                dialog.pack();
                dialog.setLocation(panel.getLocationOnScreen().x + panel.getWidth(), panel.getLocationOnScreen().y);
                dialog.setVisible(true);
            }
        });
        frame.add(panel);
        frame.add(button, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestColorChooser().initUI();
            }
        });
    }
}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
4

Using @Guillaume's approach, java.awt.image.RescaleOp can be used to change the colors of an image dynamically. Examples may be found here, here and here.

image

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Sorry I did not write a detailed enough question. Your suggestion is great for recoloring a static image. But I am rather recoloring a dynamically generated 3D OpenGL scene. – Christopher Bruns Feb 24 '13 at 15:17