Home > database >  How to listen default color change inside my custom JComponent?
How to listen default color change inside my custom JComponent?

Time:12-03

I am the author of some JComponent extension. I wrote some example components.

In one example components I am just populating them with predefined subcomponents:

public class JSwingExample02 extends JComponent {

    public JSwingExample02() {
        populate();
    }

    private void populate() {
        setLayout(new BorderLayout());
        JLabel jLabel = new JLabel("Hello World!");
        add(jLabel, BorderLayout.CENTER);
    }

in other components I am drawing them from scratch

@Override protected void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;

    g2.fillOval(10, 10, 100, 100);
}

Now my components are used from withing third party code (IDEA Plugin) and it applies color theme for it: my components are shown in "dark theme" although I have no any line of code for color.

For example

enter image description here

i.e. text is white.

How can I LISTEN to these colors, i.e. know them beforehand, if I want for example, to draw something explicit with them?

CodePudding user response:

There are different ways to get and set colors. Here are a few. This creates a simple frame/panel combination to show the background color. You can also set the color in the paintComponent method. There it will be foreground or background depending on what you are painting.

A nice way to offer the user to select color is the JColorChooser. It can accept a default color and return whatever is selected.

If you really want to know when a color has changed you need to establish a listener for the component and listen for property changes. The example shows the demo panel listening for foreground and background color changes. Each of your components must register a property listeners to handle events.

NOTE: The Demo class is actually listening for its own changes. This does not have to be the case. Any class that implements the PropertyChangeListener interface may listen for property change events from any other class that fires property changes. Just make certain that particular class instance is used when registering events.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ColorDemo extends JPanel implements PropertyChangeListener{
    
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ColorDemo demo = new ColorDemo();           
        demo.setPreferredSize(new Dimension(200,200));

        // listen for these properties
        demo.addPropertyChangeListener("background", demo );
        demo.addPropertyChangeListener("foreground", demo );
        
        frame.add(demo);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        
        
        demo.setBackground(Color.CYAN);
        System.out.println(
                "back ground color is : "   demo.getBackground());
        demo.setVisible(true);
        // use color chooser
        Color newColor = JColorChooser.showDialog(null,
                "Color Chooser", demo.getBackground());
        System.out.println(
                "Retrieved new color from chooser "   newColor);
        System.out.println(
                "default foreground color is :"   demo.getForeground());
        
        demo.setForeground(Color.RED);
        demo.repaint();
    }
        
    public void paintComponent(Graphics g) {
            super.paintComponent(g);
            System.out.println(
                    "Graphics context color : "   g.getColor());
        }
    
    public void propertyChange(PropertyChangeEvent pce) {
        String name = pce.getPropertyName();
        System.out.println(name   " change caught");
        System.out.println("old "   name   " was "   pce.getOldValue());
        System.out.println("new "   name   " is "   pce.getNewValue());
        System.out.println();
    }
}

CodePudding user response:

Try to set LAF and listen to LAF changes:

class JSwingExample02 extends JComponent  {

    public JSwingExample02(PropertyChangeListener listener) {
        //set LAF
        try {
            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
            ex.printStackTrace();
        }
        //listen to LAF changes
        UIManager.addPropertyChangeListener(listener);
        populate();
    }

    private void populate() {
        setLayout(new BorderLayout());
        JLabel jLabel = new JLabel("Hello World!");
        add(jLabel, BorderLayout.CENTER);
    }

    //returns active LAF
    public LookAndFeel lookAndFeel(){
        return UIManager.getLookAndFeel();
    }
}

"lookAndFeel" property change is fired when LAF changes.
See this Q&A for a list of other properties.

  • Related