Reputation: 141
In the code below, the arrow keys are used to draw a line as in etch-a-sketch (but you have to resize the window first to trigger the panel's focus request at the right time -- that's a question for a different time, perhaps). The graphics command g.drawLine() occurs in the keyPressed() function, repaint() is not called explicitly, but the image updates itself as the arrow keys are pressed. Why is that? All the documentation I have looked at only talks about the JPanel automatically repainting itself when it is resized or uncovered.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Etch extends JPanel implements KeyListener{
public int xPrev, yPrev, xNew, yNew, inc;
public Etch(int start){
xPrev = start;
yPrev = start;
xNew = start;
yNew = start;
inc = 10;
addKeyListener(this);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
this.requestFocusInWindow();
}
public static void main(String[] args)
{
JFrame w = new JFrame("Keyboard");
w.setBounds(100, 100, 600, 600);
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Etch panel = new Etch(200);
panel.setFocusable(true);
panel.setBackground(Color.RED);
Container c = w.getContentPane();
c.add(panel);
w.setResizable(true);
w.setVisible(true);
}
public void keyPressed(KeyEvent e){
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP){
xPrev = xNew;
yPrev = yNew;
yNew -= inc;
}
if (code == KeyEvent.VK_DOWN){
xPrev = xNew;
yPrev = yNew;
yNew += inc;
}
if (code == KeyEvent.VK_LEFT){
xPrev = xNew;
yPrev = yNew;
xNew -= inc;
}
if (code == KeyEvent.VK_RIGHT){
xPrev = xNew;
yPrev = yNew;
xNew += inc;
}
Graphics g = this.getGraphics();
g.setColor(Color.BLUE);
g.drawLine(xPrev, yPrev, xNew, yNew);
}
// Not used but required by the KeyListener interface
public void keyReleased (KeyEvent e) { }
public void keyTyped (KeyEvent e) { }
}
Upvotes: 0
Views: 60
Reputation: 347184
this.requestFocusInWindow();
is a bad idea within the paintComponent
method. Painting should paint the current state and never change the state of the componentgetGraphics
is not how painting is done in Swing. Custom painting should be done from within the context of the paintComponent
method. See Painting in AWT and Swing and Performing Custom Painting for more detailsKeyListener
, as you can control the focus level required to trigger the key events. See How to Use Key Bindings for more detailsRemember, you don't control the paint process in Swing, a paint cycle can be triggered by any number of events, most of which you don't actually control. Try working within the process instead of out of it.
Start by creating a List
of java.awt.Point
. Add each point to the List
when a key event occurs. Use the paintComponent
to iterate over the List
and paint the lines between the Point
s...
Upvotes: 2