简体   繁体   English

合成器外观中的默认按钮输入映射?

[英]Default button input map in a synth look and feel?

I am trying to use the UIManager to get and clear some default key bindings so that the spacebar doesn't activate my JButtons, as explained here . 我试图用UIManager的获得和清除一些默认的键绑定,使空格键不激活我的Jbutton将作为解释在这里 Problem is, likely due to my synth look and feel, (InputMap)UIManager.get("Button.focusInputMap"); 问题是,可能是由于我的合成器外观, (InputMap)UIManager.get("Button.focusInputMap"); returns a null . 返回null Does anyone know of a way to easily clear components input maps some other way, or why the UIManager returns a null in this case? 有没有人知道如何以其他方式轻松清除组件输入映射,或者为什么UIManager在这种情况下返回null? Any tips are appreciated, thanks beforehand. 感谢任何提示,事先感谢。

First off: I like the idea of a decorated StyleFactory as suggested in the other answer, by @David :-) - so if that works out would suggest to use go that direction. 首先:我喜欢在另一个答案中建议的装饰StyleFactory的想法,@ David :-) - 所以如果这样做会建议使用那个方向。

Anyway, couldn't resist experimenting a bit: looks like Nimbus (and possibly other Synth-based LAFs) need those defaults overrides extremely early in the life-cycle: they accept them only if done before any component is actually created 无论如何,无法抗拒实验:看起来像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");

If the UIManager doesn't return an inputMap at that point, I would regard that as a misbehaviour of your custom LAF and would try to dig further as to why that happens. 如果UIManager在那时没有返回inputMap,我会认为这是你自定义LAF的不当行为,并会尝试进一步挖掘为什么会发生这种情况。 Another thingy you could try is to set an entirely new inputMap (which would have the advantage of surviving a LAF toggle, as it isn't a UIResource, like: 您可以尝试的另一件事是设置一个全新的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);

I'm not near a computer to try this, but looking at the openjdk 7 source here , the mapping looks fixed by default. 我不是在计算机附近尝试这个,但是在这里查看 openjdk 7源代码,默认情况下映射看起来是固定的。

A possible, but slightly hacky, solution could be to create and install a decorator SynthStyleFactory that modifies the style prior to returning it. 一个可能的,但有点hacky的解决方案可能是创建和安装装饰器SynthStyleFactory ,它在返回之前修改样式。

EDIT: I've updated the below code sample as I've had a chance to test this. 编辑:我已经更新了下面的代码示例,因为我有机会测试这个。 It didn't work in it's original form, but the updated code worked for me. 它没有以原始形式工作,但更新后的代码对我有用。

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;

     }
}

EDIT: I don't seem able to add a comment to the original post, so just to clarify, I had confirmed that UIManager.get("Button.focusInputMap") returned null with just plain Synth, prior to creating any components. 编辑:我似乎无法在原帖中添加注释,所以为了澄清,我已经确认UIManager.get(“Button.focusInputMap”)在创建任何组件之前返回null而只是简单的Synth。 Possibly Nimbus is overriding this behaviour. 可能是Nimbus压倒了这种行为。

 SynthLookAndFeel laf = new SynthLookAndFeel();
 UIManager.setLookAndFeel(laf);
 System.out.println(UIManager.get("Button.focusInputMap") == null); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM