Reputation: 13
There seems to be a problem when using KeyListener on fillPolygon/drawPolygon. I can't move polygons using KeyListener, but I can move other graphics. Here is the java code:
import java.awt.Color;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Exer09Laggui extends Applet implements KeyListener {
int width;
int height;
int carLength = 200;
int carWidth = 75;
int nPoints = 4;
// for body
int body_x = 0;
int body_y = 0;
// for front windshield
// x coordinates
int frontWS_x1 = 125;
int frontWS_x2 = 125;
int frontWS_x3 = 145;
int frontWS_x4 = 145;
// y coordinates
int frontWS_y1 = 62;
int frontWS_y2 = 10;
int frontWS_y3 = 5;
int frontWS_y4 = 67;
int[] xPoints1 = { frontWS_x1, frontWS_x2, frontWS_x3, frontWS_x4 };
int[] yPoints1 = { frontWS_y1, frontWS_y2, frontWS_y3, frontWS_y4 };
public void init() {
width = getSize().width;
height = getSize().height;
setBackground(Color.GRAY);
addKeyListener(this);
}
public void paint(Graphics g) {
// for the car body
g.setColor(Color.BLACK);
// fillRoundRect(int x, int y, int width, int height, int arcWidth, int
// arcHeight)
g.fillRoundRect(body_x, body_y, carLength, carWidth, 30, 30);
// for the front windshield
// fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
g.setColor(Color.white);
g.drawPolygon(xPoints1, yPoints1, nPoints);
g.setColor(new Color(200, 200, 255));
g.fillPolygon(xPoints1, yPoints1, nPoints);
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
// for body
body_y += 5;
// for front windshield
frontWS_y1 += 5;
frontWS_y2 += 5;
frontWS_y3 += 5;
frontWS_y4 += 5;
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
// for body
body_y -= 5;
// for front windshield
frontWS_y1 -= 5;
frontWS_y2 -= 5;
frontWS_y3 -= 5;
frontWS_y4 -= 5;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
// for body
body_x -= 5;
// for front windshield
frontWS_x1 -= 5;
frontWS_x2 -= 5;
frontWS_x3 -= 5;
frontWS_x4 -= 5;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
// for body
body_x += 5;
// for front windshield
frontWS_x1 += 5;
frontWS_x2 += 5;
frontWS_x3 += 5;
frontWS_x4 += 5;
}
repaint();
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
and here is the html... I don't know what is wrong, Please Help...
<html>
<body>
<applet code = 'Exer09Laggui.class'
width = '1340'
height = '635'/>
</body>
</html>
Upvotes: 1
Views: 4316
Reputation: 285405
It's a focus issue and the key is to get focus onto the applet after it is visible, and the latter part is the tricky part, since just calling requestFocus()
in the init()
method won't work. You can do it in a Swing Timer in init, or override setVisible as shown below as kludge 1 or kludge 2:
import java.applet.Applet;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JOptionPane;
public class Exer09Laggui extends Applet implements KeyListener {
private boolean firstSetVisible = true;
public void init() {
addKeyListener(this);
// kludge one:
int timerDelay = 400;
new javax.swing.Timer(timerDelay , new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Exer09Laggui.this.requestFocusInWindow();
((javax.swing.Timer)evt.getSource()).stop();
}
}).start();
}
// kludge two
public void setVisible(boolean b) {
super.setVisible(b);
if (firstSetVisible) {
requestFocusInWindow();
firstSetVisible = false;
}
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
JOptionPane.showMessageDialog(this, "down");
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
JOptionPane.showMessageDialog(this, "up");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
JOptionPane.showMessageDialog(this, "left");
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
JOptionPane.showMessageDialog(this, "right");
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
Another trick when debugging these types of things is to simplify your code as much as possible so that only the essentials remain that are required to demonstrate the error. Which code is easier for us to read and understand, your code, or my simpler code -- and you'll see why this is helpful to us. it's also helpful to you since you eliminate things that might complicate the issue and thereby deal with just the pure problem.
Edit
To move the "windshield" you need to update the data that the windshield uses to draw with. What is that data? The two int[] arrays, xPoints1 and yPoints1. Since your code doesn't change these, then the windshields will remain in place. You need to add something like:
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
// for body
body_y += 5;
// for front windshield
frontWS_y1 += 5;
frontWS_y2 += 5;
frontWS_y3 += 5;
frontWS_y4 += 5;
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
// for body
body_y -= 5;
// for front windshield
frontWS_y1 -= 5;
frontWS_y2 -= 5;
frontWS_y3 -= 5;
frontWS_y4 -= 5;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
// for body
body_x -= 5;
// for front windshield
frontWS_x1 -= 5;
frontWS_x2 -= 5;
frontWS_x3 -= 5;
frontWS_x4 -= 5;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
// for body
body_x += 5;
// for front windshield
frontWS_x1 += 5;
frontWS_x2 += 5;
frontWS_x3 += 5;
frontWS_x4 += 5;
}
// ***** note added code *****
xPoints1 = new int[]{ frontWS_x1, frontWS_x2, frontWS_x3, frontWS_x4 };
yPoints1 = new int[]{ frontWS_y1, frontWS_y2, frontWS_y3, frontWS_y4 };
repaint();
}
Upvotes: 1
Reputation: 168825
The array values don't update automatically, because they are primitives, not objects.
// <applet code='Exer09Laggui' width=400 height=200></applet>
import java.awt.Color;
import java.awt.Graphics;
import java.applet.Applet;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Exer09Laggui extends Applet implements KeyListener {
int width;
int height;
int carLength = 200;
int carWidth = 75;
int nPoints = 4;
// for body
int body_x = 0;
int body_y = 0;
// for front windshield
// x coordinates
int frontWS_x1 = 125;
int frontWS_x2 = 125;
int frontWS_x3 = 145;
int frontWS_x4 = 145;
// y coordinates
int frontWS_y1 = 62;
int frontWS_y2 = 10;
int frontWS_y3 = 5;
int frontWS_y4 = 67;
int[] xPoints1 = { frontWS_x1, frontWS_x2, frontWS_x3, frontWS_x4 };
int[] yPoints1 = { frontWS_y1, frontWS_y2, frontWS_y3, frontWS_y4 };
public void init() {
width = getSize().width;
height = getSize().height;
setBackground(Color.GRAY);
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
}
public void paint(Graphics g) {
// for the car body
g.setColor(Color.BLACK);
// fillRoundRect(int x, int y, int width, int height, int arcWidth, int
// arcHeight)
g.fillRoundRect(body_x, body_y, carLength, carWidth, 30, 30);
// for the front windshield
// fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
g.setColor(Color.white);
g.drawPolygon(xPoints1, yPoints1, nPoints);
g.setColor(new Color(200, 200, 255));
g.fillPolygon(xPoints1, yPoints1, nPoints);
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
// for body
body_y += 5;
// for front windshield
frontWS_y1 += 5;
frontWS_y2 += 5;
frontWS_y3 += 5;
frontWS_y4 += 5;
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
// for body
body_y -= 5;
// for front windshield
frontWS_y1 -= 5;
frontWS_y2 -= 5;
frontWS_y3 -= 5;
frontWS_y4 -= 5;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
// for body
body_x -= 5;
// for front windshield
frontWS_x1 -= 5;
frontWS_x2 -= 5;
frontWS_x3 -= 5;
frontWS_x4 -= 5;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
// for body
body_x += 5;
// for front windshield
frontWS_x1 += 5;
frontWS_x2 += 5;
frontWS_x3 += 5;
frontWS_x4 += 5;
}
xPoints1[0] = frontWS_x1;
xPoints1[1] = frontWS_x2;
xPoints1[2] = frontWS_x3;
xPoints1[3] = frontWS_x4;
yPoints1[0] = frontWS_y1;
yPoints1[1] = frontWS_y2;
yPoints1[2] = frontWS_y3;
yPoints1[3] = frontWS_y4;
repaint();
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
Upvotes: 1