JavaFX KeyEvent und Canvas draw Problem

BlaueBohne

Mitglied
Hallo liebe Leute,

Ich habe folgendes Problem. Ich beschäftige mich seit Neuestem mit der Programmierung in JavaFX und bin auch recht zufrieden damit.

Nun wollte ich mir einen kleinen Dummi erstellen um mit den KeyEvents rumzuspielen und zeichne hierfür ein Rechteck auf einen Canvas, was sich mit den Arrow-Keys nach recht, oder links bewegt.

Soweit kein Problem, jedoch nach jedem Klick macht das Rechteck erst einen Satz und erst dann wird es "fließend" gezeichnet.
Hoffe, ich konnte das verständlich erklären. ^^

Hier der Code:


Die Main:
Java:
package springenderblock;

import javafx.application.Application;
import javafx.stage.Stage;

public class SpringenderBlock extends Application 
{
    
    @Override
    public void start(Stage primaryStage) 
    {
        primaryStage.setTitle("Springender Block");
        
        Leinwand leinwand = new Leinwand();
        
        primaryStage.setScene(leinwand);
        primaryStage.show();
    }

    public static void main(String[] args) 
    {
        launch(args);
    }
    
}

und die Scene:

Java:
package springenderblock;

import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;

public class Leinwand extends Scene
{
    Canvas canvas;
    StackPane stackPane;
    int posx = 100;
    GraphicsContext gc;
    
    public Leinwand()
    {
        super(new StackPane(),1024,800);
        stackPane = new StackPane();
        makeAll();
        stackPane.getChildren().add(canvas);
        this.setRoot(stackPane);
        events();
    }
    
    public void makeAll()
    {
        canvas = new Canvas(1024,800);
        gc = canvas.getGraphicsContext2D();
        
        gc.save();
        gc.setFill(Color.BLUE);
        gc.fillRect(posx, 600, 150, 150);
        gc.restore(); 
    }

    private void events()
    {
        setOnKeyPressed(new EventHandler <KeyEvent>()
        {
            @Override
            public void handle(KeyEvent e)
            {
                
                if(e.getCode() == KeyCode.LEFT)
                {
                    gc.clearRect(0, 0, 1024, 800);
                    posx = posx -20;
                    gc.setFill(Color.BLUE);
                    gc.fillRect(posx, 600, 150, 150);
                    System.out.println("Check Left");
                }
                
                else if(e.getCode() == KeyCode.RIGHT)
                {
                    gc.clearRect(0, 0, 1024, 800);
                    posx = posx +20;
                    gc.setFill(Color.BLUE);
                    gc.fillRect(posx, 600, 150, 150);
                    System.out.println("Check Right");
                }
            }   
        });
    }
}


Kann mir das irgendwie nicht erklären. Ist mir unter Swing irgendwie nie aufgefallen...
Gibt es dafür eine Lösung?
 

BlaueBohne

Mitglied
Um es genauer zu beschreiben. Ich möchte ja das Rechteck um 20 Pixel jeweils verschieben. Lasse ich jetzt eine taste gedrückt, bewegt es sich erst 20 Pixel, dann entsteht eine Pause und dann bewegt sich das Rechteck erst "fließend".
 

dzim

Top Contributor
Hast du mal geschaut, wie die Events gefeuert werden? Vielleicht liegt es nicht am Code, sondern die Key-Events werden tatsächlich mit einer "Unterbrechung" ausgelöst...
Vielleicht wäre es auch sinnvoll, den EventHander nur an das Canvas zu hängen (und den Focus darauf zu setzen). Aber ich hab bisher Canvas nie benötigt, und weiss es daher nicht genauer.
 

BlaueBohne

Mitglied
Hatte ich auch probiert, aber dann empfängt er die Events komischerweise nicht. Lässt sich irgendwie nur über die Scene steuern. (Bitte immer um Rat, fals ich falsch liege)

Hast du mal geschaut, wie die Events gefeuert werden? Vielleicht liegt es nicht am Code, sondern die Key-Events werden tatsächlich mit einer "Unterbrechung" ausgelöst...

Das dachte ich auch, aber das würde nicht erklären, wieso sie dann im Anschluss fließend ablaufen.
 

dzim

Top Contributor
Melde dich evtl. mal auf dem Bugtracker https://javafx-jira.kenai.com/ an und schau dich mal um, ob da wer schon solche Issues hatte. Wenn nein, kannst du ja ein Ticket öffnen und deiner Beschreibung ein Ein-Klassen-Beispiel beilegen.

BTW: Laut Canvas (JavaFX 8) erbt Canvas von Node ( Node (JavaFX 8) ) und verfügt damit über eine key-pressed-Methode: Node (JavaFX 8)
Wichtig:
setOnKeyPressed hat gesagt.:
Defines a function to be called when this Node or its child Node has input focus and a key has been pressed. The function is called only if the event hasn't been already consumed during its capturing or bubbling phase.
Das Problem könnte also vielleicht auch am Event-Bubbling liegen, denn du markierst dein Event nicht als "consumed" und damit fangen es evtl. noch ander Handler:
KeyEvent (JavaFX 8)
Am besten also "e#consume()" in deinem EventHandler aufrufen (siehe http://docs.oracle.com/javase/8/javafx/api/javafx/event/Event.html ), um das (Key)Event als verarbeitet zu markieren.
 

BlaueBohne

Mitglied
BTW: Laut Canvas (JavaFX 8) erbt Canvas von Node ( Node (JavaFX 8) ) und verfügt damit über eine key-pressed-Methode: Node (JavaFX 8)

Das ist richtig, funktioniert aber irgendwie nicht. ^^

Mit e.consume() Hab ich es jetzt auch mal probiert, hat jedoch keine Wirkung erzielt. :/
 

BlaueBohne

Mitglied
Habe es hinbekommen. Man muss einfach mit ner Timeline arbeiten und diese triggern. Echt dumm gelöst in JavaFX, aber na ja.
Ansonsten find ichs nach wie vor super. ;)

Hier der Code:


Java:
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.util.Duration;

public class Leinwand extends Scene
{
    Canvas canvas;
    StackPane stackPane;
    int posx = 100;
    GraphicsContext gc;
    Timeline timeline;
    int direction = 0;
    
    public Leinwand()
    {
        super(new StackPane(),1024,800);
        stackPane = new StackPane();
        makeAll();
        stackPane.getChildren().add(canvas);
        this.setRoot(stackPane);
        events();
        initTimeline();
        timeline.play();
    }
    
    public void makeAll()
    {
        canvas = new Canvas(1024,800);
        gc = canvas.getGraphicsContext2D();
        
        gc.save();
        gc.setFill(Color.BLUE);
        gc.fillRect(posx, 600, 150, 150);
        gc.restore(); 
    }
    

    private void events()
    {

        setOnKeyPressed(new EventHandler <KeyEvent>()
        {
            
            @Override
            public void handle(KeyEvent e)
            {
                if(e.getCode() == KeyCode.LEFT)
                {
                    direction = -20;
                }
                
                else if(e.getCode() == KeyCode.RIGHT)
                {
                    direction = +20;
                }
            }   
        });
        
        setOnKeyReleased(new EventHandler <KeyEvent>()
        {
            
            @Override
            public void handle(KeyEvent e)
            {
                direction = 0;
            }   
        });
        
        
    }
    
    public void initTimeline()
    {
        timeline = new Timeline();
        timeline.setCycleCount(Timeline.INDEFINITE);
        KeyFrame kf = new KeyFrame(Duration.millis(40), new EventHandler<ActionEvent>()
        {

            @Override
            public void handle(ActionEvent e) 
            {
                if(direction != 0)
                {
                    if(direction > 0)
                    {
                        gc.clearRect(0, 0, 1024, 800);
                        posx = posx +20;
                        gc.setFill(Color.BLUE);
                        gc.fillRect(posx, 600, 150, 150);
                        System.out.println("Check Left");
                    }
                    
                    if(direction < 0)
                    {
                        gc.clearRect(0, 0, 1024, 800);
                        posx = posx -20;
                        gc.setFill(Color.BLUE);
                        gc.fillRect(posx, 600, 150, 150);
                        System.out.println("Check Left");
                    }
                }
            }
                        
        });
        timeline.getKeyFrames().add(kf);
    }
}

hoffe, das hilft einigen verirrten Seelen da draußen. :)

Ps.: Habs jetzt nicht "optimal" oder "schön" gelöst, aber das Prinzip sollte somit klar sein.
 
Zuletzt bearbeitet:

dzim

Top Contributor
I see, ok. Ich versteh' nur gerade noch nicht den Zusammenhang zwischen dem EventHander am KeyFrame...

Ah. Moment. Du updatest das Canvas eigentlich die ganze Zeit, oder?
Hm. Ob das im Sinne des Erfinders ist, kann ich mir gerade aber auch nicht vorstellen...

Auf StackOverflow gab es zu JavaFX mal folgende Frage:
javafx 2 - How do I make a circle move on events? - Stack Overflow

Und diese Frage scheint noch eher in deine Richtung zu gehen:
How to get smooth animation with KeyPress event in javaFX? - Stack Overflow

Ich denke, da sind die "sauberen" Lösungen, als alle 40ms eine Animation zu starten!
Aber das ist nur meine Meinung...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Monokuma KeyEvent in der Canvas Klasse AWT, Swing, JavaFX & SWT 0
M KeyEvent ohne Fokus konsumieren AWT, Swing, JavaFX & SWT 1
F AWT awt KeyEvent - Zeichen direkt nach Eingabe löschen AWT, Swing, JavaFX & SWT 2
Bluedaishi JavaFX JFoenix TextField KeyEvent AWT, Swing, JavaFX & SWT 2
L JavaFX ASCII Zeichen /char von KeyEvent erhalten AWT, Swing, JavaFX & SWT 5
Wurstkopp JavaFX JavaFX KeyEvent kein Zahlencode um unbekannte Mediatasten auszuwerten? AWT, Swing, JavaFX & SWT 0
B JavaFX Wo liegt mein Gedankenfehler ??? KeyEvent geht nicht ... AWT, Swing, JavaFX & SWT 8
S Swing JDialog mit KeyEvent als Rückgabe AWT, Swing, JavaFX & SWT 1
dat_vin KeyEvent jTextField AWT, Swing, JavaFX & SWT 12
A Swing KeyEvent mit KeyListener und KeyAdapter kürzer schreiben AWT, Swing, JavaFX & SWT 7
B Event Handling KeyEvent für "+"-Tase auf dem Numpad? AWT, Swing, JavaFX & SWT 2
R Integer to KeyEvent AWT, Swing, JavaFX & SWT 2
sylo STRG + TAB KeyEvent abfangen AWT, Swing, JavaFX & SWT 6
earlgrey_tea KeyEvent reagiert nicht auf Eingabe ("Pausentaste") AWT, Swing, JavaFX & SWT 11
Luk10 KeyEvent ... AWT, Swing, JavaFX & SWT 6
M KeyEvent, KEY_TYPED & backspace/left/right. AWT, Swing, JavaFX & SWT 3
H KeyEvent für JFrame AWT, Swing, JavaFX & SWT 3
S Spezielles KeyEvent AWT, Swing, JavaFX & SWT 6
Luma AWTEventListener KeyEvent und KEY_TYPED AWT, Swing, JavaFX & SWT 5
P KeyEvent methode an actionEvent methode weiterleiten AWT, Swing, JavaFX & SWT 5
A KeyEvent bei TAB-Druck AWT, Swing, JavaFX & SWT 10
J KeyEvent bei JTable mehrmals hintereinander ausführen AWT, Swing, JavaFX & SWT 9
J KeyEvent STRG+l, CTRL_DOWN_MASK AWT, Swing, JavaFX & SWT 7
I Pfeiltasten für KeyEvent AWT, Swing, JavaFX & SWT 4
G Windows Taste in KeyEvent? AWT, Swing, JavaFX & SWT 4
M KeyEvent - Programm mit ESC beenden AWT, Swing, JavaFX & SWT 7
H KeyEvent Leerzeichen und Backspace funktioren nicht! HILFE! AWT, Swing, JavaFX & SWT 2
S KeyEvent im JPanel AWT, Swing, JavaFX & SWT 3
G KeyEvent - Probleme AWT, Swing, JavaFX & SWT 6
G Suche einen KeyEvent für die Taste "ä" AWT, Swing, JavaFX & SWT 7
H JavaFX Canvas neu zeichnen anstoßen AWT, Swing, JavaFX & SWT 34
H JavaFX Gedrehter Text auf Canvas (Positionierung) AWT, Swing, JavaFX & SWT 6
ExceptionOfExpectation Textdarstellung auf einem Canvas mit Hilfe von repaint(); AWT, Swing, JavaFX & SWT 6
W Clear Canvas und anschließendes neues Erstellen von Objekten auf Canvas aus ArrayList AWT, Swing, JavaFX & SWT 4
W Canvas oder Polygone? AWT, Swing, JavaFX & SWT 3
Monokuma Canvas Form entfernen AWT, Swing, JavaFX & SWT 2
M Internal Frames und Canvas-Element AWT, Swing, JavaFX & SWT 9
TheJavaKid Auf eine Zeichnung im Canvas reagieren AWT, Swing, JavaFX & SWT 13
M Halbkreiszeichnen(Canvas) - Diesen mit Mouseevents bestücken AWT, Swing, JavaFX & SWT 3
dereki2000 AWT Canvas zeichnet nicht AWT, Swing, JavaFX & SWT 7
D Canvas oder scene graph? AWT, Swing, JavaFX & SWT 16
J Canvas wird nicht angezeigt AWT, Swing, JavaFX & SWT 10
Y Objekte grafisch darstellen ohne GMF - Composite auf Canvas? AWT, Swing, JavaFX & SWT 2
Prafy AWT Klickbare Bereiche auf Canvas AWT, Swing, JavaFX & SWT 2
J JavaFX JavaFX Canvas einfaches Zeichenprogramm AWT, Swing, JavaFX & SWT 7
P MalProgramm mit JScrollPane und Canvas AWT, Swing, JavaFX & SWT 2
Cromewell JavaFX Nur bestimmten Teil eines Canvas rendern und anzeigen AWT, Swing, JavaFX & SWT 2
N Swing Benötige Hilfe um ein Swing Canvas zu speichern AWT, Swing, JavaFX & SWT 4
L JavaFX Canvas max size? AWT, Swing, JavaFX & SWT 1
J JavaFX Rendering von Canvas sehr langsam AWT, Swing, JavaFX & SWT 2
P AWT Canvas freihändig zeichnen AWT, Swing, JavaFX & SWT 1
Regedit JavaFX Java Canvas hört ständig auf zu aktualisieren/malen AWT, Swing, JavaFX & SWT 3
H JavaFX Freezes beim Zeichnen mit Canvas AWT, Swing, JavaFX & SWT 3
Z Canvas in Frame einfügen. Problem mit 4-Gewinnt AWT, Swing, JavaFX & SWT 1
K Fragen zu JavaFx Canvas AWT, Swing, JavaFX & SWT 0
C Java FX Canvas missing getGraphicContext2D AWT, Swing, JavaFX & SWT 5
windl Overlay mit Transparentem JWindow und Canvas AWT, Swing, JavaFX & SWT 2
S JavaFX Canvas - nur eine Figur auf der Zeichenfläche färben? AWT, Swing, JavaFX & SWT 1
R JComponent auf Canvas AWT, Swing, JavaFX & SWT 8
S Canvas durch transparentes JPanel sichtbar machen AWT, Swing, JavaFX & SWT 2
A JavaFX Menubar wird von Canvas überzeichnet AWT, Swing, JavaFX & SWT 8
antonbracke Multiplayer Shooter- Wie geht das mit Canvas & Graphics AWT, Swing, JavaFX & SWT 6
Luk10 KeyBindings mit Canvas? AWT, Swing, JavaFX & SWT 3
B LookAndFeel GWT: Canvas in TabSet nicht sichtbar AWT, Swing, JavaFX & SWT 2
K canvas zeig nach repaint nichts an AWT, Swing, JavaFX & SWT 8
T Canvas clipping AWT, Swing, JavaFX & SWT 4
S 2 Canvas übereinander AWT, Swing, JavaFX & SWT 2
S 2D-Grafik Canvas Problem(Größe) AWT, Swing, JavaFX & SWT 6
K 3D-Grafik Canvas ist ein eigener Frame?! AWT, Swing, JavaFX & SWT 13
F Canvas Objekt außerhalb des Frames zeichnen AWT, Swing, JavaFX & SWT 3
M Wofür Canvas? AWT, Swing, JavaFX & SWT 5
frankred Swing Canvas nach "Window-resize" neu Zeichnen lassen wegen Anzeigefehler AWT, Swing, JavaFX & SWT 4
S Canvas in ScrollPane wird beim scrollen immer neu gezeichnet AWT, Swing, JavaFX & SWT 3
F Nur ein Objekt auf Canvas neu zeichnen AWT, Swing, JavaFX & SWT 4
B AWT Canvas überdeckt nach repaint() JComboBox-Optionen AWT, Swing, JavaFX & SWT 2
lumo SWT Canvas transparent AWT, Swing, JavaFX & SWT 4
2 AWT Zeichnen in Canvas AWT, Swing, JavaFX & SWT 5
B 2D-Grafik Malen/übermalen mit Canvas AWT, Swing, JavaFX & SWT 5
L Dynamisch Objekte in Canvas zeichnen AWT, Swing, JavaFX & SWT 5
G Auf Canvas zeichnen nur über boolean-Abfragen? AWT, Swing, JavaFX & SWT 5
S Canvas-Inhalt in Laufzeit ändern AWT, Swing, JavaFX & SWT 6
R In JFrame oder in Canvas mit grafischen Elemente zeichnen AWT, Swing, JavaFX & SWT 2
I Canvas Repaint Probleme AWT, Swing, JavaFX & SWT 2
S Bild wird auf Canvas in Applet nicht gezeichnet AWT, Swing, JavaFX & SWT 4
G SWT Linie unter transparentes Canvas zeichnen AWT, Swing, JavaFX & SWT 4
F Swing Paint mit Canvas Element AWT, Swing, JavaFX & SWT 35
S SWT Canvas: Flackernde Bilder AWT, Swing, JavaFX & SWT 3
T AWT canvas AWT, Swing, JavaFX & SWT 3
P Canvas: String wird nicht gezeichnet AWT, Swing, JavaFX & SWT 5
T SWT Canvas Koordinaten per MouseMove auslesen AWT, Swing, JavaFX & SWT 1
H Zeichnen auf smartgwt Canvas AWT, Swing, JavaFX & SWT 4
G Drag and Drop JTree to Canvas AWT, Swing, JavaFX & SWT 7
K Swing Sinuskurve zeichnen auf Canvas AWT, Swing, JavaFX & SWT 2
M AWT Component/Canvas erzeugt unerwünschten Rahmen bei paint AWT, Swing, JavaFX & SWT 3
J Canvas / paint() AWT, Swing, JavaFX & SWT 2
D Canvas soll angezeigtes jpg-Bild aktualisieren AWT, Swing, JavaFX & SWT 4
N zeichnen auf awt canvas AWT, Swing, JavaFX & SWT 9
G Ein Wort in einem String färben in einer Canvas AWT, Swing, JavaFX & SWT 10
J Canvas Inhalt als Bild speichern! AWT, Swing, JavaFX & SWT 16
T zeichnen mit canvas AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben