Results 1 to 4 of 4
  1. #1
    benedict is offline Member
    Join Date
    May 2011
    Posts
    1
    Rep Power
    0

    Default How to correctly identify "alt shift +" keypress?

    This is actually a specific instance of a general problem that is driving me batty. Here are the specifics.

    In programs such as, say, browsers, it's common to assign the key combo "alt -" to reduce font size, and "alt +" (which is to say, "shift alt +" on US keyboards) to increase font size. I want to make it easy to specify such key combos, and to handle them when the user activates them

    If only life were this easy. It turns out that pressing "alt -" on a US keyboard actually generates a "–" (short dash) character, while pressing "shift alt +" generates "±" (the plus or minus sign.) And there is, as far as I can tell, no easy way of knowing what symbol (the one printed on the key) was actually pressed, because the only other applicable key info in a key event is a numerical code representing the physical key that was pressed--and the same physical key may have different symbols on different keyboard styles. Trust me, it's not as easy as simply extracting the appropriate data from the key events generated by AWT--I've spent hours on this. Given that "shift +" generates a + character, one would expect that "alt shift +" would generate a + character with the ALT modifier on, but this is not the case.

    Now I know that programs manage to do this somehow, but I'm sure not seeing an easy solution. Is there a library out there I could use? Could someone suggest a different approach? This has got me completely stopped for the time being.

    Thanks,
    Ken

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,193
    Rep Power
    19

  3. #3
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,234
    Rep Power
    7

    Default

    I don't know of any keyboard independent solution for this.

    The first two key bindings show how you bind "-" and "+" to an Action and work as you expect.

    The next two bindings show the next logical step of how you think you would bind "alt -" and "alt +" to an Action but it doesn't work. The problem is that "alt" plus any character doesn't generate a character in a text field so you can't use the "typed" key stroke.

    The final two bindings show what you need to do to get the binding that you want. You need to use a "pressed" or "released" event and these need a key code to generate the event, not a character.

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.text.*;
    
    public class KeyBindingTest extends JFrame
    {
    	public KeyBindingTest()
    	{
    		JPanel panel = new JPanel();
    		panel.setFocusable( true );
    		getContentPane().add( panel );
    
    		createBinding(panel, "typed -"); // works
    		createBinding(panel, "typed +"); // works
    
    		createBinding(panel, "alt typed -"); // doesn't work
    		createBinding(panel, "alt typed +"); // doesn't work
    
    		createBinding(panel, "alt pressed MINUS"); // works
    		createBinding(panel, "alt shift pressed EQUALS");  // works
    	}
    
    	public void createBinding(JComponent component, String binding)
    	{
    		InputMap im = component.getInputMap();
    		ActionMap am = component.getActionMap();
    		KeyStroke ks = KeyStroke.getKeyStroke( binding );
    		im.put(ks, binding);
    		am.put(binding, new SimpleAction(binding));
    	}
    
    	class SimpleAction extends AbstractAction
    	{
    		public SimpleAction(String name)
    		{
    			putValue( Action.NAME, name );
    		}
    
    		public void actionPerformed(ActionEvent e)
    		{
    			System.out.println( getValue( Action.NAME ) );
    		}
    	}
    
    	public static void main(String[] args)
    	{
    		KeyBindingTest frame = new KeyBindingTest();
    		frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
    		frame.setSize(300, 300);
    		frame.setLocationRelativeTo( null );
    		frame.setVisible(true);
    	}
    }
    I think this just confirms exactly what you have been saying but I wan't sure if you where aware of how to use the key bindings if you know the layout of the keyboard.

  4. #4
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,193
    Rep Power
    19

    Default

    I guess using the virtual key codes of KeyEvent should be keyboard agnostic, but I don't have an alternative keyboard layout on which i can test that assumption.

    The API does say
    Virtual key codes are used to report which keyboard key has been pressed
    Java Code:
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    import javax.swing.*;
    
    public class AltPlusMinus {
    
      private static final String INCREASE_FONT = "increaseFont";
      private static final String DECREASE_FONT = "decreaseFont";
    
      public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
    
          @Override
          public void run() {
            new AltPlusMinus().makeUI();
          }
        });
      }
    
      public void makeUI() {
        JTextArea textArea = new JTextArea(30, 5);
        InputMap inputMap = textArea.getInputMap();
        ActionMap actionMap = textArea.getActionMap();
    
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, KeyEvent.ALT_DOWN_MASK),
                INCREASE_FONT);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, KeyEvent.ALT_DOWN_MASK),
                INCREASE_FONT);
    
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SUBTRACT, KeyEvent.ALT_DOWN_MASK),
                DECREASE_FONT);
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, KeyEvent.ALT_DOWN_MASK),
                DECREASE_FONT);
    
        actionMap.put(INCREASE_FONT, new FontSizeAction(textArea, 1));
        actionMap.put(DECREASE_FONT, new FontSizeAction(textArea, -1));
    
        textArea.setText("The quick brown fox jumps over the lazy dog.");
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(textArea));
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    }
    
    class FontSizeAction extends AbstractAction {
    
      private JTextArea textArea;
      private float increment;
    
      public FontSizeAction(JTextArea textArea, int increment) {
        super();
        this.textArea = textArea;
        this.increment = increment;
      }
    
      @Override
      public void actionPerformed(ActionEvent e) {
        Font font = textArea.getFont();
        // TODO: check that the font size doesn't get too big or too small
        if (font.getSize() > increment * - 1) {
          font = font.deriveFont(font.getSize2D() + increment);
          textArea.setFont(font);
        }
      }
    }
    db

Similar Threads

  1. Replies: 1
    Last Post: 01-21-2010, 09:20 AM
  2. How correctly invoke function "round"?
    By artemff in forum New To Java
    Replies: 2
    Last Post: 01-01-2010, 11:31 AM
  3. " shift " Operator ???
    By MuslimCoder in forum New To Java
    Replies: 5
    Last Post: 02-09-2009, 05:51 AM
  4. Replies: 2
    Last Post: 01-24-2009, 06:56 PM
  5. Replies: 1
    Last Post: 10-20-2008, 07:35 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •