Java Swing中如何识别触发PropertyChangeListener的具体组件
如何在Swing主题变更时识别触发变更的组件
方法1:通过PropertyChangeEvent的source传递触发组件
修改ThemeManager的主题设置方法,允许传入触发变更的组件,并在触发事件时将该组件作为事件源(或保留原source,将组件存入事件的userData):
public class ThemeManager { private String theme; // ... 其他成员 public void setTheme(String newTheme, Component triggerComponent) { String oldTheme = this.theme; this.theme = newTheme; // 触发事件时携带触发组件 firePropertyChange("theme", oldTheme, newTheme); // 若需保留ThemeManager作为source,可改用自定义事件传递组件 } }
在触发主题变更的组件(如单选按钮)的监听器中,调用setTheme时传入自身:
settingsLightThemeRadioButton.addActionListener(e -> { themeManager.setTheme("light", settingsLightThemeRadioButton); });
最后在ThemeManagerFrame的propertyChange方法中获取触发组件:
@Override public void propertyChange(PropertyChangeEvent evt) { if ("theme".equals(evt.getPropertyName())) { String newTheme = (String) evt.getNewValue(); // 获取触发组件 Component trigger = (Component) evt.getSource(); System.out.println("Theme changed by: " + trigger.getName()); // 同步ButtonGroup示例:根据触发组件更新其他组的选中状态 if (trigger == settingsLightThemeRadioButton) { otherButtonGroup.getElements().asIterator().forEach(btn -> { if ("light".equals(btn.getActionCommand())) { btn.setSelected(true); } }); } // ... 其他UI更新逻辑 } }
方法2:自定义事件类携带触发组件
若需保留ThemeManager作为事件源,可自定义PropertyChangeEvent子类存储触发组件:
public class ThemeChangeEvent extends PropertyChangeEvent { private final Component triggerComponent; public ThemeChangeEvent(Object source, String propertyName, Object oldValue, Object newValue, Component triggerComponent) { super(source, propertyName, oldValue, newValue); this.triggerComponent = triggerComponent; } public Component getTriggerComponent() { return triggerComponent; } }
修改ThemeManager的触发逻辑:
public void setTheme(String newTheme, Component triggerComponent) { String oldTheme = this.theme; this.theme = newTheme; firePropertyChange(new ThemeChangeEvent(this, "theme", oldTheme, newTheme, triggerComponent)); }
在监听器中强转事件获取组件:
@Override public void propertyChange(PropertyChangeEvent evt) { if ("theme".equals(evt.getPropertyName()) && evt instanceof ThemeChangeEvent) { ThemeChangeEvent themeEvent = (ThemeChangeEvent) evt; String newTheme = (String) themeEvent.getNewValue(); Component trigger = themeEvent.getTriggerComponent(); System.out.println("Theme changed by: " + (trigger != null ? trigger.getName() : "Unknown")); // 同步ButtonGroup逻辑... } }
方法3:在触发源直接同步组件
如果不需要在全局监听器中识别组件,可在触发主题变更的组件监听器中直接同步其他ButtonGroup,避免后续监听器处理:
settingsLightThemeRadioButton.addActionListener(e -> { // 先同步另一个ButtonGroup的选中状态 otherButtonGroup.setSelected(settingsLightThemeRadioButton.getModel(), true); // 再通知主题变更 themeManager.setTheme("light"); });
内容的提问来源于stack exchange,提问作者IssaKass
相关产品推荐
相关产品推荐

