似乎在 FocusListener 中没有读取 JPanel 背景
Posted
技术标签:
【中文标题】似乎在 FocusListener 中没有读取 JPanel 背景【英文标题】:Seems like JPanel background isn't read in FocusListener 【发布时间】:2012-02-06 00:05:57 【问题描述】:这个问题出现在my last question here之后。我想将每个按钮的焦点和失去焦点的背景设置为主菜单下方的背景颜色(ContentPane 是 JPanel),所以按钮看起来像标签。在不同的环境中可能会有所不同,所以它是动态的,所以我不能手动设置它。现在,如果我记录 ContentPane 背景,它会显示 238、238、238。如果我在 FocusListener 中记录它 - 它还会显示 238、238、238。如果我直接将按钮的背景设置为 FocusListener 外部的 ContentPane 背景 - 它可以工作,但如果我设置在 FocusListener 内部 - 看起来没有读取和设置值,但如果我手动设置颜色 - 它可以工作。这怎么可能发生?将 FocusListener 设置为按钮是我在主 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);
【问题讨论】:
对我来说,如果您可以创建并发布sscce(请查看链接),我将能够更好地理解这一点。祝你好运! 请问是否多次调用了focusLost? 我查过了。每次单击其中一个按钮时都会调用它,但ContentPane.getBackground()
每次都记录相同的值:javax.swing.plaf.ColorUIResource[r=238,g=238,b=238]
“所以按钮看起来像标签。” 我在您之前的问题的屏幕截图中看不到任何使用 JTabbedPane
和自定义 PLAF 无法实现的内容.但是,您似乎并没有听取所提供的好建议(至少,不是在 cmets 中)。
@Andrew Thompson 请...,我看不到有什么可以听的,但可能让我瘫痪了 *** 我持续失眠超过 2 天
【参考方案1】:
请不要那样做,因为我看了你之前的帖子...,现在我无法抗拒
更好和最简单的方法是将ChangeListener
添加到预期的JButtons
,然后在stateChanged(ChangeEvent changeEvent)
中,您可以确定哪个JButtons
触发了此事件,对于事件类型,您必须从ButtonModel
中提取此事件的类型
(其余由你决定,请把这些JButtons
放到Vector, Array or Enumerations
),例如
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();
);
【讨论】:
在 changeListener 中,更仔细地查看您的 ifs - 括号中的所有内容都是相同的。几天前我想过,但我的答案和你的一样,这就是为什么我将按钮更改为我所做的。另外,我知道只有6个按钮,没有更多,所以如果我想进行按钮开关优化,那么我需要保存像“PressedButton”这样的全局变量,这样我就知道要释放哪个按钮了。无论如何感谢您的想法 @PooLaS 关键区别在于检查事件源的ButtonModel
。 +1 顺便说一句。【参考方案2】:
由于某些 L&F 不显示对背景颜色的更改是一种有用的方式,因此您可能需要考虑另一种突出显示形式:不同的边框、更改的前景色、自定义图标或合适的背景面板。更多here.
【讨论】:
【参考方案3】:自己找到答案真是太好了:
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));
);
感谢所有尝试(并且确实)帮助我的人
【讨论】:
以上是关于似乎在 FocusListener 中没有读取 JPanel 背景的主要内容,如果未能解决你的问题,请参考以下文章
VerifyListener 和 FocusListener 冲突