Change background color of selected JToggleButton

I am trying to change the color of a JToggleButton when it has been selected in a reliable, appearance-independent manner.

When using Metal L & F, using UIManager is the approach:

 UIManager.put("ToggleButton.selected", Color.RED); 

Note Iyy pointed out that I had a typo in the property name above, but I will leave it higher for people who get here, but the actual property name should be:

 UIManager.put("ToggleButton.select", Color.RED); 

However, this does not work in my current Look and Feel (currently Windows XP). After some further analysis, it seems that the appearance of the system in Windows (still XP) does not use any of the UIManager properties UIManager for ToggleButton for ToggleButton in general, or at least it does not provide them (there is a quick online example to find all property keys from UIManager , which in this example is explicitly limited in the Color properties).

I tried to set the background color:

 Action action = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { /* stuff */ } }; JToggleButton button = new JToggleButton(action); // tried with and without opaque true button.setOpaque(true); button.setBackground(Color.RED); 

Not only does not change the selected state, but does not even affect the unselected state.

I tried to change the background color only after receiving the action:

 @Override public void actionPerformed(ActionEvent e) { JToggleButton button = (JToggleButton)e.getSource(); if (button.isSelected()) // alternatively, (Boolean)getValue(Action.SELECTED_KEY) { button.setBackground(Color.RED); } } 

None of this works. The only thing I found to work requires that I draw a button myself in the selected state (which leads to a working example, although non-standard):

 private class ColoredToggleButton extends JToggleButton { ColoredToggleButton(Action action, Color color) { super(action); setBackground(color); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); if (this.isSelected()) { int w = getWidth(); int h = getHeight(); String s = getText(); // selected color g.setColor(getBackground()); g.fillRect(0, 0, w, h); // selected foreground color g.setColor(SystemColor.controlText); g.drawString(s, (w - g.getFontMetrics().stringWidth(s)) / 2 + 1, (h + g.getFontMetrics().getAscent()) / 2 - 1); } } } 

This is slightly modified from the comment in this Java bug report . Interesting (funny?) In statements that were corrected in 1998.

Does anyone know of a more convenient, L&F independent way to set the background color of the selected JToggleButton?

+7
source share
5 answers

You can see if setIcon() enough for your purpose, but you can also override paint() in the ButtonUI ButtonUI .

Addendum: @kleopatra's comment is well received: changing the UI delegate is not trivial. A recent @mKorbel example shows both the complexity and versatility of the approach. Its significant advantage is independence from appearance.

Less ambitious approaches are listed here .

+3
source

"ToggleButton.selected" is incorrect, this requires "ToggleButton.select". And the component must be updated.

 UIManager.put("ToggleButton.select", Color.WHITE); SwingUtilities.updateComponentTreeUI(togglebuttonname); 
+5
source
 JToggleButton btn = new JToggleButton(...); btn.setUI(new MetalToggleButtonUI() { @Override protected Color getSelectColor() { return Color.RED; } }); 
+3
source

You can simply force the background color before each redraw - for this you need to change the paintComponent, check if the button is turned on, set the background mode depending on the switching state and, finally, let the super class execute the actual paint task:

 public class ColoredToggleButton extends JToggleButton { @Override public void paintComponent(Graphics g) { Color bg; if (isSelected()){ bg = Color.GREEN; } else { bg = Color.RED; } setBackground(bg); super.paintComponent(g); } } 
+1
source

If you prefer to use an action listener instead of overriding methods in the user interface, you can simply change the user interface to the user interface without any selectColor properties.

Here is an example I used recently

 private class FavouriteToggle extends JToggleButton { public FavouriteToggle() { setUI(new BasicToggleButtonUI()); //Removes selectColor ////Your Custom L&F Settings//// setBackground(new Color(255, 252, 92)); setForeground(Color.GRAY); setText("Favourite"); setBorder(null); setFocusPainted(false); ////Add your own select color by setting background//// addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if(((JToggleButton) e.getSource()).isSelected()) { setForeground(Color.BLACK); setBackground(new Color(255, 251, 0)); } else { setBackground(new Color(255, 252, 92)); setForeground(Color.GRAY); } } }); } } 
0
source

All Articles