Question

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.

Was it helpful?

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

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top