Search code examples
javaswinguser-interfacecolor-picker

How to continuously update scene color while adjusting JColorChooser?


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.


Solution

  • 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();
                }
            });
        }
    }