Anzeige:
Ergebnis 1 bis 10 von 10

Thema: JFrame->KeyEvent + MousePosition Abfragen?

  1. #1
    Registrierter Benutzer
    Registriert seit
    03.04.2002
    Beiträge
    112

    JFrame->KeyEvent + MousePosition Abfragen?

    Hi.

    kaum ist das erste Problem behoben, ist schon das nächste da.

    Ich habe einen JFrame/JDialog. Ich will nun beim drücken von z.B. STRG+F9, dass ich dann mit getComponentAt(int x, int y) die Component abfragen kann. Im prinzip recht simpel.

    Erstes Problem ist nur, dass der KeyListener nicht wirklich so funktioniert, wie ich es mir gedacht habe. Wenn ich über dem LayeredPane vom JFrame bin, dann registriert er den Tastendruck ja wohl, sobald ich aber über der Table bin, macht er das nichtmehr.
    Ich will aber nicht jede Component mit einem Listener belegen, dann bring mit das getComponentAt(x,y) ja auch nix mehr.
    Was ich möchte ist eigentlich, dass ich, egal wo im JFrame (also von der MausPosition her gesehen), solange der Frame aktiv ist, die TastenKombi drücken kann und dann möchte ich halt abfragen, ob Control-down ist, ob F9 gedrückt wurde und dann die X/Y-Position von der Maus. Damit möchte ich dann getComponentAt(x,y) aufrufen und diese in dem Component-Tree (Thread weiter unten) dann selektieren. Das Selektieren etc ist kein Problem. Nur die TastenKombi zu prüfen und gleichzeitig die MausPosition zu bekommen, das ist mein Problem.

    Ansatzweise habe ich folgendes:

    Code:
    final ActionListener listener = new ActionListener() {
      public final void actionPerformed(final ActionEvent event) {
        System.out.println("Key typed.. " + "   " + getX() + "x" + getY());
      }
    };
    
    final KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0, true);
    
    getRootPane().registerKeyboardAction(listener, keyStroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    Wenn ich nun F9 drücke, dann wird das, was in der ActionPerformed-Methode steht, ausgeführt. getX() und getY() sind allerdings nicht die Maus-Werte, denn diese sind immer gleich. Ausserdem ist es ja im moment nur F9, ohne Control.

    Kann mir da jemand helfen?

    TIA && Mfg, Matflasch
    Verteilt die Macht, dass sie keinen mächtig macht!

  2. #2
    Registrierter Benutzer
    Registriert seit
    07.02.2002
    Beiträge
    41
    Hi,

    was ist denn, wenn der ActionListener gleichzeitig MouseMotionListener des JFrames wäre und so permanent mit der aktuellen Position der Maus versorgt wird. Wenn dann die Taste gedrückt werden würde, wüsste der ActionListener die aktuelle Position der Maus.

    Denke, dass es so klappen könnte.

    Gruss
    Sebastian

  3. #3
    Registrierter Benutzer Avatar von Sym
    Registriert seit
    05.09.2002
    Ort
    Bremen
    Beiträge
    278
    Hi,

    getX(), bzw. getY() gibt die Fenster-Werte zurück. Du muss schon die Werte, die Dir das Event zurückgibt nutzen.

    Dann solltest Du auch ein MouseEvent nutzen und nicht nur das ActionEvent. Da gibt es dann auch die richtigen Funktionen.
    Denk mal drüber nach...

    Lars

    ACHTUNG: ersetze Linux durch GNU/Linux an den entsprechenden Stellen
    www.macuser.de, MSVC2005 Express und Qt, Qt/Mac installieren

  4. #4
    Registrierter Benutzer
    Registriert seit
    03.04.2002
    Beiträge
    112
    Kann man den ActionListener denn gleichzeitig mit dem MouseMotionListener 'belegen'? Habe beim stöbern gelesen, dass das nicht gehen soll...?

    Dass getX() und getY() einfach so verwendet die Fensterposition zurück liefert, habe ich auch noch rausgefunden
    Das Problem ist nur, dass mir das KeyEvent die X und Y-Position der Maus ja leider nicht zurück liefern, daher bräuchte ich eine Kombination aus KeyEvent und MouseListener, damit ich beides kombiniert nutzen kann, nur wie gesagt habe ich gelesen, dass das nicht so einfach gehen soll. Bei der Suche bin ich dann auch auf die Lösung gefunden, die ich gepostet habe, allerdings bin ich damit nicht glücklich, da mir die X/Y-Position der Maus fehlt, um getComponentAt(x,y) anwenden zu können :/

    Ich werde morgen mal versuchen, die beiden irgendwie zu kombinieren...

    Falls jemand sowas schonmal gemacht hat und mir direkt ne Lösung sagen kann, wäre das nicht schlecht

    Mfg, Matflasch
    Verteilt die Macht, dass sie keinen mächtig macht!

  5. #5
    Registrierter Benutzer Avatar von Sym
    Registriert seit
    05.09.2002
    Ort
    Bremen
    Beiträge
    278
    Hi,

    Du musst einen MouseListener (oder MouseAdapter) implementieren. Dort kannst Du das MouseEvent abfangen. So sollte das klappen.
    Denk mal drüber nach...

    Lars

    ACHTUNG: ersetze Linux durch GNU/Linux an den entsprechenden Stellen
    www.macuser.de, MSVC2005 Express und Qt, Qt/Mac installieren

  6. #6
    Registrierter Benutzer
    Registriert seit
    03.04.2002
    Beiträge
    112
    Jo das hatte ich auch gemacht bei dem JFrame, allerdings brauche ich ja die Kombination aus KeyEvent und MouseListener :/

    Beim drücken von STRG+F9 will ich ja die Mouse-Position abfragen, das geht ja auch nicht mit dem MouseListener alleine.
    Ausgelöst werden soll das Event eigentlich nur durch drücken von STRG+F9. Dann will ich halt die Component haben, die gerade unter der Maus liegt.
    Die Component selbst soll nicht angeklickt werden oder so, das macht mir das ganze Problem eigentlich nur.

    Kann man in einem solchen Listener denn beides Kombinieren?
    Weil das Problem mit dem KeyEvent ist ja auch, dass dann der Focus auf dem JFrame sein muss, und wenn der Focus grad bei der Table ist, dann registriert er das KeyEvent ja nicht wirklich. Habe da heut schon voll viel mit rumprobiert, ohne erfolg..

    Das einzige, was geklappt hat bisher, war mit dem KeyStroke. Den müsste ich irgendwie mit dem MouseListener verbinden.

    Ich werde das morgen früh einfach nochmal ausprobieren, irgendwie muss das ja gehen
    Verteilt die Macht, dass sie keinen mächtig macht!

  7. #7
    Registrierter Benutzer Avatar von Sym
    Registriert seit
    05.09.2002
    Ort
    Bremen
    Beiträge
    278
    So schwer ist das doch nicht.

    Du kannst doch in einem Boolean speichern, ob die Maus im Frame ist, oder eben nicht. Immer wenn Du mit der Maus rausgehst, wird der Wert auf false gesetzt. Wenn Du wieder das Frame "enterst", wird gewechselt.

    Und im ActionListener greifst Du darauf zu.
    Denk mal drüber nach...

    Lars

    ACHTUNG: ersetze Linux durch GNU/Linux an den entsprechenden Stellen
    www.macuser.de, MSVC2005 Express und Qt, Qt/Mac installieren

  8. #8
    Registrierter Benutzer
    Registriert seit
    07.02.2002
    Beiträge
    41
    Also ich würde einfach eine neue Klasse implementieren, die sowohl ActionListener als auch MouseListener realisiert. Und diese neue Klasse meldest du dann als Listener an der entsprechenden Komponente an.

    Ich glaub mit der anonymen Klasse bekommst du das nicht hin, MouseMotionListener und ActionListener zu erzeugen.

    Also irgendwas wir:

    Code:
    public class FrameAction implements MouseMotionListener, ActionListener {
    
      private int xWert;
      private int ywert;
    
      public void mouseDragged(MouseEvent e)  {
      }
    
      public void mouseMoved(MouseEvent e)  {
    
        this.xWert = e.getX();
        this.yWert = e.getY();
      }
    
      public void actionPerformed(ActionEvent e) {
    
         //Aufruf der Methode, die die Kompoente ermittelt.
      }
    }
    Übernehme keine Garantie, dass da auch wirklich so funktioniert, aber ich glaub schon, dass es das so tun sollte.

    Gruss
    Sebastian

  9. #9
    Registrierter Benutzer
    Registriert seit
    03.04.2002
    Beiträge
    112
    Danke für die Antworten zwischendurch mal

    Also ich habe mir nun eine eigene Klasse erstellt, die MouseMotionListener, ActionListener, KeyListener, MouseListener implementiert.
    Damit kann ich zwar die entsprechenden Listener setzen bei dem Frame, allerdings klappt das ganze nicht über der JTable. Wahrscheinlich muss ich dann jeder Component den Listener bekannt machen, richtig?
    Das ist eigentlich das, was ich nicht wollte.

    Bzw. Ich nutze den Listener nun mit dem KeyStroke (oben) zusammen. Somit wird mitlerweile bei STRG+F9 erkannt, dass er was tun soll. Führt auch schön die actionPerformed() aus und hat durch die mouseMove() auch die X/Y-Position der Maus. (Ist das nicht unnötige Rechenzeit, bei jeder Mausbewegung die Positionen zu setzen? Sind zwar nur 2 int-Werte, aber... ich bin von sowas eigentlich nicht so der Fan, sehe nur keine andere Möglichkeit...).

    Das Problem ist halt noch, dass das ganze nur bei dem LayeredPane dann greift, somit also bei Toolbar, Menuebar, leider aber nicht bei JScrollPane, JTable etc.

    Ein weiteres Problem, was mir nun aufgefallen ist, getComponentAt(x,y) liefert leider nur die oberste Component *g*
    Ich bräuchte aber die Unterste.

    Meine Idee wäre:
    Ich habe die Oberste Component. Somit kann ich, wie bei dem JTree, auch alle UnterComponents rausfinden. Die MausPosition habe ich auch, daher könnte ich eine Art Abfrage machen, die testet, ob es in dem Rechteck liegt...:
    X-Position, X+WIDTH,
    Y-Position, Y+HEIGHT

    Ich sehe nur schon das Problem bei JScrollPanes/JTables. Die haben doch die gleichen Koordinaten/Breite/Höhe, oder?

    Mfg, Matflasch
    Verteilt die Macht, dass sie keinen mächtig macht!

  10. #10
    Registrierter Benutzer
    Registriert seit
    03.04.2002
    Beiträge
    112
    Ok,

    hab nun alles soweit, mein einziges(, vorerst letztes ) Problem ist:

    Wie kann ich allen Components den Listener zuweisen, ohne es von Hand zu machen? Bei teilweise 200 Components keine schöne aufgabe... das ganze dann bei X anwendungen...

    Ich will dem JFrame/this einfach den Listener zuweisen und dann sollen alle Components im JFrame sich den vom JFrame holen, geht das?

    Hier mal meine Listener-Klasse:
    Code:
    public class FrameListener implements MouseMotionListener, ActionListener, KeyListener, MouseListener {
    
        // Besitzer des Listeners
        Frame ownerFrame = null;
    
        // Die Component, über der die Maus gerade steht
        Component objHoverComponent = null;
    
        // X-Position der Maus
        private int intXPosition = 0;
    
        // Y-Position der Maus
        private int intYPosition = 0;
    
        /**
         * Standardkonstruktur
         * 
         * @param p_Frame
         *            p_Frame Der Frame wird übergeben, da die getComponentAt(x,y)
         *            Methode aufgerufen wird. Diese benötigt den Frame, von dem aus
         *            die Methode aufgerufen werden soll
         */
        public FrameListener(Frame p_Frame) {
            // ownerFrame setzen
            ownerFrame = p_Frame;
        }
        public void mouseClicked(MouseEvent e) {
            //        System.out.println("FrameListener -> mouseClicked()");
        }
        public void mouseEntered(MouseEvent e) {
            //        System.out.println("FrameListener -> mouseEntered()");
        }
        public void mouseExited(MouseEvent e) {
            //        System.out.println("FrameListener -> mouseExited()");
        }
        public void mousePressed(MouseEvent e) {
            //        System.out.println("FrameListener -> mousePressed()");
        }
        public void mouseReleased(MouseEvent e) {
            //        System.out.println("FrameListener -> mouseReleased()");
        }
        public void keyPressed(KeyEvent e) {
            //        System.out.println("FrameListener -> keyPressed()");
        }
        public void keyReleased(KeyEvent e) {
            //        System.out.println("FrameListener -> keyReleased()");
        }
        public void keyTyped(KeyEvent e) {
            //        System.out.println("FrameListener -> keyTyped()");
        }
        public void mouseDragged(MouseEvent e) {
            //        System.out.println("FrameListener -> actionPerformed()");
        }
        public void mouseMoved(MouseEvent e) {
            System.out.println("FrameListener -> mouseMoved()" + e.getX() + "x" + e.getY() + "C:" + e.getComponent());
            // Componente sichern, die sich momentan unter der
            // Maus befindet
            objHoverComponent = e.getComponent();
            // X-Position der Maus sichern
            this.intXPosition = e.getX();
            // Y-Position der Maus sichern
            this.intYPosition = e.getY();
        }
        public void actionPerformed(ActionEvent e) {
            getComponent(objHoverComponent);
        }
        public void getComponent(Component p_Component) {
            // Die Component, die als Root-Stamm angezeigt werden soll
            Component t_ComponentRoot = ownerFrame.getComponentAt(intXPosition, intYPosition);
            // dlgShowAppComponents-Dialog erstellen
            dlgShowAppComponents dlgShowAppComponents = new dlgShowAppComponents(ownerFrame, new BO_StartParameter(), t_ComponentRoot, null, p_Component);
            // Dialog anzeigen
            dlgShowAppComponents.show();
        }
    Angewendet wird der Listener nun mit:

    Code:
    	// Instanz-Variable des Listeners erstellen
    	final FrameListener objFrameListener = new FrameListener(this);
    	// KeyStroke erstellen STRG+F9
    	final KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_F9, InputEvent.CTRL_DOWN_MASK, true);
    Folgendes muss ich nun pro Component machen (was ich sehr mühsam finde, wenn es 100-200Components sind...):
    Code:
            // this
            this.addMouseMotionListener(objFrameListener);
            this.addMouseListener(objFrameListener);
            this.addKeyListener(objFrameListener);
    addMouseListener kann ich wahrscheinlich zwar auch weg lassen, aber naja.

    Es muss doch irgendwie gehen, dass die Components sich die Listener von der übergeordneten Component(JFrame,JDialog) holen, oder ist das unmöglich?

    Es wäre schön, wenn die insgesamt 5 Zeilen alles wären, was mich nun zum Ziel bringt
    Verteilt die Macht, dass sie keinen mächtig macht!

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •