我试图用UIManager的获得和清除一些默认的键绑定,使空格键不激活我的Jbutton将作为解释在这里 。 问题是,可能是由于我的合成器的外观和感觉, (InputMap)UIManager.get("Button.focusInputMap");
返回一个null
。 有谁知道的方式来轻松地清除组件映射输入一些其他的方式,或者为什么UIManager的在这种情况下返回空值? 任何提示的赞赏,感谢提前。
Answer 1:
我不是一个电脑试试这个附近,但在OpenJDK 7的源看这里 ,映射看起来默认固定。
一种可能的,但是稍微哈克,解决方案可能是创建和安装一个装饰的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与只是普通的合成器。 雨云可能是压倒一切的这种行为。
SynthLookAndFeel laf = new SynthLookAndFeel();
UIManager.setLookAndFeel(laf);
System.out.println(UIManager.get("Button.focusInputMap") == null);
Answer 2:
首先:我喜欢装饰StyleFactory的主意,因为在其他的回答表明,通过@大卫:-) - 所以,如果可以算出建议使用去那个方向。
无论如何,忍不住尝试了一下:看起来像雨云(可能还有其他的基于合成器的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);
文章来源: Default button input map in a synth look and feel?