【问题标题】:How to detect a modifier key-combination upon button click in java如何在java中单击按钮时检测修饰键组合
【发布时间】:2015-04-10 20:53:49
【问题描述】:

我在 Java Swing 应用程序中有一个用于缩放到选择的按钮。我实现了 3 种点击方式:

  • 单击:使用逐步动画放大到选择
  • option-click:向选择方向执行单个缩放步骤
  • command-click:突然放大到全选

当另外按住 shift 键时,我想实现相反的行为(即从 选择向外缩放到完全缩小),所以它会是这样的:

  • shift-click:通过逐步动画完全缩小
  • shift-option-click:在选择范围之外执行一个缩放步骤
  • shift-command-click:突然放大到完全缩小

我知道除了 shift-option-click 和 shift-command-click 之外的所有操作。例如。以下是我如何进行单步放大:

int stepMask = InputEvent.ALT_MASK;
if((e.getModifiers() & InputEvent.ALT_MASK) == stepMask) {
    //do the single-step zoom
}

但我不知道如何通过点击进行组合键。我尝试过的所有东西都只适用于单个修饰键。如何在单击按钮时检测组合键?

【问题讨论】:

    标签: java swing click modifier


    【解决方案1】:

    还有一种更优雅的方法。首先,将您的组合掩码定义为常量:

    private static final int SHIFT_OPTION_MASK = InputEvent.ALT_MASK | InputEvent.SHIFT_MASK;
    

    然后,在按钮的 ActionListener 中,执行以下操作:

    if((e.getModifiers() & SHIFT_OPTION_MASK) == SHIFT_OPTION_MASK) {
        // code for event
    }
    

    如果你有很多这些,你可以更进一步。首先定义一个枚举:

    import java.awt.event.InputEvent;
    
    public enum ModifierKey {
        ALT(InputEvent.ALT_MASK),
        SHIFT(InputEvent.SHIFT_MASK),
        CONTROL(InputEvent.CTRL_MASK),
        COMMAND(InputEvent.META_MASK);
        // add more enum values here as needed
    
        public static boolean checkFor(ActionEvent e, ModifierKey... expectedModifiers) {
            int expectedModifierMask = 0;
            for (ModifierKey expectedModifier : expectedModifiers) {
                expectedModifierMask |= expectedModifier.getMask();
            }
            return (e.getModifiers() & expectedModifierMask) == expectedModifierMask;
        }
    
        private final int mask;
    
        ModifierKey(int mask) {
            this.mask = mask;
        }
    
        public int getMask() {
            return mask;
        }
    }
    

    然后,在你的 actionListener 中,你可以这样做:

    import static ModifierKey.*;
    
    ...
    
    if (checkFor(e, OPTION, SHIFT)) {
        // code for event
    }
    

    【讨论】:

    • 对于匿名投票者,您愿意发表评论吗?我在实践中使用它。它工作得很好,而且 IMO 更具可读性。
    • 20 多行代码和代码在每个事件中使用自定义方法,其他人在第一次看到代码时必须记住使用或查找代码,与单行代码 if((e.getModifiers() & (InputEvent.ALT_MASK | InputEvent.SHIFT_MASK) != 0 ) 相比哪个本身是完全可读的?这不像 InputEvent 常量被混淆命名。您的版本如何“更具可读性”?为了我的样板,它看起来像样板。
    • 非常欢迎您提出这个意见。 :) 在我相对较大的 Swing 应用程序中,我在几十个地方使用了 checkFor 函数(请注意,在我的回答中我写了“如果你有很多这些。”我发现它们中的每一个都更具可读性,也更容易让语法正确,所以额外的二十行(我从来不用碰)很容易为自己付出代价。
    • 此外,对 checkFor 的每次调用都比等效的“原始”方法短几个字符,更不用说它不包括任何按位操作,我发现这很容易出错。花了十分钟写完这二十行,每次需要检查修饰键时,我都节省了三十秒。
    【解决方案2】:

    修饰符值是一个按位或运算的值,包含与事件相关的所有 InputEvent 修饰符。要识别特定的修饰符,请检查给定逻辑您认为必要的所有内容:

    if((e.getModifiers() & InputEvent.ALT_MASK) != 0 && (e.getModifiers() & InputEvent.SHIFT_MASK) != 0 ) {
        //code for event
    }
    

    【讨论】:

    • 为什么不把它简化为 if((e.getModifiers() & (InputEvent.ALT_MASK | InputEvent.SHIFT_MASK) != 0 ) { //事件代码 }
    • @Gordon 因为如果按住 alt shift 键,该代码就会执行。
    • 不,不会。这是一个面具。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    • 2011-03-07
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多