I have an assignment that I am doing where I am supposed to implement and design an application that plays a game called catch the creature. Have the creature appear at a random location then disappear and reappear somewhere else. The goal is to "catch" the creature by clicking the creature with a mouse button. Record the number of times the creature is caught.
I need help just displaying the creature which is an JPEG of a pikachu, I have tried a few things but none of them work. Any help is appreciated thank you!
Main Code:
import javax.swing.*;
public class Catch_The_Creature
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Catch the Creature");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Creature panel = new Creature();
JOptionPane.showMessageDialog(frame, "Catch Pikachu!");
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
Creature Code:
import java.awt.*;
import java.util.Random;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Creature extends JPanel
{
private final int WIDTH = 400, HEIGHT = 300;
private final int DELAY=20, IMAGE_SIZE = 60;
private ImageIcon image;
private int pikachuX, pikachuY;
private int x, y;
private int catchCount=0;
private static Random generator = new Random();
private Timer time;
private ActionListener updater;
private JLabel countLabel;
public Creature()
{
image = new ImageIcon("image/pikachu.jpg");
time = new Timer(DELAY, updater);
addMouseListener ((MouseListener) new MouseClickedListener());
setBackground (Color.green);
setPreferredSize(new Dimension(1900,1000));
time.start();
}
public boolean point(int x, int y)
{
if (x == pikachuX && y == pikachuY)
{
catchCount++;
return true;
}
return false;
}
public int getCatchCount()
{
return catchCount;
}
private class MouseClickedListener extends MouseAdapter
{
public void mouseClicked(MouseEvent event)
{
point(event.getX(), event.getY());
}
}
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.drawImage(image.getImage(),WIDTH, HEIGHT, null);
page.drawString("Pikachus Captured: " + catchCount, 10, 35);
setFont(new Font("Arial", Font.BOLD,35));
}
public void actionPerformed(ActionEvent event)
{
time.setDelay(1000);
x += pikachuX;
y += pikachuY;
if (x <= 0 || x >= WIDTH-IMAGE_SIZE)
pikachuX = pikachuX * -1;
if (y <= 0 || y >= HEIGHT-IMAGE_SIZE)
pikachuY = pikachuY * -1;
repaint();
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0){}
}
It doesn't look like you ever add the ImageIcon to the panel or tell it to paint in the paintComponent() method.
First solution [Preferred]: Add ImageIcon to the panel. In the constructor
super.add(image);
Make sure you use the correct layout (probably a null or absolute layout) and that you update the coordinates of the ImageIcon itself, not just some member variables.
Second solution: Paint the ImageIcon in the paintComponent() method. This is probably discouraged because it goes against the general Swing principles.
Make sure your Image file is in the right directory. If you're running from netbeans or eclipse your file structure should look like this
ProjectRoot
src
bin
image
pikachu.jpeg
Since you are using "image/pikachu.png", you image filder should be a child of the project root folder as that's where the IDE will first search fore your file path
Edit: To draw image. Instead of using ImageIcon, use BufferedImage
try {
BufferedImage image = ImageIO.read("image/pikachu.jpeg");
} catch (Exception ex){
ex.printStackTrace();
}
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.drawImage(image, x, y, heightYouWant, widthYouWant, this);
page.drawString("Pikachus Captured: " + catchCount, 10, 35);
setFont(new Font("Arial", Font.BOLD,35));
}
All i needed to do was put values on where I wanted the picture to start at in the constructor.
public Creature()
{
image = new ImageIcon ("pikachu.png");
time = new Timer(DELAY, updater);
x = 0;
y = 50;
addMouseListener ((MouseListener) new MouseClickedListener());
setBackground (Color.green);
setPreferredSize(new Dimension(1900,1000));
time.start();
}
While still using an Image Icon and still paint the image in the paint component.
public void paintComponent(Graphics page)
{
super.paintComponent(page);
image.paintIcon (this, page, x, y);
page.drawString("Pikachus Captured: " + catchCount, 10, 35);
setFont(new Font("Arial", Font.BOLD,35));
}
Related
EDIT: First question solved, see Roberto Attias 's answer and maybe read the comment . Still there's the second issue.
I have to do a small 2D game in Java and I want to stick to AWT as much as possible, ( so no SWING nor Java2D unless absolutely necessary).
I have a window and I can draw an image on it but there's two issues.
First I can't draw more than one Image. In fact with some of my test when in debug I can see that my program will draw my two images only to delete them and re-draw the first image.
Second, that first image which is re-drawn is not at the coordinate it should ( its slightly on the left and on below )
For now I have something like that:
public class AwtManager {
private Frame frame;
private Panel panel;
public AwtManager(){
frame = new Frame("a");
frame.setSize(800,600);
frame.setLocation(100, 100);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEnvent){
System.exit(0);
}
});
panel = new Panel();
// here I tried to setBounds to solve my second issue, it didn't work
//panel.setBounds(0, 0, 800, 600);
frame.add(panel);
frame.setVisible(true);
}
This part open my windows and works quite nicely but my second issue seems to be caused by the borders of my frame / panel so there might be some changement to do here.
public void showMytwoImagesFFS(ArrayList<ImageComponent> images){
for (int i = 0; i < images.size(); i++) {
panel.add(images.get(i);
//And this is where I'm lost
}
// or here maybe
frame.setVisible(true);
}
}
In this second part I tried every combination of Component.paint(g), Component.update(g), Component.repaint(), Component.setVisible(true) I could think of.
My object ImageComponent is simply this:
public class ImageComponent extends Component {
private static final long serialVersionUID = 1L;
private BufferedImage img;
private int x;
private int y;
public ImageComponent(String path,int x, int y){
try{
img = ImageIO.read(new File(path));
this.x = x;
this.y = y;
}
catch (IOException e){
e.printStackTrace();
}
}
This function getPreferredSize() disturbs me like hell, it should return the preferred size of the ImageComponent but apparently I have to put the size of my frame/ panel otherwise it won't work.
public Dimension getPreferredSize(){
return new Dimension(800,600);
}
And finally my paint, update, repaint:
public void paint(Graphics g){
g.drawImage(img, x, y,null);
}
public void update(Graphics g){
super.update(g);
}
public void repaint(){
this.getGraphics().drawImage(img, x, y, null);
}
}
I highly doubt that those three look like what they should but I find the documents on the subject very hard to understand.
So pleas, could you help me with those issues, and by the way if you know how Component.setVisible(boolean) works i would like to know because in debug mod, this function made me loose some hair.
EDIT:
Here's a screenshot of my window knowing that I asked for two red square (there are Images not Rectangle), one a 0,0, the other at 200, 200.
EDIT 2:
Here's a fully runnable code (i think):
import java.awt.*;
import java.util.*;
import java.awt.event.*;
public class AwtManager {
private Frame frame;
private Panel panel;
public static void main(String args[]) {
new AwtManager();
ArrayList<ImageComponent> images = new ArrayList<>();
images.add(new ImageComponent("myimage.jpg", 0, 0));
images.add(new ImageComponent("myimage.jpg", 200, 200));
showMytwoImagesFFS(images);
}
public AwtManager(){
frame = new Frame("a");
frame.setSize(800,600);
frame.setLocation(100, 100);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEnvent){
System.exit(0);
}
});
panel = new Panel();
frame.add(panel);
frame.setVisible(true);
}
public void showMytwoImagesFFS(ArrayList<ImageComponent> images){
for (int i = 0; i < images.size(); i++) {
panel.add(images.get(i));
}
frame.setVisible(true);
}
}
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
public class ImageComponent extends Component {
private static final long serialVersionUID = 1L;
private BufferedImage img;
private int x;
private int y;
public ImageComponent(String path,int x, int y){
try{
img = ImageIO.read(new File(path));
this.x = x;
this.y = y;
}
catch (IOException e){
e.printStackTrace();
}
}
public Dimension getPreferredSize(){
return new Dimension(800,600);
}
public void paint(Graphics g){
g.drawImage(img, x, y,null);
}
public void update(Graphics g){
super.update(g);
}
public void repaint(){
this.getGraphics().drawImage(img, x, y, null);
}
}
Just a quick thought, but do you know the visibility of each of your images in that ArrayList? I.e.
public void showMytwoImagesFFS(ArrayList<ImageComponent> images){
for (int i = 0; i < images.size(); i++) {
images.get(i).setVisible(true);//is the visibility actually true?
panel.add(images.get(i);
}
// or here maybe
frame.setVisible(true);
}
Also, do you have screenshots of how your program looks at the moment? With gui problems, I find they're easier to solve if I can see what's going on.
This is your code, slightly modified to run. In the future, please post fully runnable examples.
import java.awt.*;
import java.util.*;
import java.awt.event.*;
public class AwtManager {
private Frame frame;
private Panel panel;
public static void main(String args[]) {
new AwtManager();
}
public AwtManager(){
frame = new Frame("a");
frame.setSize(800,600);
frame.setLocation(100, 100);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEnvent){
System.exit(0);
}
});
panel = new Panel();
// here I tried to setBounds to solve my second issue, it didn't work
//panel.setBounds(0, 0, 800, 600);
frame.add(panel);
ArrayList<ImageComponent> images = new ArrayList<>();
images.add(new ImageComponent("myimage.jpg", 0, 0));
showMytwoImagesFFS(images);
frame.setVisible(true);
}
public void showMytwoImagesFFS(ArrayList<ImageComponent> images){
for (int i = 0; i < images.size(); i++) {
panel.add(images.get(i));
}
}
}
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
public class ImageComponent extends Component {
private static final long serialVersionUID = 1L;
private BufferedImage img;
private int x;
private int y;
public ImageComponent(String path,int x, int y){
try{
img = ImageIO.read(new File(path));
this.x = x;
this.y = y;
}
catch (IOException e){
e.printStackTrace();
}
}
public Dimension getPreferredSize(){
return new Dimension(800,600);
}
public void paint(Graphics g){
g.drawImage(img, x, y,null);
}
public void update(Graphics g){
super.update(g);
}
public void repaint(){
this.getGraphics().drawImage(img, x, y, null);
}
}
I've just started my course Programming 2, and its quite a jump from the introducting course we had before. I am to make a program that has three buttons "red", "blue", "green" and when I click "red" a red square is to appear. When I click another button, there are more squares, and the color of the square depends on the button I press.
My problem is, that when I press "red", I have to press another button before the red square appears. So in reality it will seem like the buttons I press are connected to a wrong action. It's really hard to describe, but it's as is there is a "delay of one action".. Can you provide a novice like me any assistance? I have tree classes in total: SquareIcon, CompositeIcon, and a tester with the frame.
It should only be necessary to look at the last class I pasted here.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
/**
* Made by Rasmus
* Version 13-11-2014.
*/
public class SquareIcon implements Icon{
private int size;
private Color color;
public SquareIcon(int size, Color color) {
this.size = size;
this.color = color;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
Rectangle2D rec = new Rectangle2D.Double(x, y, size, size);
g2.fill(rec);
g2.setColor(color);
}
public int getIconWidth() {
return size;
}
public int getIconHeight() {
return size;
}
}
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
/**
* Made by Rasmus
* Version 13-11-2014.
*/
public class CompositeIcon implements Icon {
private ArrayList<Icon> icons;
public CompositeIcon() {
icons = new ArrayList<Icon>();
}
public void paintIcon(Component c, Graphics g, int x, int y) {
for (Icon i : icons) {
i.paintIcon(c, g, x, y);
x += i.getIconWidth();
}
}
public int getIconWidth() {
int width = 0;
for (Icon i : icons) {
width += i.getIconWidth();
}
return width;
}
public int getIconHeight() {
int height = 0;
for (Icon i : icons) {
if (i.getIconHeight() > height) {
height = i.getIconHeight();
}
}
return height;
}
public void addIcon(Icon i) {
icons.add(i);
}
}
And the last:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Made by Rasmus
* Version 13-11-2014.
*/
public class FrameTest implements ActionListener {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
JButton redButton = new JButton("Rød");
JButton greenButton = new JButton("Grøn");
JButton blueButton = new JButton("Blå");
frame.add(redButton);
frame.add(greenButton);
frame.add(blueButton);
final CompositeIcon ci = new CompositeIcon();
final SquareIcon red = new SquareIcon(50, Color.RED);
final SquareIcon green = new SquareIcon(50, Color.GREEN);
final SquareIcon blue = new SquareIcon(50, Color.BLUE);
JLabel squareLabel = new JLabel(ci);
frame.add(squareLabel);
redButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ci.addIcon(red);
frame.pack();
frame.repaint();
}
});
greenButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ci.addIcon(green);
frame.pack();
frame.repaint();
}
});
blueButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ci.addIcon(blue);
frame.pack();
frame.repaint();
}
});
frame.setSize(250, 75);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
}
}
Two things I would suggest:
First, I would advise that you delete the last action performed block. That block may be causing the error.
Second, if that isn't causing the error, try inserting breakpoints or print statements to see when it enter the action performed loop, then you can work from there.
I have a Java Swing question. I am currently coding the game checkers as an exercise. I created the checkers pieces as JLabels with an ImageIcon of the checkers piece. I added a MouseListener to update the x and y locations of the label on the frame, and am using an ActionListener to set the label location every 5 milliseconds based on a timer. It works except that the label jumps around the screen when I am dragging it with the mouse (instead of tracking with the mouse).
Does anybody know what is causing this? Is there an easy solution based on the code I currently have?
I am new to swing stuff so I realize I could be taking the wrong approach entirely. I am unable to attach the image, but it is just a 80 x 80 px square with a solid black circle in the foreground and the background is transparent. Thanks a lot!
package checkers;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.*;
public class Piece2 extends JLabel implements
ActionListener, MouseListener, MouseMotionListener{
ImageIcon checkerIcon;
String color = null;
Timer t = new Timer(5, this);
int x, y, width = 80, height = 80;
public Piece2(int initX, int initY, String color){
this.x = initX;
this.y = initY;
this.color = color;
t.start();
setLocation(x, y);
setSize(width, height);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
addMouseMotionListener(this);
addMouseListener(this);
if(color.equals("Red")){
checkerIcon = new ImageIcon("/RedChecker.png");
}
else if(color.equals("Black")){
checkerIcon = new ImageIcon("/BlackChecker.png");
}
setIcon(checkerIcon);
}
#Override
public void actionPerformed(ActionEvent e) {
setLocation(x, y);
}
/**
* Mouse Event Listeners
*
*/
#Override
public void mouseDragged(MouseEvent e) {
this.x = e.getX();
this.y = e.getY();
}
#Override
public void mouseReleased(MouseEvent e) {
x = x - (x % 50);
y = y - (y % 50);
}
#Override
public void mouseMoved(MouseEvent e) {}
#Override
public void mouseClicked(MouseEvent e) {}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
//To test Piece
public static void main(String[] args){
Piece2 p1 = new Piece2(0, 0, "Black");
JFrame frame1 = new JFrame("Test");
frame1.setSize(800, 800);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.add(p1);
frame1.setVisible(true);
}
}
Im working on an assignment where an image moves around and when the user clicks on the image it will change and as soon as it moves again via timer class, the images chages back to the original. As of now I can click the image to change it, but it wont change back when it is time to move again. Is there a way to change back after it moves?
Here is my code
Main:
import java.awt.*;
import javax.swing.*;
public class Catch_The_Creature
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Catch the Creature");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JOptionPane.showMessageDialog(frame, "Catch Pikachu!");
frame.getContentPane().add(new Creature());
frame.pack();
frame.setVisible(true);
}
}
Panel:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Creature extends JPanel
{
private static final int DELAY=900;
private Random generator = new Random();
private ImageIcon image, image1;
private Timer timer;
private int x, y;
private int catchCount=0;
public Creature()
{
image = new ImageIcon ("pikachu.png");
image1 = new ImageIcon ("pokeball.png");
timer = new Timer(DELAY, new MoveListener());
x = generator.nextInt( 1900 );
y = generator.nextInt(1000);
addMouseListener (new MouseClickedListener());
setBackground (Color.green);
setPreferredSize(new Dimension(1900,1000));
timer.start();
}
//Draws the image.
public void paintComponent(Graphics page)
{
super.paintComponent(page);
image.paintIcon (this, page, x, y);
page.drawString("Pikachus Captured: " + catchCount, 10, 35);
setFont(new Font("Arial", Font.BOLD,35));
}
//Method for moving the image.
public void move()
{
timer.start();
x = generator.nextInt( 1900 );
y = generator.nextInt(1000);
if (timer.isRunning())
{
x = generator.nextInt( 1900 );
y = generator.nextInt(1000);
}
repaint();
}
//Method for getting the number of times caught.
public int getCatchCount()
{
return catchCount;
}
//Makes the image move
private class MoveListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
move();
repaint();
}
}
//Records when the user clicks the image.
private class MouseClickedListener extends MouseAdapter
{
public void mouseClicked(MouseEvent event)
{
if((event.getButton() == MouseEvent.BUTTON1) && between(event.getX(), x, x + image.getIconWidth()) && between(event.getY(), y, y + image.getIconHeight()))
{
System.out.println("CAUGHT ONE!");
catchCount++;
move();
image=image1;
}
}
}
private static boolean between(int x, int lower, int upper)
{
return (x >= lower) && (x <= upper);
}
}
i hope i understand what do you try to achieve. first you need 3 Images:
private ImageIcon imageToDraw, image1, image2;
Creature will look like this now:
public Creature()
{
image1 = new ImageIcon ("pikachu.png");
image2 = new ImageIcon ("pokeball.png");
imageToDraw = image1;
...
}
in move() you should set the image to image1:
public void move()
{
imageToDraw = image1;
timer.start();
x = generator.nextInt( 1900 );
...
}
dont forget to change image to imageToDraw in paint():
public void paintComponent(Graphics page)
{
super.paintComponent(page);
imageToDraw.paintIcon (this, page, x, y);
...
}
remove move(); from onclick-event and change image to imageToDrwa in click-action:
public void mouseClicked(MouseEvent event)
{
if((event.getButton() == MouseEvent.BUTTON1) && between(event.getX(), x, x + image.getIconWidth()) && between(event.getY(), y, y + image.getIconHeight()))
{
System.out.println("CAUGHT ONE!");
catchCount++;
//move(); should be removed
imageToDraw=image1;
}
}
edit:move(); removed from onclick-event
You need a way to paint either Image. Right now you are just assigning image to image1 and when you do that the Image that is from "pikachu.png" disappears.
Without restructuring too much you can just make a flag for which one to paint:
/* as a field */
private boolean justCaptured;
Now you have to change your painting logic a little:
if (justCaptured) {
image1.paintIcon (this, page, x, y);
} else {
image.paintIcon (this, page, x, y);
}
Now the first thing you do is instead of reassigning image, set the flag to true:
System.out.println("CAUGHT ONE!");
catchCount++;
justCaptured = true;
move();
There's one last thing you need to do which is to set the flag back to false for the next draw. There are some different ways to approach this but the simplest I see without refactoring a number of things is to queue it for later:
System.out.println("CAUGHT ONE!");
catchCount++;
justCaptured = true;
move();
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() {
justCaptured = false;
}
});
Using invokeLater will enqueue it at the end of EventQueue and it will be changed after previously queued tasks complete. So after the mouse event exits and then after the repaint you've just requested in move.
"I post all of it in case anyone would like to give advice on other things general things."
You're calling timer.start in move and this doesn't appear necessary. Timers repeat by default.
move generates x and y twice. Since you call timer.start in the constructor, timer.isRunning will always be true.
MoveListener calls repaint after calling move but move also calls repaint.
"Also so people can test it themselves if they would like to."
We can't run it because we don't have your images. If you want to post it so we can run it change the code so it works without them. Otherwise we have to go and change it somehow ourselves. Here's a static method that returns a blank ImageIcon:
public static ImageIcon createBlankIcon(int w, int h, Color color) {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(color);
g2d.fillRect(0, 0, w, h);
g2d.dispose();
return new ImageIcon(img);
}
You can substitute something like that for content, eg: image = getBlankIcon(50, 50, Color.RED);.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Panel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
final static int WIDTH = 800;
final static int HEIGHT = 600;
private int x = 40, y = 49, r = 20;
Dimension SIZE = new Dimension(WIDTH, HEIGHT);
public Panel() {
setLayout(new BorderLayout());
setPreferredSize(SIZE);
setMaximumSize(SIZE);
setMinimumSize(SIZE);
setBackground(Color.cyan);
setFocusable(true);
requestFocus();
new input(this);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.fillOval(x, y, r, r);
repaint();
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class input extends KeyAdapter {
private Panel panel;
public input(Panel panel) {
panel = new Panel();
panel.addKeyListener(this);
}
#Override
public void keyPressed(KeyEvent e) {
int keycode = e.getKeyCode();
int x = panel.getX();
int y = panel.getY();
if (keycode == KeyEvent.VK_LEFT) {
panel.setX(x - 1);
}
if (keycode == KeyEvent.VK_RIGHT) {
panel.setX(x + 1);
}
}
}
I'm a Java newbie. I was trying to make a class specially for KeyListener
but it just doesn't work. I can't figure out what I did wrong.
It might be meaningless to make a inputhandler class, and it controls only the only one class (jpanel), but i used to put all of my code in one single class.. it looks so bad. i'm learning to make them into more separate classes or make them more object-oriented~
I just confuse when to make a new class, and when not.
please help me, could you tell me what i did wrong with my code above. Was my thought wrong or just the code?
This looks like the first reason your KeyListener doesn't work:
public input(Panel panel) {
panel = new Panel();
panel.addKeyListener(this);
}
When you do this:
new input(this);
Because you are also doing this:
panel = new Panel();
You are adding the KeyListener to new Panel(), not the panel you are passing in to the constructor with this.
Personally I don't see a problem with creating a listener object just to listen, although I do not think that is necessary here.
Although presumably this will not have an effect on your listener, one other problem I see is that you are overriding paint which you should not be doing in Swing. You should be overriding paintComponent. See Painting in AWT and Swing: http://www.oracle.com/technetwork/java/painting-140037.html#callbacks
Also as far as style goes, class names start with a capital letter in Java. Your input class should be named Input.