按下某个键时,在JSpinner上增加步长

时间:2015-04-18 22:12:19

标签: java swing jspinner event-listener

我希望能够在按下某个键时增加JSpinner上的步长。到目前为止我尝试的是将KeyListener放在我的微调器上,当按下某个键时,更改步长的值。当密钥被释放时,它应该返回默认值。

我认为我不必将KeyListener直接放在JSpinner上,而是放在按钮上。

我真的不知道如何实现这一目标。让我感到困惑的是双Listener

以下是我为KeyListener撰写的代码:

public class SpinnerKeyIncrement implements KeyListener {

    JSpinner spinner;
    SpinnerNumberModel spinnerModel;

    public SpinnerKeyIncrement(JSpinner s) {
        this.spinner = s;
        if(spinnerModel == null)
            spinnerModel = (SpinnerNumberModel) spinner.getModel();
    }


    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_CONTROL) {
            spinnerModel.setStepSize(.10);
        }
        else if(e.getKeyCode() == KeyEvent.VK_SHIFT) {
            spinnerModel.setStepSize(1);
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        spinnerModel.setStepSize(0.01);

    }

    @Override
    public void keyTyped(KeyEvent e) {}

    }
}

1 个答案:

答案 0 :(得分:4)

同样,我使用Key Bindings来解决这个问题,并且我使用绑定到JSpinner的InputMap的绑定,当它有焦点时它是活动的:

  InputMap inputMap = spinner.getInputMap(JComponent.WHEN_FOCUSED);

一个有效的小例子程序可能如下所示:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class ChangeStepSize extends JPanel {
   private static final String DOUBLE_STEP = "double step";
   public static final int SMALL_STEP_SIZE = 1;
   public static final int BIG_STEP_SIZE = 10;

   // bind to the "d" key, but you could use any key you'd like
   private static final int SPECIAL_KEY = KeyEvent.VK_D;
   private SpinnerNumberModel numberModel = new SpinnerNumberModel(50, 0, 100, 1);
   private JSpinner spinner = new JSpinner(numberModel);

   public ChangeStepSize() {
      add(spinner);

      // set up key bindings. First get InputMap and ActionMap
      InputMap inputMap = spinner.getInputMap(JComponent.WHEN_FOCUSED);
      ActionMap actionMap = spinner.getActionMap();

      // next set bindings for when key is pressed
      boolean onKeyRelease = false;
      KeyStroke keyStroke = KeyStroke.getKeyStroke(SPECIAL_KEY, 0, onKeyRelease);
      inputMap.put(keyStroke, DOUBLE_STEP + onKeyRelease);
      actionMap.put(DOUBLE_STEP + onKeyRelease, new DoubleStepAction(onKeyRelease));

      // next set bindings for when key is released
      onKeyRelease = true;
      keyStroke = KeyStroke.getKeyStroke(SPECIAL_KEY, 0, onKeyRelease);
      inputMap.put(keyStroke, DOUBLE_STEP + onKeyRelease);
      actionMap.put(DOUBLE_STEP + onKeyRelease, new DoubleStepAction(onKeyRelease));
   }

   // our Action is passed in a parameter to indicate which state it
   // gets activated in: key press or key release
   private class DoubleStepAction extends AbstractAction {
      private boolean onKeyRelease;

      public DoubleStepAction(boolean onKeyRelease) {
         this.onKeyRelease = onKeyRelease;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         if (onKeyRelease) {
            numberModel.setStepSize(SMALL_STEP_SIZE);
         } else {
            numberModel.setStepSize(BIG_STEP_SIZE);
         }
      }
   }

   private static void createAndShowGui() {
      ChangeStepSize mainPanel = new ChangeStepSize();

      JFrame frame = new JFrame("ChangeStepSize");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}