javaswingjcolorchooser

Set foreground and background color of JButton with JColorChooser


I have a simple application which consists of a JButton and a JColorChooser. When i press the button 2 JColorChoosers appear.The one allows me to select a background color and the second one allows me to select a foreground color. I save each color in a separate variable.Here is my code:

    public class Slide extends JFrame{

        Color bgColor;
        JButton colorButton=new JButton();
        JColorChooser colorPicker=new JColorChooser();
        public Slide(){
            JPanel panel=new JPanel();
            panel.setLayout(new MigLayout("", "[][][][][]", "[][][][][][]"));
            this.setContentPane(panel);
            colorButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    //1st color chooser for background color
                    bgColor=JColorChooser.showDialog(null, "Background color", null);
//2nd colorchooser appears for foreground
                    Color fgColor=JColorChooser.showDialog(null, "Foreground color", null);
                    colorButton.setBackground(bgColor);
                    colorButton.setForeground(fgColor);
                }
            });
            colorButton.setText("Pick a color");
            panel.add(colorButton, "cell 0 5");
            this.setSize(400, 400);
            this.setVisible(true);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        }

        public static void main(String args[]){
            new Slide();
        }
    }

Now my question is:Is it possible to minimize the part of the JColorChooser.I mean I want to show The JColorChooser only once and get both foreground and background colors from the user


Solution

  • I don't think you can use JOptionPane for this, as the dialog would disappear immediately after you press a button holding an option.


    You could make your own JDialog that has a JColorChooser in the center and some buttons like Set Foreground and Set Background at the bottom; This way you don't have to call 2 JColorChoosers:

    enter image description here

    Code:

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JColorChooser;
    import javax.swing.JComponent;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class Example {
    
        public Example() {
    
            JButton button = new JButton("Button");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    CustomColorChooserDialog dialog = new CustomColorChooserDialog(button);
                    dialog.setVisible(true);
                }
            });
    
            JFrame frame = new JFrame();
            frame.getContentPane().setLayout(new FlowLayout());
            frame.getContentPane().add(button);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String args[]) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Example();
                }
            });
        }
    }
    
    class CustomColorChooserDialog extends JDialog {
    
        JComponent targetComponent;
        JColorChooser colorChooser;
        JButton backgroundButton;
        JButton foregroundButton;
        JButton okButton;
    
        public CustomColorChooserDialog(JComponent targetComponent) {
    
            this.targetComponent = targetComponent;
    
            colorChooser = new JColorChooser();
    
            ButtonActionListener listener = new ButtonActionListener();
    
            backgroundButton = new JButton("Set Background");
            backgroundButton.addActionListener(listener);
    
            foregroundButton = new JButton("Set Foreground");
            foregroundButton.addActionListener(listener);
    
            okButton = new JButton("OK");
            okButton.addActionListener(listener);
    
            JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
            buttonPanel.add(backgroundButton);
            buttonPanel.add(foregroundButton);
            buttonPanel.add(okButton);
    
            getContentPane().add(colorChooser, BorderLayout.CENTER);
            getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
    
            pack();
            setModal(true);
            setLocationRelativeTo(targetComponent);
    
        }
    
        private class ButtonActionListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource().equals(backgroundButton)) {
                    targetComponent.setBackground(colorChooser.getColor());
                } else if (e.getSource().equals(foregroundButton)) {
                    targetComponent.setForeground(colorChooser.getColor());
                } else if (e.getSource().equals(okButton)) {
                    dispose();
                }
            }
        }
    
    }