2015-04-18 7 views
3

Я хочу иметь возможность увеличить размер шага на JSpinner, когда нажата определенная клавиша. То, что я пробовал до сих пор, заключалось в том, чтобы положить KeyListener на мой счетчик, и когда нажата определенная клавиша, измените значение размера шага. Когда ключ освобождается, он должен вернуться к нему по умолчанию.Увеличьте размер шага на JSpinner при нажатии определенной клавиши

Я думаю, что мне не нужно прямо ставить 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) {} 

    } 
} 
+2

Sorry - что именно ISN Не работает? Что касается бит KeyListener, здесь всегда лучше использовать привязки клавиш. Если вы не получите помощь в ближайшее время, подумайте о создании и публикации [sscce] (http://sscce.org) или [минимальной примерной программы/mcve] (http://stackoverflow.com/help/mcve), где вы сконденсируйте свой код на самый маленький бит, который все еще компилируется и запускается, не имеет внешних зависимостей (например, необходимо связать с базой данных или изображениями), не имеет дополнительного кода, который не имеет отношения к вашей проблеме, но все еще демонстрирует вашу проблему. –

+0

KeyBinding? что это такое? – Chax

+0

[Что такое ключевые привязки?] (Https://www.google.com/?q=java+key+bindings&gws_rd=ssl#q=java+key+bindings) –

ответ

4

Опять же, я хотел бы использовать привязки ключей, чтобы решить эту проблему, и я хотел бы использовать привязки, связанные с InputMap в JSpinner, что активно, когда оно имеет фокус :

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(); 
     } 
     }); 
    } 
} 
+0

+1 за хороший ответ. Это немного сложнее, чем я думал, что это будет, но я вижу, как это работает. Спасибо, еще один день, узнав что-то :) – Chax

+0

@Chax: привязки клавиш немного сложнее KeyListeners, но для этой ситуации они работают намного лучше, и, как и большинство вещей, как только вы привыкнете к ним, их кодирование становится второй натурой , –

+0

@Chax: также обратите внимание на структуру моего ответа - минимальную программу, которая иллюстрирует проблему и решение. Для будущих аналогичных вопросов подумайте о публикации аналогичного типа программы, [минимальной примерной программы] (http://stackoverflow.com/help/mcve), той, которую мы можем скомпилировать и запустить, и той, которая демонстрирует проблему непосредственно для нас. Это облегчит вам ** много. –