[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Java keypad event creation. What type of event to create? KeyEvent or ActionEvent?

Posted on 2014-08-23
5
Medium Priority
?
285 Views
Last Modified: 2014-08-28
I'm writing a Java program that will ultimately target an embedded system.

The embedded system will have a physical keypad.

Pressing a button on the physical keypad creates an interrupt which runs the interrupt code which can do... whatever would be appropriate for it to do. (It provides a different number for each keypad button, so we can tell which keypad button was pressed.) Currently I'm writing the emulation code that emulates this keypad.

I'm not sure if I should be generating a KeyEvent, or an ActionEvent, or some other sort of event.

I have a window (JFrame) that emulates the keypad, showing buttons for each key on the keypad.

I have another window (another JFrame) which is the view. This window should react to the keypad buttons in the other window. I expect this view window will have some sort of listener listening for keypad button pressed events.

To further complicate, it would be nice if the emulation program would also respond to the computer keyboard; e.g. the keypad emulation window has Up, Down, Left, Right arrow keys, so pressing the arrow keys on the computer keyboard should do the same thing as clicking the arrow button in the keypad emulation window.

To further confuse, I just realized there are two different ActionEvents in Java
java.awt.event.ActionEvent
javafx.event.ActionEvent
I'm not using javafx.


So my questions are:
what sort of "event" should my keypad emulation window generate?
How can my View Window subscribe to these events?
(Supposedly Keypad knows nothing about View, and View knows nothing about details of Keypad. Probably a Controller knows about both of them and connects them together.)

How can I get the Computer Keyboard Arrow Keys to also effect the same result as the arrow key buttons in the Keypad Emulation Window?

Can you provide a simple example?
0
Comment
Question by:deleyd
  • 3
  • 2
5 Comments
 
LVL 37

Accepted Solution

by:
zzynx earned 2000 total points
ID: 40282581
>> what sort of "event" should my keypad emulation window generate?
KeyEvent for sure
>> How can my View Window subscribe to these events?
Your window that emulates the keypad should implement KeyEventDispatcher
Your window that should listen to those KeyEvents should implement KeyListener and should subscribe itself to receive the key events dispatched by the emulating window by calling:
        <your emulating window>.addKeyListener(this);

Open in new window


>> How can I get the Computer Keyboard Arrow Keys to also effect the same result
>> as the arrow key buttons in the Keypad Emulation Window?
By also let the same listening window subscribe itself to the class that generates the "real" key events:
        <your other class generating "real" key events>..addKeyListener(this);

Open in new window


>> Can you provide a simple example?
Sorry, I don't have the time for that. But maybe these can help you:
* http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html
* http://java.about.com/od/Handling-Events/ss/A-Keylistener-Example-Program.htm
0
 

Author Comment

by:deleyd
ID: 40284392
Is there another way to set the parent InputMap and ActionMap of controls to be the JPanel they are all on? Or do I have to go through each control separately and manually set the parent InputMap and ActionMap?
int rows = 3;
int cols = 3;

JPanel panel = new JPanel(new GridLayout(rows, cols));

panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
panel.add(button5);
panel.add(button6);
panel.add(button7);
panel.add(button8);
panel.add(button9);

InputMap inputMapPanel = panel.getInputMap();

button1.getInputMap().setParent(inputMapPanel);
button2.getInputMap().setParent(inputMapPanel);
button3.getInputMap().setParent(inputMapPanel);
button4.getInputMap().setParent(inputMapPanel);
button5.getInputMap().setParent(inputMapPanel);
button6.getInputMap().setParent(inputMapPanel);
button7.getInputMap().setParent(inputMapPanel);
button8.getInputMap().setParent(inputMapPanel);
button9.getInputMap().setParent(inputMapPanel);

ActionMap actionMapPanel = panel.getActionMap();

button1.getActionMap().setParent(actionMapPanel);
button2.getActionMap().setParent(actionMapPanel);
button3.getActionMap().setParent(actionMapPanel);
button4.getActionMap().setParent(actionMapPanel);
button5.getActionMap().setParent(actionMapPanel);
button6.getActionMap().setParent(actionMapPanel);
button7.getActionMap().setParent(actionMapPanel);
button8.getActionMap().setParent(actionMapPanel);
button9.getActionMap().setParent(actionMapPanel);


KeyStroke keyUp = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
KeyStroke keyDown = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);

inputMapPanel.put(keyUp, "DoSomething");
inputMapPanel.put(keyDown, "DoThis");

Open in new window

0
 
LVL 37

Expert Comment

by:zzynx
ID: 40285063
An alternative can be seen in this code of my class EscDialog being a JDialog that closes when ESC is pressed.
But it should react on pressing ESC, no matter what control is currently focused.
Therefor the KeyListener is added recursively. I think that's what you want if I understand your code above well.

import javax.swing.JDialog;
import java.awt.*;
import java.awt.event.*;

/**
 * a JDialog that disappears when ESC is pressed
 */
public class EscDialog extends JDialog implements ContainerListener, KeyListener {

    public EscDialog(Frame frame, String title, boolean modal) {
        super(frame, title, modal);
        addListenersRecursively(this);
    }

    public EscDialog(Frame frame, boolean modal) {
        super(frame, modal);
        addListenersRecursively(this);
    }

    //The following function is recursive and is intended for internal use only.
    //It is private to prevent anyone calling it from other classes
    //The function takes a Component as an argument and adds this JDialog as a KeyListener to it.
    //Besides it checks if the component is actually a Container and if it is, 
    //there  are 2 additional things to be done to this Container :
    // 1 - add this Dialog as a ContainerListener to the Container
    // 2 - call this function recursively for every child of the Container.

    private void addListenersRecursively(Component c) {
        //To be on the safe side, try to remove KeyListener first 
        //just in case it has been added before.
        //If not, it won't do any harm
        c.removeKeyListener(this);
        //Add KeyListener to the Component passed as an argument
        c.addKeyListener(this);

        if (c instanceof Container) {
            //Component c is a Container. The following cast is safe.
            Container container = (Container) c;
            //To be on the safe side, try to remove ContainerListener first 
            //just in case it has been added before.
            //If not, it won't do any harm
            container.removeContainerListener(this);
            //Add ContainerListener to the Container.
            container.addContainerListener(this);

            //Get the Container's array of children Components.
            Component[] children = container.getComponents();

            //For every child repeat the above operation.
            for (int i = 0; i < children.length; i++) {
                addListenersRecursively(children[i]);
            }
        }
    }

    //The following function is the same as the function above with the exception that it does exactly the opposite - 
    // removes this Dialog from the listener lists of Components.
    private void removeListenersRecursively(Component c) {
        c.removeKeyListener(this);
        if (c instanceof Container) {
            Container container = (Container) c;
            container.removeContainerListener(this);
            Component[] children = container.getComponents();
            for (int i = 0; i < children.length; i++) {
                removeListenersRecursively(children[i]);
            }
        }
    }

    //ContainerListener interface
    //---------------------------------------------------------

    //This function is called whenever a Component or a Container is added 
    //to another Container belonging to this Dialog

    public void componentAdded(ContainerEvent e) {
        addListenersRecursively(e.getChild());
    }

    //This function is called whenever a Component or a Container is removed from another Container belonging to this Dialog
    public void componentRemoved(ContainerEvent e) {
        removeListenersRecursively(e.getChild());
    }

    //KeyListener interface
    //---------------------------------------------------------
    //This function is called whenever a Component belonging to this Dialog 
    //(or the Dialog itself) gets the KEY_PRESSED event

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            //Key pressed is the ESCAPE key.
            performEscapeAction(e);
        }
    }
    //We need the following 2 functions to complete imlementation of KeyListener

    public void keyReleased(KeyEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }

    //Default response to ESCAPE key pressed goes here
    public void performEscapeAction(KeyEvent evt) {
        setVisible(false);
    }
}

Open in new window

0
 

Author Closing Comment

by:deleyd
ID: 40287222
Thank you I think I have it now.

For anyone else reading this, I found how to make a class an "ActionTalker" here:
http://www.java2s.com/Tutorial/Java/0260__Swing-Event/ManagingListenerListswithEventListenerList.htm

The parts are:

private EventListenerList actionListenerList = new EventListenerList();

      public void addActionListener(ActionListener actionListener) {
            actionListenerList.add(ActionListener.class, actionListener);
      }

      public void removeActionListener(ActionListener actionListener) {
            actionListenerList.remove(ActionListener.class, actionListener);
      }

      protected void fireActionPerformed(ActionEvent actionEvent) {
            EventListener listenerList[] = actionListenerList.getListeners(ActionListener.class);
            for (int i = 0, n = listenerList.length; i < n; i++) {
                  ((ActionListener) listenerList[i]).actionPerformed(actionEvent);
            }
      }
0
 
LVL 37

Expert Comment

by:zzynx
ID: 40290190
Thanx 4 axxepting
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
Suggested Courses
Course of the Month18 days, 6 hours left to enroll

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question