2

I'm going to enhance an application with a Swing UI, to allow the user to pick colors so they're not stuck with the default color choices.

It is common for other applications to have shaded rectangles drawn on each button that activates a color selector, with the rectangle's color changing accordingly when a new color is selected. I am trying to achieve the same effect by placing a small JPanel with the selected color on the button, but that results in a tiny square in the middle of the button, instead of filling most of the surface of the button.

I figure another way would be to dynamically generate rectangular icons with the colors and then add the appropriate icon to each button, but surely there must be a simpler way?

Gigatron
  • 1,995
  • 6
  • 20
  • 27
  • Since there is no way of making a custom renderer for the buttons, I don't think it will be very easy. But I guess you could always make a custom button (say, ColourButton). Otherwise your solution with the icons seems pretty nice. – MarioDS Apr 26 '12 at 13:02
  • Have you tried setBackground(Color) on the Button (make sure the button is opaque with setOpaque(boolean))? – Guillaume Polet Apr 26 '12 at 13:02
  • Yes, I've tried `setBackground()` but it only changes the color in a rectangle surrounding the button, it doesn't change the surface color of the button. – Gigatron Apr 26 '12 at 13:04

3 Answers3

3

put there JButton.setIcon with expected Rectangle, for example

EDIT

I am trying to achieve the same effect by placing a small JPanel with the selected color on the button, but that results in a tiny square in the middle of the button, instead of filling most of the surface of the button.

only JFrame (BorderLayout) and JPanel (FlowLayout) have got pre-implemented LayoutManager, for rest of JComponents (add one JComponent to the another JComponent) you have to define LayoutManager, please read this thread

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I think this approach would not only be more robust than setting the BG as suggested in other answers, but would also be more like the user experience 'the path of least surprise' the OP is after. Lovely little addition by @trashgod, though I'm still undecided between using an `Icon` and altering the `Graphics` of a `BufferedImage`. – Andrew Thompson Apr 26 '12 at 13:38
  • @AndrewThompson: Good points. I'll implement `Icon` when I want to leverage a component's text alignment; a `BufferedImage` is handy for compositing. – trashgod Apr 26 '12 at 13:45
  • I ended up using the technique in the ColorIcon example to draw a filled rectangle icon on each button. I didn't realize it would be that simple. Trashgod, if you rewrite your ColorIcon comment as an answer I'll accept it. – Gigatron May 01 '12 at 01:04
2

Here is an example using setBackground that works for me:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class Test {

    public static void main(String... args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        final JButton button = new JButton("Hello");
        button.setOpaque(true);
        panel.add(button);
        button.setBackground(Color.RED);
        button.setOpaque(true);
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Color c = JColorChooser.showDialog(button, "Choose a color", button.getBackground());
                if (c != null) {
                    button.setBackground(c);
                }
            }
        });
        frame.setContentPane(panel);
        frame.setPreferredSize(new Dimension(800, 600));
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setVisible(true);
    }
}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • 1
    While the code above works for the default Look and Feel, with the Windows Look and Feel it doesn't work as intended; it only shows a red rectangle surrounding the button and the surface color of the button does not change. – Gigatron Apr 30 '12 at 01:23
1

Every swing component is drawn using the JComponent.drawComponent(...) method, you can override the default behavior if you want. For example, to make a panel like you suggest. It is worth noting though, that you can change a jpanels background color to achieve the exact same thing.

    JColorChooser chooser = new JColorChooser(Color.BLACK);
    chooser.setVisible(true);

    Color color = chooser.getColor();
    if (color!=null) {
        colorPanel.setBackground(color);
    }

Where colorPanel would be your JPanel indicating your color.

Maarten Blokker
  • 604
  • 1
  • 5
  • 23