Can someone tell me what I need to do to get ImageObserver to work. I thought this would work. I'd like it to print a message when the image loads but it doesn't... What am I doing wrong? This can probably be answered easily.
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImageTest extends JPanel implements ImageObserver {
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y,
int width, int height) {
if((infoflags & ALLBITS) == 0) {
System.out.println("Processing still");
return true;
} else {
System.out.println("Done processing");
return false;
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, this);
}
BufferedImage img;
public ImageTest (){
try {
img = ImageIO.read(new File("res/soccer-ball.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]) {
JFrame f = new JFrame();
f.setContentPane(new ImageTest());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1000, 1000);
f.setVisible(true);
}
}
Instead of putting it in the drawImage simply use the ToolKit to process your image where you will use the instance of your ImageObserver to prepare the image
change this:
try {
img = ImageIO.read(new File("res/soccer-ball.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
to:
public class ImageTest extends JPanel implements ImageObserver {
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y,
int width, int height) {
if((infoflags & ALLBITS) == 0) {
System.out.println("Processing still");
return true;
} else {
System.out.println("Done processing");
repaint();
return false;
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, this);
}
Image img;
public ImageTest (){
Toolkit toolkit = Toolkit.getDefaultToolkit();
img = toolkit.getImage("res/soccer-ball.jpg");
toolkit.prepareImage(img, -1, -1, this);
}
public static void main(String args[]) {
JFrame f = new JFrame();
f.setContentPane(new ImageTest());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1000, 1000);
f.setVisible(true);
}
}
Where you need to repaint the JPanel when the image is finished processing or else the image wont show.
For one thing, JPanel already implements ImageObserver, so overriding imageUpdate in this way likely breaks the panel's normal functionality.
Also, you implement ImageObserver but never subscribe/register to observe anything.
Try this:
...
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
if ((infoflags & ALLBITS) == 0) {
System.out.println("Processing still");
} else {
System.out.println("Done processing");
}
return super.imageUpdate(img, infoflags, x, y, w, h);
}
...
public ImageTest() {
try {
img = ImageIO.read(new File("res/soccer-ball.jpg"));
prepareImage(img, this);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
...
Related
I'm working on image processing but I can't find a way to paint GUI RGB with binary image reading. I'm stuck with paintComponent area.
I can read file but cant paint RGB values to GUI. Can somebody guide me please?
This is what I have done so far:
private int ws;
private FileInputStream fis;
mybin(){
try {
fis = new FileInputStream("mybin.bin");
String mn = getMagicNumber();
System.out.println(mn);
skipWhitespace();
int width = readNumber();
System.out.println(width);
skipWhitespace();
int height = readNumber();
System.out.println(height);
skipWhitespace();
int maxNum = readNumber();
System.out.println(maxNum);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e2) {}
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600,600);
this.setVisible(true);
}
private String getMagicNumber() {
byte [] magicNum = new byte[2];
try {
fis.read(magicNum);
} catch (IOException e) {
e.printStackTrace();
}
return new String(magicNum);
}
private void skipWhitespace() {
try {
ws = fis.read();
while(Character.isWhitespace(ws))
ws = fis.read();
} catch (IOException e) {
e.printStackTrace();
}
}
private int readNumber() {
String wstr = "";
try {
while(!Character.isWhitespace(ws)) {
//while(Character.isDigit(ws))
wstr = wstr + (ws-'0'/*48*/);
ws = fis.read();
}
}catch(IOException e2) {}
System.out.println(wstr);
return Integer.parseInt(wstr);
}
class DrawingPanel extends JPanel{
#Override
public void paintComponent(Graphics g) {
}
}
public static void main(String [] args) {
new mybin();
}
}
If you have a data structure to hold RGB values and want to paint them on the screen:
First you should create an image of them, first. Something like this:
// Create an image, with given dimensions, and RGB palette...
final BufferedImage image = new BufferedImage( width, height, BufferedImage.TYPE_INT_RGB);
// Paint the RGB values (EG from arrays) to the image
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
// Convert the R,G,B values to a single int
final int rgb = r[x,y]*0x10000 + g[x,y]*1x100 + b[x,y];
// Color the pixel...
image.setRGB(x, y, rgb);
}
Then display it on your GUI.
This could be done, creating a special component, and performing painting, see c0der's answer.
Or you could just create an Icon, and add it to any JLabel:
label.setIcon(new ImageIcon(image));
Painting a BufferedImage can be as simple as:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class ImageFrame extends javax.swing.JFrame {
public ImageFrame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(new GraphicsPanel());
pack();
setVisible(true);
}
public static void main(final String[] args){
new ImageFrame();
}
}
class GraphicsPanel extends JPanel {
private BufferedImage image;
//always use publicly accessible resources when posting mcve
private final String imagePath = "https://upload.wikimedia.org/wikipedia/commons/3/3f/Crystal_Project_bug.png";
GraphicsPanel(){
try {
image = ImageIO.read(new URL(imagePath)); //or image = ImageIO.read(new File(...));
} catch(final IOException e) {e.printStackTrace(); }
setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
}
#Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
}
For some reason, my KeyListener works just fine and fires off the Booleans to make down and up true and false and the y value changes according to those Booleans exactly how I want it to. My problem is that for some reason, the red rectangle appears to grow in size rather than move, and I'm pretty sure that it's because the previous frame is not cleared. I tried to use super.paintComponent(g); to clear the frame but this accomplishes nothing. Here's the code:
JFrame:
import java.awt.*;
import javax.swing.*;
public class H extends JFrame
{
public H()
{
super("Atlas Blade");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
pack();
P p = new P();
Insets frameInsets = getInsets();
int frameWidth = p.getWidth() +
(frameInsets.left + frameInsets.right);
int frameHeight = p.getHeight() + (
frameInsets.top + frameInsets.bottom);
setPreferredSize(new Dimension(frameWidth, frameHeight));
setLayout(null);
add(p);
pack();
setVisible(true);
}
}
JPanel:
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.image.*;
public class P extends JPanel implements KeyListener, Runnable
{
private long updateCount=0;
private long paintCount=0;
private int updatesPerSecond = 50;
private boolean aLeft,aRight,aDown,aUp=false;
private boolean up,down,left,right=false;
int x = 20;
int y=20;
Hb box = new Hb(x,y);
Rectangle rect = new Rectangle(0,300,300,50);
BufferedImage buffer;
public P()
{
super();
setSize(600,350);
//setSize(50,50);
buffer = new BufferedImage (600,350,BufferedImage.TYPE_4BYTE_ABGR);
addKeyListener(this);
Thread jim = new Thread(this);
jim.start();
}
public void run()
{
int waitToUpdate = 1000/updatesPerSecond;
long startTime = System.nanoTime();
while(true)
{
boolean shouldRepaint = false;
long currentTime = System.nanoTime();
long updatesNeeded = (((currentTime-startTime) / 1000000))/ waitToUpdate;
for(long x = updateCount; x< updatesNeeded; x++)
{
updateGame();
shouldRepaint=true;
updateCount++;
}
if(shouldRepaint)
{
paintCount++;
repaint();
}
try
{
Thread.sleep(5);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics bg = buffer.getGraphics();
bg.setColor(Color.BLACK);
bg.drawRect(0,300,300,50);
bg.setColor(Color.RED);
bg.fillRect(x,y,35,35);
g.drawImage(buffer,0,0,null);
}
public void updateGame()
{
box.updateHitbox(x,y);
if(down)
{
if(!box.center.intersects(rect))
{
y++;
//y=y+40;
}
}
else if(up)
{
if(!box.center.intersects(rect))
{
y--;
}
}
}
public void keyPressed(KeyEvent e)
{
int code = e.getKeyCode();
if(code==KeyEvent.VK_A)
{
left=true;
right=false;
aLeft=true;
aRight=false;
aDown=false;
aUp=false;
}
if(code==KeyEvent.VK_D)
{
left=false;
right=true;
aLeft=false;
aRight=true;
aDown=false;
aUp=false;
}
if(code==KeyEvent.VK_S)
{
System.out.println(y);
down=true;
up=false;
aLeft=false;
aRight=false;
aDown=true;
aUp=false;
}
if(code==KeyEvent.VK_W)
{
down=false;
up=true;
aLeft=false;
aRight=false;
aDown=false;
aUp=true;
}
repaint();
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
int code = e.getKeyCode();
if(code==e.VK_A)
{
left=false;
aLeft=false;
}
if(code==e.VK_D)
{
right=false;
aRight=false;
}
if(code==e.VK_S)
{
down=false;
aDown=false;
}
if(code==e.VK_W)
{
up=false;
aUp=false;
}
}
public void addNotify()
{
// call super so the method still does what it was built to do
super.addNotify();
// requests focus so that key inputs are sent to this screen
requestFocus();
}
}
And the Hb class:
import java.awt.Rectangle;
public class Hb
{
public Rectangle center,left,right,up,down;
public Hb(int x, int y)
{
center = new Rectangle(x,y,50,50);
left = new Rectangle(x-1,y+1,1,48);
right = new Rectangle(x+50,y+1,1,48);
up = new Rectangle(x+1,y-1,48,1);
down = new Rectangle(x+1,y+50,48,1);
}
public void updateHitbox(int x, int y)
{
center = new Rectangle(x,y,50,50);
left = new Rectangle(x-1,y+1,1,48);
right = new Rectangle(x+50,y+1,1,48);
up = new Rectangle(x+1,y-1,48,1);
down = new Rectangle(x+1,y+50,48,1);
}
}
Your problem is that you're doing all your drawing in the BufferedImage, and that doesn't allow erasure of "dirty" pixels. Instead, only draw in the BufferedImage that which should be a static and unchanging part of the image, usually the background. The foreground image that moves should be painted directly in paintComponent using the Graphcis object given to the method by the JVM.
public P() {
super();
setSize(600, 350); // not recommended
buffer = new BufferedImage(600, 350, BufferedImage.TYPE_4BYTE_ABGR);
Graphics bg = buffer.getGraphics();
bg.setColor(Color.BLACK);
bg.drawRect(0, 300, 300, 50);
bg.dispose();
// ....
}
and
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(buffer, 0, 0, null);
g.setColor(Color.RED);
g.fillRect(x, y, 35, 35);
}
I'm currently coding a game and I'm trying to have it where if you click on the first button on the front page, it shows a transition screen for 5 seconds, and then shows the game. Here is my code:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ForgottenMain extends JPanel implements KeyListener,MouseListener{
/**
*
*/
private static final int TIMER_DELAY = 35;
private static final long serialVersionUID = -4926251405849574401L;
public static BufferedImage attic,flashlight,player,killer,frontpage,transition;
public static boolean onFrontPage,up,down,left,right,inAttic,onTransition;
public static int px,py,kx,ky;
public static Thread th1,th2;
public static JFrame frame = new JFrame("Forgotten");
public static void main(String[] args){
onFrontPage = true;
px = 600;
py = 400;
ForgottenMain fm = new ForgottenMain();
frame.add(fm);
frame.setSize(1200,800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.add(new ForgottenMain());
fm.repaint();
}
public ForgottenMain(){
init();
}
public void init(){
setSize(1200,800);
setVisible(true);
frame.addKeyListener(this);
frame.addMouseListener(this);
try{
player = ImageIO.read(new File("char.png"));
flashlight = ImageIO.read(new File("flashlightimage.png"));
attic = ImageIO.read(new File("attic.png"));
killer = ImageIO.read(new File("killer.png"));
frontpage = ImageIO.read(new File("frontpageoutline.png"));
transition = ImageIO.read(new File("transitionoutline.png"));
} catch (Exception e){
e.printStackTrace();
}
// Gameloop
new javax.swing.Timer(TIMER_DELAY, new ActionListener() {
public void actionPerformed(ActionEvent e) {
gameLoop();
}
}).start();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int fx = px - 1033;
int fy = py - 635;
kx = 500;
ky = 500;
// Removes the flickering of the images
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Resets the screen to make sure that it only shows the character once
g2.clearRect(0, 0, 1200, 800);
// Draws the background attic
if(inAttic == true){
System.out.println("Drawing attic");
g2.drawImage(attic,0,0,this);
}
if(onFrontPage == true){
g2.drawImage(frontpage, 0, 0, this);
}
// Draws the player
if(onFrontPage == false && onTransition == false){
g2.drawImage(player, px, py, this);
// Draws the Serial Killer
g2.drawImage(killer, kx, ky, this);
// Draws the flashlight
g2.drawImage(flashlight, fx, fy, this);
}
if(onTransition == true){
g2.drawImage(transition, 0, 0, this);
System.out.println("Drawing Transition");
try {
System.out.println("Sleeping for 5 Seconds");
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Done sleeping.");
onTransition = false;
inAttic = true;
}
System.out.println(px + " " + py);
}
public void gameLoop(){
}
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("MouseLocation: " + arg0.getX() + ", " + arg0.getY());
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent e) {
if(e.getX() > 499 && e.getY() > 343 && e.getX() < 748 && e.getY() < 391){
onFrontPage = false;
onTransition = true;
repaint();
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
My problem is, in the paint method, in the if statement testing if onTransition is equal to true, it's supposed to draw the image transition, wait 5 seconds, and then draw the game.
However, right now it's waiting 5 seconds, then quickly drawing the transition screen and then the game. For some reason they are out of order.
How can I fix this? I have tried alternate methods of waiting 5 seconds, for example using currentTimeMillis();, but have the same outcome.
You have some serious problems:
you add panels twice
you have some circuitous use of frame etc
Beyond that the following will work: you have to realize that you don't have control of the painting process. Therefore you should launch a new thread to count the sleep and let the paint do its work uninhibited.
(Also I have removed static - if you really want them you can try to put them back in - if it doesnt work you just throw them out)
class F extends JPanel implements MouseListener{
/**
*
*/
private static final int TIMER_DELAY = 35;
private static final long serialVersionUID = -4926251405849574401L;
public BufferedImage attic,flashlight,player,killer,frontpage,transition;
public boolean onFrontPage,up,down,left,right,inAttic,onTransition;
public int px,py,kx,ky;
public static Thread th1,th2;
public JFrame frame = new JFrame("Forgotten");
public F(){
init();
}
public void init(){
setSize(1200,800);
setVisible(true);
onFrontPage = true;
px = 600;
py = 400;
frame.add(this);
frame.setSize(1200,800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.addMouseListener(this);
try{
// player = ImageIO.read(new File("char.png"));
// flashlight = ImageIO.read(new File("flashlightimage.png"));
// attic = ImageIO.read(new File("attic.png"));
// killer = ImageIO.read(new File("killer.png"));
attic = ImageIO.read(new File(...));
frontpage = ImageIO.read(new File(...));
transition = ImageIO.read(new File(...));
} catch (Exception e){
e.printStackTrace();
}
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int fx = px - 1033;
int fy = py - 635;
kx = 500;
ky = 500;
// Removes the flickering of the images
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Resets the screen to make sure that it only shows the character once
g2.clearRect(0, 0, 1200, 800);
// Draws the background attic
if(inAttic == true){
System.out.println("Drawing attic"+System.currentTimeMillis());
g2.drawImage(attic,0,0,this);
}
if(onFrontPage == true){
g2.drawImage(frontpage, 0, 0, this);
}
// Draws the player
if(onFrontPage == false && onTransition == false){
g2.drawImage(player, px, py, this);
// Draws the Serial Killer
g2.drawImage(killer, kx, ky, this);
// Draws the flashlight
g2.drawImage(flashlight, fx, fy, this);
}
if(onTransition == true){
Graphics gt=transition.getGraphics();
gt.setColor(Color.red);
gt.drawString("xxx"+System.currentTimeMillis(), 10, 100);
g2.drawImage(transition, 0, 0, this);
onTransition = false;
inAttic = true;
}
System.out.println(px + " " + py);
}
public void gameLoop(){
}
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("MouseLocation: " + arg0.getX() + ", " + arg0.getY());
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent e) {
onFrontPage = false;
onTransition = true;
Thread th=new Thread() {
public void run() {
repaint();
System.out.println("Drawing Transition"+System.currentTimeMillis());
try {
System.out.println("Sleeping for 5 Seconds"+System.currentTimeMillis());
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Done sleeping."+System.currentTimeMillis());
repaint();
}
};
th.start();
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
}
How do I get my image to follow my mouse anywhere on the screen?
The below code makes the image move along the x axis.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class PlayerTwo implements KeyListener, MouseListener, MouseMotionListener{
public static int PLAYER_HEIGHT = 15;
public static int PLAYER_WIDTH = 15;
private Image p2Image = null;
private static int x = 0;
private static int y = 0;
private int heightPosition = 0;
Main main = null;
public PlayerTwo(Image pi, Main m ){
main = m;
p2Image = pi;
y = (int)((Main.WIDTH*2)+(PLAYER_WIDTH*2));
heightPosition = Main.HEIGHT-PLAYER_HEIGHT-20;
}
public void drawPlayer(Graphics g){
g.drawImage(p2Image, y, heightPosition, main);
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent me) {
int newX = me.getX();
int newY = me.getY();
if(newY > (Main.HEIGHT+PLAYER_HEIGHT+10)){
y = Main.HEIGHT+PLAYER_HEIGHT+10;
}else{
y = newY;
}
// if (newX > (Main.WIDTH-PLAYER_WIDTH-10)){
// x = Main.WIDTH-PLAYER_WIDTH-10;
// }else{
// x = newX;
// }
}
}
Updated with Main...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
public class Main extends JFrame implements Runnable {
public static int WIDTH = 600;
public static int HEIGHT = 600;
private int gameSpeed = 100;
PlayerOne playOne = null;
PlayerTwo playTwo = null;
Image p1Image = null;
Image p2Image = null;
Image backImage = null;
Graphics offscreen_high;
BufferedImage offscreen;
public Main(String frameTitle) {
super(frameTitle);
p1Image = new javax.swing.ImageIcon("src/resources/player1.gif").getImage();
p2Image = new javax.swing.ImageIcon("src/resources/player2.gif").getImage();
backImage = new javax.swing.ImageIcon("src/resources/back.png").getImage();
offscreen = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
offscreen_high = offscreen.createGraphics();
playOne = new PlayerOne(p1Image, this);
playTwo = new PlayerTwo(p2Image, this);
addKeyListener(playOne);
addKeyListener(playTwo);
addMouseListener(playTwo);
addMouseMotionListener(playTwo);
setSize(WIDTH, HEIGHT);
setVisible(true);
startGame();
}
public void startGame() {
Thread thread = new Thread(this);
thread.start();
}
public void paint(Graphics g) {
offscreen_high.setColor(Color.black);
offscreen_high.fillRect(0, 0, WIDTH, HEIGHT);
offscreen_high.drawImage(backImage, 0, 0, this);
playOne.drawPlayer(offscreen_high);
playTwo.drawPlayer(offscreen_high);
g.drawImage(offscreen, 0, 0, this);
}
// public void update(Graphics g){
// paint(g);
// }
public void run() {
int count = 0;
while (true) {
try {
Thread.sleep(gameSpeed);
} catch (InterruptedException ie) {
}
repaint();
count++;
}
}
public static void main(String[] args) {
Main main = new Main("Game On!");
}
}
Generally, you need some way to tell the UI that it should be updated.
Assuming that Main is some kind of component (and it's also responsible for painting the Player), you should be calling its repaint method in the mouseListener
But without more details, this is more of a guess
Updated
After a muck around with the code, the main problem, as I see it, is your trying to draw the image only the horizontal axis (x) using the vertical position (y)...
public void drawPlayer(Graphics g){
//g.drawImage(p2Image, y, heightPosition, main);
g.drawImage(p2Image, x, heightPosition, main);
}
To get it to work, you're going to have to uncomment the code in you mouseMoved method so that the x position updates.
You should also avoid painting to top level containers, the main reason (apart from the fact that you can screw up the paint process) is that top level containers are not double buffered.
Instead, you should move your entire game container over to something like a JPanel and override it's paintComponent method (and don't for get to call super.paintComponent)
How do I use KeyListener on this code to move up and down? Ii know how to use KeyListener but I don't know where it put it on this code.
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class ControlPanel extends JPanel implements Runnable,ActionListener,KeyListener,MouseListener{
private MainPanel main;
private final static int maxWidth = 800, maxHeight = 600; //width & height of JPanel
private boolean running; //keeps track of state of the program
private Thread thread;
private Graphics2D graphics;
private Image image; //used for double buffering
private BufferedImage bgImage;
private String s = "";
Font f = new Font("Times New Roman",Font.PLAIN,50);
Timer t = new Timer(2000,this);
private int typed = 0;
private int x = 50,y = 500;
public ControlPanel(MainPanel main) {
this.setDoubleBuffered(false); //we'll use our own double buffering method
this.setBackground(Color.black);
this.setPreferredSize(new Dimension(maxWidth, maxHeight));
this.setFocusable(true);
this.requestFocus();
this.main = main;
addKeyListener(this);
addMouseListener(this);
t.start();
}
public static void main(String[] args) {
new MainPanel();
}
public void addNotify() {
super.addNotify();
startGame();
}
public void stopGame() {
running = false;
}
//Creates a thread and starts it
public void startGame() {
if (thread == null || !running) {
thread = new Thread(this);
}
thread.start(); //calls run()
}
public void run() {
running = true;
init();
while (running) {
createImage(); //creates image for double buffering
///////////////USE THESE 2 METHODS////////////////////
update(); //use this to change coordinates, update values, etc
draw(); //use this to draw to the screen
//////////////////////////////////////////////////////
drawImage(); //draws on the JPanel
}
System.exit(0);
}
//Use this to create or initialize any variables or objects you have
public void init() {
}
public void initGame(){
}
//Use this to update anything you need to update
public void update() {
}
//Use this to draw anything you need to draw
public void draw() {
graphics.setColor(Color.WHITE);
graphics.fillRect(250, 450, 300,100);
graphics.setColor(Color.WHITE);
graphics.fillRect(250, 320, 300,100);
graphics.setColor(Color.GREEN);
graphics.setFont(f);
graphics.drawString(s, x, y);
typed = 0;
graphics.setFont(f);
graphics.setColor(Color.blue);
graphics.drawString("HANGMAN", 270,75);
graphics.setFont(f);
graphics.setColor(Color.blue);
graphics.drawString("PLAY", 330, 390);
graphics.setFont(f);
graphics.setColor(Color.blue);
graphics.drawString("QUIT", 330, 520);
graphics.setColor(Color.red);
graphics.drawRect(248, 318, 304,104);
}
//creates an image for double buffering
public void createImage() {
if (image == null) {
image = createImage(maxWidth, maxHeight);
if (image == null) {
System.out.println("Cannot create buffer");
return;
}
else
graphics = (Graphics2D)image.getGraphics(); //get graphics object from Image
}
if (bgImage == null) {
graphics.setColor(Color.black);
graphics.fillRect(0, 0, maxWidth, maxHeight);
//System.out.println("No background image");
}
else {
//draws a background image on the Image
graphics.drawImage(bgImage, 0, 0, null);
}
}
//outputs everything to the JPanel
public void drawImage() {
Graphics g;
try {
g = this.getGraphics(); //a new image is created for each frame, this gets the graphics for that image so we can draw on it
if (g != null && image != null) {
g.drawImage(image, 0, 0, null);
g.dispose(); //not associated with swing, so we have to free memory ourselves (not done by the JVM)
}
image = null;
}catch(Exception e) {System.out.println("Graphics objects error");}
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
typed = 1;
s+=Character.toString(e.getKeyChar());
s+=" ";
System.out.println(s);
}
#Override
public void mouseClicked(MouseEvent e) {
System.out.println(e.getPoint());
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
KeyListener isn‘t designated for listening of keyboard events for Swing JComponents, use KeyBindings instead, output to the Swing GUI should be from Swing Action
You have added key listener by calling this
addKeyListener(this);