Keyevent an System senden

Viprex

Grünschnabel
Nachdem ich hier schon viele Antworten gefunden habe, jetzt meine 1. Frage:

Ich möchte, dass auf Tastendruck von VK.DIVIDE sich ein Menu öffnet. Das Menu reagiert auf ALT+M, das ist kein Problem. Allerdings möchte ich das Menu eben auch auf das Keyevent VK.DIVIDE öffnen.
Hat jemand eine Idee, wie ich das realisieren kann? Ich habe mir gedacht, ich fange das Keyevent VK.DIVIDE ab und führe dann die Aktion ALT+M aus. Nur finde ich leider keinen Weg, diesen Tastendruck ans System zu senden.
Ich vermute, das könnte auch über Keyevents laufen, nur weiß ich leider nicht wie.

Außerdem möchte ich, dass ich im dann aufgerufenen Menu mit den Pfeiltasten VK.UP und VK.DOWN navigieren kann.

Hintergrund: Wie sollen eine Handyanwendung programmieren, die nur auf bestimmte Tasten reagiert. Diese Tasten senden eben nur die Keyevents des Nummerpads. Ich kann also nicht auf dem Bildschirm in der GUI rumklicken, sondern muss alles über die Nummernpadtasten steuern können.

Ich danke euch für eure Antwort und Hilfestellung!

Edit: Ich sehe, dass immer Java Code eingefügt wird, finde aber anscheinend nicht die richtigen Code-Tags. Im Editor stehen nur Tags für HTML, PHP und Code? Egal, nachfolgend nochmal mein Code:

Code:
public class Add_1 extends Add {

    private static final long serialVersionUID = 1L;

    protected String getTitle() { return "Neuer Eintrag"; }
    protected String getLabelLeft() { return "Menu"; }
    protected String getLabelRight() { return "Entf"; }
    
    private JTextField _sumtext;
    private JFormattedTextField _datetext;
    private JTextField _commenttext;
    
    private JMenuBar _menuBar;
    private JMenu _menu;
    private JMenuItem _beendenM, _ausgabenM;  
        
    private int _focus = 0;
    
    public Add_1(MobileApp app) {
        super(app);
        _expense = new Expense();
        // if nothing is specified, create own data set.
        useData(_expense);
    }
    
    public Add_1(MobileApp app, Expense data) {
        super(app);
        // ...or gladly use the given one...
        useData(data);
    }

    protected JPanel getDialogContent() {       
        JPanel content = new JPanel();
        content.setLayout(new GridLayout(6,1));
        
        // sum label and input
        content.add(new JLabel("Betrag (in Cent)"));
        
        // input
        _sumtext = new JTextField();
        _sumtext.setDocument(new NumberDocument());
        _sumtext.setBorder(BorderFactory.createLineBorder(Color.red));
        content.add(_sumtext);
        
        // date label and input
        content.add(new JLabel("Datum"));
        
        // current date...
       _datetext = new JFormattedTextField();
       _datetext.setEditable(false);
       _datetext.setBorder(BorderFactory.createLineBorder(Color.gray));
        
       // date
        content.add(_datetext);
       
        
        // comment
        content.add(new JLabel("Kommentar"));
        _commenttext = new JTextField("");
        _commenttext.setBorder(BorderFactory.createLineBorder(Color.gray));
        content.add(_commenttext);
                
        return content;
    }
    

    /**
     * Erstellt das Menu unten Links
     */
    public JMenuBar createMenuBar() 
    {                
        // Create the menu bar
        _menuBar = new JMenuBar();
        
        _menuBar.setBackground(Color.BLACK);
        _menuBar.setForeground(Color.WHITE);
        _menuBar.setOpaque(true); // otherwise the background is not drawn
        //_menuBar.setHorizontalAlignment(SwingConstants.CENTER);
        _menuBar.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));
        
        // Menu erstellen
        _menu = new JMenu(getLabelLeft());
        _menu.setBackground(Color.BLACK);
        _menu.setForeground(Color.WHITE);
        _menu.setOpaque(true); // otherwise the background is not drawn
        _menu.setMnemonic(KeyEvent.VK_M);
        _menu.getAccessibleContext().setAccessibleDescription("Das Menu");

        // MenuItem zu Beenden
        _beendenM = new JMenuItem("Beenden", KeyEvent.VK_B);  
        // Tastaturkürzel für _beendenM festlegen
        _beendenM.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.ALT_MASK));
        _beendenM.getAccessibleContext().setAccessibleDescription("Programm beenden");
        _menu.add(_beendenM);
        
        // Seperator zum Menu hinzufügen
        _menu.insertSeparator(1);
        
        // MenuItem zu Ausgaben
        _ausgabenM = new JMenuItem("Ausgaben", KeyEvent.VK_A);  
        // Tastaturkürzel für _ausgabenM festlegen
        _ausgabenM.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.ALT_MASK));
        _ausgabenM.getAccessibleContext().setAccessibleDescription("Ausgaben ansehen");
        _menu.add(_ausgabenM);
        
        _menu.setMenuLocation(-11,-56);
    
        //Listener für die Menuitems registrieren
        addListener();
        
        // das fertige Menu zur Menubar hinzufügen
        _menuBar.add(_menu);
        
        return _menuBar;
    }
    
    /**
     * Die Action Listener für die Menu Items registrieren
     */
    protected void addListener() {
        // Action auf Menuklick Beenden
        _beendenM.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                System.out.println("Beenden");
            }
        }
        );
        
        // Action auf Menuklick Ausgaben
        _ausgabenM.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                System.out.println("Ausgaben");
            }
        }
        );
    }

........ UNWICHTIGES RAUSGESCHNITTEN

public boolean keyPressed(int keyCode) {
        if(keyCode == KeyEvent.VK_SUBTRACT) {

            JTextField field = null;
            if(_focus == 0) { field = _sumtext; }
            if(_focus == 1) { return true; } // del disabled for _datetext
            if(_focus == 2) { field = _commenttext; }
                      
                int pos = field.getCaretPosition();
                String t = field.getText();
    
                // we can't delete something here
                if(pos == 0) return true;
                
                // get the fucking char and kill it
                int KILL = 1;
                String first = t.substring(0, pos-KILL);
                String end = t.substring(pos);
                // nothing happened...
                field.setText(first+end);
                field.setCaretPosition(pos-1);
                return true;
        }
        
        if(keyCode == KeyEvent.VK_DIVIDE) {
            //save changes
            saveFields();
            _focus=3;
            changeFocus();
            
            // next thing
            
            //Menu_add newOne = new Menu_add(_app);
            //_app.newDialog(newOne);
            return true;
        }
          
        if(_focus==1 && keyCode == KeyEvent.VK_LEFT) {
            Datumkram kram = new Datumkram();
            _datetext.setText(kram.dayMinus(_datetext.getText()));
            _datetext.setCaretPosition(0); 
        }
        if(_focus==1 && keyCode == KeyEvent.VK_RIGHT) {
            Datumkram kram = new Datumkram();
            _datetext.setText(kram.dayPlus(_datetext.getText()));
            _datetext.setCaretPosition(10); 
        }
        
        // next window
        if(keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_MULTIPLY) {
            //save changes
            saveFields();
            // next thing
            //Add_Category newOne = new Add_Category(_expense);
            //newOne.useData(_expense);
            //_app.newDialog(newOne);
            return true;
        }
        
        // down = bottom input field
        if(keyCode == KeyEvent.VK_DOWN) {
            _focus ++;
            if(_focus > 2) _focus = 0;
            changeFocus();
            return true;
        }
        // up = top input field
        if(keyCode == KeyEvent.VK_UP) {
            -- _focus;
            if(_focus < 0) _focus = 2;
            changeFocus();
            return true;
        }

        return false;
    }
    
    // there must be a better way...
    private void changeFocus() {
        if(_focus == 0)
        {
            _sumtext.requestFocus();
            _sumtext.setBorder(BorderFactory.createLineBorder(Color.red));
            _datetext.setBorder(BorderFactory.createLineBorder(Color.gray));
            _commenttext.setBorder(BorderFactory.createLineBorder(Color.gray));
            
        }
        if(_focus == 1) { 
            _datetext.requestFocus(); 
            _datetext.setCaretPosition(0); 
            _sumtext.setBorder(BorderFactory.createLineBorder(Color.gray));
            _datetext.setBorder(BorderFactory.createLineBorder(Color.red));
            _commenttext.setBorder(BorderFactory.createLineBorder(Color.gray));
        }
        if(_focus == 2) {
            _commenttext.requestFocus();
            _sumtext.setBorder(BorderFactory.createLineBorder(Color.gray));
            _datetext.setBorder(BorderFactory.createLineBorder(Color.gray));
            _commenttext.setBorder(BorderFactory.createLineBorder(Color.red));
        }
        if(_focus == 3) {
            _menu.requestFocus();
            _menu.setBackground(Color.red);
        }
    }
 
Java Tags gibt es nicht im Editor auszuwählen, du kannst sie aber einfach hinschreiben... sieht aus wie die anderen Tags, steht halt nur Java drin. Das geht hier für ziemlich viele Sprachen.

Wieso setzt du nicht einfach den VK_DIVIDE als Mnemonic für das Menü? Oder brauchst du das andere auch noch?

Gehen die Pfeiltasten nicht automatisch? Ich dachte immer das wäre so.
 
Wieso setzt du nicht einfach den VK_DIVIDE als Mnemonic für das Menü? Oder brauchst du das andere auch noch?
Das habe ich probiert, die Mnemonic reagiert aber nur auf Alt+M. Setze ich sie auf VK.DIVIDE, dann reagiert sie weder auf / noch auf Alt+/

Gehen die Pfeiltasten nicht automatisch? Ich dachte immer das wäre so.

Ja, das dachte ich auch. Leider werden die blöden Pfeiltasten vorher durch die ganzen Keyevents abgefangen. Ich vermute, das ist einfach nur ein Focusproblem. Da schaue ich nochmal, wenn der korrekte Aufruf mit VK.DIVIDE des Menus funktioniert.
 
So nimm mal das Beispiel von:
http://www.cs.cf.ac.uk/Dave/HCI/HCI_Handout_CALLER/node79.html

Und füg im Konstruktor hinter dem setSize(...) folgendes ein:
Java:
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

this.addKeyListener(new KeyAdapter() {

	@Override
	public void keyReleased(KeyEvent evt) {
		if (evt.getKeyCode() == KeyEvent.VK_F1) {
			System.out.println("F1 pressed");
			menuFile.doClick();
		}
	}

});

Das Menü "File" öffnet sich dann bei Taste F1.

Die Pfeiltasten funktionieren auch... naja zumindest die normalen, auf dem Keypad habe ich keine (Notebook).
 
Das bringt nichts. Der Keylistener liegt in einer anderen Klasse. Die Keys werden ja auch aufgerufen, das ist kein Problem. Leider geht der Menuaufruf nur mir ALT + /.
 
Lies doch mal durch was ich da gepostet habe.... ich rufe auf den Tastendruck F1 das Menü File auf. Das ist doch dass was du brauchst!
 
Entschuldige bitte, ich habe beim Nachvollziehen des Codebeispiels und deines Codeschnipsels menu.doClick() überlesen. Das war der entscheidende Hinweis. Alles andere funktioniert ja, daher habe ich zu früh abgeschaltet.

Vielen vielen Dank für deine Hilfestellung und den entscheidenden Hinweis.


Jetzt frage ich mich, ob es ein äquivalent doClick zum Schließen gibt. Habe leider nichts dergleichen gefunden.


Viel wichtiger ist aber, dass ich gerne den Focus beim Öffnen des Menüs auf ein JMenuItem lenken möchte. Es gibt da allerhand Focusmethoden, bei mir funktioniert aber leider keine davon.

Was ich mach:

menu.requestFocus(), damit zuerst einmal das Menu den Focus bekommt.
Auch probiert habe ich, dem JMemuItem mit JMenuItem.requestFocus() den Focus aufzudrücken. Geht auch nicht.

Ich bekomme mit menu.getSelectedIcon() bekomme ich erwartungsgemäß null, da ja kein Item ausgewählt ist.

Nochmal mein Problem: Ich kann leider nicht mit der Maus in das Menu klicken. Ich rufe das Menu mit einer Taste auf (menu.doClick) Dann muss der Focus ins Menu gelenkt werden, damit ich dort mit den Pfeiltasten navigieren und mit der Enter Taste etwas auswählen kann.

Kann mir dabei vielleicht jemand Hilfestellung geben? Vielen lieben Dank!
 
Ich bekomme mit menu.getSelectedIcon() bekomme ich erwartungsgemäß null, da ja kein Item ausgewählt ist.

Du wirst da eigentlich immer null bekommen, wenn du kein SelectedIcon gesetzt hast.


Eigentlich ist doch direkt das erste MenuItem gewählt und dann kann man doch mit den Pfeiltasten navigieren.


MFG

Sascha
 
Eigentlich hast du auch Recht, aber leider geht das in diesem Fall nicht, da die Up und Down Tasten vorhar abgefangen werden. Ich muss also per Hand das Menu traversieren nachbauen.

Interessant ist dabei für mich auch, wie ich ein selektierten Menueintrag abfragen kann. Da muss ich bestimmt wieder einen Listener bemühen. Ich weiß nur nicht welchen der übermäßig vielen. Kann mir jemand einen Tipp geben?
 
Zurück