0

This problem appeared after my last question here. I want to set each button focused and lost focus background to background color which is below main menu (ContentPane which is JPanel), so buttons look like tabs. It couuld be different in different environments, so it is dynamic, so I can't set it manually. Now, If I log ContentPane background it says 238, 238, 238. If I log it inside FocusListener - it also states 238, 238, 238. If I directly set button's background to ContentPane background outside FocusListener - it works, but if I set inside FocusListener - it looks like value is not read and set, but if I set color manually - it works. How this could happen? Setting FocusListener to buttons is the last thing what I do in initialization of main JPanel.

private void setButtonDefaults(JButton but) {//calls once for each menu button to set defaults
    but.setBorderPainted(false);
    but.setBackground(Color.DARK_GRAY);
    but.setForeground(Color.WHITE);
    but.setName(but.getText().toLowerCase());
    but.setPreferredSize(buttonSize);
    but.addActionListener(this);
    //add focus listener
    but.addFocusListener(new FocusListener() {
        @Override
        public void focusLost(FocusEvent e) {
            Color clr = ContentPane.getBackground();
            log(clr + "");//logs that color is 238, 238, 238
            JButton button = (JButton) e.getSource();
            button.setBackground(clr);//value is not read
            //button.setBackground(new Color(238, 238, 238)); //value is read
        }

        @Override
        public void focusGained(FocusEvent e) {
            //same as focusLost function
        }
    });
}
private void enableOnlyOne(JButton but) { 
/* calls each time when one of menu buttons are pressed. 
All buttons are unpressed and changed colors to black and one
button is set as pressed and changes background color to
ContentPane background color
*/
    //disable all
    setButtonDisabled(MLibrary);
    setButtonDisabled(MScheduler);
    setButtonDisabled(MBudget);
    setButtonDisabled(MReports);
    setButtonDisabled(MManage);
    setButtonDisabled(MSettings);
    //enable one
    but.getModel().setPressed(true);
    but.setBackground(ContentPane.getBackground());//value is read perfect
    but.setForeground(Color.BLACK);
}
private void setButtonDisabled(JButton but) {
    but.getModel().setPressed(false);
    but.setBackground(Color.DARK_GRAY);
    but.setForeground(Color.WHITE);
}
Community
  • 1
  • 1
Paulius Vindzigelskis
  • 2,121
  • 6
  • 29
  • 41
  • 4
    For me, I'd be able to much better understand this if you could create and post an [sscce](http://sscce.org) (please check the link). Much luck! – Hovercraft Full Of Eels Jan 09 '12 at 12:58
  • CAn you please check if the focusLost is called multiple times? – Adel Boutros Jan 09 '12 at 13:02
  • I checked it. It is called everytime when I click one of buttons, but `ContentPane.getBackground()` logs same value each time: `javax.swing.plaf.ColorUIResource[r=238,g=238,b=238]` – Paulius Vindzigelskis Jan 09 '12 at 13:31
  • *"so buttons look like tabs."* I don't see anything in the screenshots of your previous question that could not be achieved using a `JTabbedPane` & a custom PLAF. But then, you do not seem to be listening to the *good* advice that is offered (at least, not in the comments). – Andrew Thompson Jan 09 '12 at 13:57
  • @Andrew Thompson please ..., I can't see there any for listening, but maybe paralized me *** my more than 2days continued insomnia – mKorbel Jan 09 '12 at 14:08
  • Insomnia is bad. :( I liked your answer, though. :) – Andrew Thompson Jan 09 '12 at 14:13
  • Not all L&Fs display changes to the background color is a useful way. – trashgod Jan 09 '12 at 14:59

3 Answers3

3

please don't do that this way, since I read your previous thread ..., now I can't resist

better and easiest way is add ChangeListener to expected JButtons, then inside stateChanged(ChangeEvent changeEvent) you can determine which of JButtons fired this event, for type of event you have to extract this event's type from ButtonModel

(rest is up to you, please put these JButtons to the Vector, Array or Enumerations), for example

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class MyButtonGroup {

    private JButton button1 = new JButton("Test Enabled / Disabled");
    private JButton button2 = new JButton("Test Enabled / Disabled");
    private JButton button3 = new JButton("Test Enabled / Disabled");

    public MyButtonGroup() {
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(3, 0, 10, 10));
        button1.addChangeListener(changeListener);
        panel.add(button1);
        button2.addChangeListener(changeListener);
        panel.add(button2);
        button3.addChangeListener(changeListener);
        panel.add(button3);
        JFrame frame = new JFrame("Grouping Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }
    private ChangeListener changeListener = new ChangeListener() {

        public void stateChanged(ChangeEvent changeEvent) {
            JButton abstractButton = (JButton) changeEvent.getSource();
            if (abstractButton == button1) {
                ButtonModel buttonModel = abstractButton.getModel();
                boolean armed = buttonModel.isArmed();
                boolean pressed = buttonModel.isPressed();
                boolean selected = buttonModel.isSelected();
                boolean rolover = buttonModel.isRollover();
                System.out.println("Changed: " + armed + "/" + pressed + "/" + selected + "/" + rolover);
            } else if (abstractButton == button2) {
                ButtonModel buttonModel = abstractButton.getModel();
                boolean armed = buttonModel.isArmed();
                boolean pressed = buttonModel.isPressed();
                boolean selected = buttonModel.isSelected();
                boolean rolover = buttonModel.isRollover();
                System.out.println("Changed: " + armed + "/" + pressed + "/" + selected + "/" + rolover);
            }
        }
    };

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                MyButtonGroup xxx = new MyButtonGroup();
            }
        });
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • In changeListener, look at your ifs more carefully - everything in brackets is the same. I thought about that some days ago, but my answer would be the same as yours, thats why I made button changing to that I did. Also, I know that there are only 6 buttons and no more, so if I want to make button switch optimization, then I need to save global variable something like "PressedButton", so then I would know which button to release. Thanks for your thoughts anyway – Paulius Vindzigelskis Jan 09 '12 at 13:45
  • 1
    @PooLaS The key difference lies in examining the event source's `ButtonModel`. +1 btw. – trashgod Jan 09 '12 at 15:29
1

Because some L&Fs don't display changes to the background color is a useful way, you may want to consider another form of highlighting: a different border, an altered foreground color, a custom icon, or a suitable background panel. More here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
0

It is so good to find out answer by myself:

private void setButtonDefaults(JButton but) {
    but.setBorderPainted(false);
    but.setBackground(Color.DARK_GRAY);
    but.setForeground(Color.WHITE);
    but.setName(but.getText().toLowerCase());
    but.setPreferredSize(buttonSize);
    but.addActionListener(this);
    //add focus listener
    final Color clr = ContentPane.getBackground();
    final int r = clr.getRed();
    final int g = clr.getGreen();
    final int b = clr.getBlue();
    but.addFocusListener(new FocusListener() {
        @Override
        public void focusLost(FocusEvent e) {
            log("r = " + r + ", g = " + g + ", b = " + b);
            JButton button = (JButton) e.getSource();
            button.setBackground(new Color(r, g, b));
        }

        @Override
        public void focusGained(FocusEvent e) {
            JButton button = (JButton) e.getSource();
            button.setBackground(new Color(r, g, b));
        }
    });
}

Thanks to everyone who tried (and did) to help me

Paulius Vindzigelskis
  • 2,121
  • 6
  • 29
  • 41