我正在尝试使用UIManager获取并清除一些默认的键绑定,以便空格键不会激活我的JButton,如here所述。问题可能是由于我的合成器外观,(InputMap)UIManager.get("Button.focusInputMap");
会返回null
。有没有人知道如何以其他方式轻松清除组件输入映射,或者为什么UIManager在这种情况下返回null?感谢任何提示,事先感谢。
答案 0 :(得分:4)
首先关闭:我喜欢在另一个答案中建议的装饰StyleFactory的想法,@ David :-) - 所以如果这样做可以建议使用那个方向。
无论如何,无法抗拒试验:看起来像Nimbus(可能还有其他基于Synth的LAF)需要这些默认值在生命周期的早期覆盖极:他们只有在完成时才会接受它们在实际创建任何组件之前
// setting LAF
InteractiveTestCase.setLAF("Nimbus");
// tweak inputMap, immediately after setting the ui is fine
// uncomment the following line and it doesn't work
// new JPanel();
InputMap inputMap = (InputMap) UIManager.get("Button.focusInputMap");
inputMap.put(KeyStroke.getKeyStroke("SPACE"), "do-nothing");
如果UIManager在那时没有返回inputMap,我会认为这是你自定义LAF的不当行为,并会尝试进一步挖掘为什么会发生这种情况。您可以尝试的另一件事是设置一个全新的inputMap(它具有幸存LAF切换的优势,因为它不是UIResource,如:
// setting LAF
InteractiveTestCase.setLAF("Nimbus");
// tweak inputMap, immediately after setting the ui is fine
InputMap inputMap = (InputMap) UIManager.get("Button.focusInputMap");
InputMap custom = new InputMap();
if (inputMap != null) {
// copy all bindings to custom
...
} else {
// add the binding we know of (as implementation detail)
custom.put(KeyStroke.getKeyStroke("released SPACE"), "released");
}
// overwrite the binding you want to change
custom.put(KeyStroke.getKeyStroke("SPACE"), "do-nothing");
// set the custom map
UIManager.put("Button.focusInputMap", custom);
答案 1 :(得分:3)
我不是在计算机附近尝试这个,但是看一下openjdk 7源here,默认情况下映射看起来是固定的。
一个可能的,但有点hacky的解决方案可能是创建和安装一个装饰器SynthStyleFactory,它在返回之前修改样式。
编辑: 我已经更新了以下代码示例,因为我有机会对此进行测试。它没有以原始形式工作,但更新后的代码对我有用。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.synth.Region;
import javax.swing.plaf.synth.SynthLookAndFeel;
import javax.swing.plaf.synth.SynthStyle;
import javax.swing.plaf.synth.SynthStyleFactory;
import sun.swing.plaf.synth.DefaultSynthStyle;
public class LnFTest {
public static void main(String[] args) throws UnsupportedLookAndFeelException{
SynthLookAndFeel laf = new SynthLookAndFeel();
laf.load(LnFTest.class.getResourceAsStream("laf.xml"), LnFTest.class);
UIManager.setLookAndFeel(laf);
SynthLookAndFeel.setStyleFactory(new MyStyleFactory(SynthLookAndFeel.getStyleFactory()));
JButton button = new JButton("Test");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("Action Performed");
}
});
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(button, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
class MyStyleFactory extends SynthStyleFactory {
private SynthStyleFactory delegate;
private Map overrides;
public MyStyleFactory(SynthStyleFactory delegate){
this.delegate = delegate;
overrides = new HashMap();
overrides.put("Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[0]));
}
public SynthStyle getStyle(JComponent c, Region id) {
SynthStyle style = delegate.getStyle(c, id);
System.out.println("Style is a: " + style);
if(style instanceof DefaultSynthStyle){
((DefaultSynthStyle)style).setData(overrides);
}
return style;
}
}
编辑: 我似乎无法在原帖中添加评论,所以 为了澄清,我已经确认UIManager.get(“Button.focusInputMap”)在创建任何组件之前返回null而只是简单的Synth。可能是Nimbus压倒了这种行为。
SynthLookAndFeel laf = new SynthLookAndFeel();
UIManager.setLookAndFeel(laf);
System.out.println(UIManager.get("Button.focusInputMap") == null);