I am trying to make a simple game in Java in which many things are moving. I watched a video on moving graphics that said that I need a Timer() to move something on the screen. When I try to make a timer in the form of Timer t = new Timer(5, this); it won't work. It tells me that there should not be any parameters for the method Timer(). Can I please have some help? By the way, I have only been coding java for 2 weeks, so I am very much a beginner. Here is my code:
package FlappyDodgeGame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
public class Game extends JFrame implements ActionListener{
static int width = 1000, height = width * 9 / 12;
public static int birdX = width * 1 / 5, birdY = height / 2, birdSize = 75;
public static double birdVel = 0, birdVelDelta = 0.1;
//error: The constructor Timer(int, Game) is undefined. quick fix: Remove arguments to match 'Timer()'.
Timer timer = new Timer(5, this);
public static void main(String args[]){
final JFrame jframe = new JFrame("Test");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setSize(width, height);
jframe.setResizable(false);
jframe.setVisible(true);
jframe.setLocationRelativeTo(null);
final GUI gui = new GUI();
jframe.add(gui);
jframe.addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
});
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
You're using the wrong Timer class:
import java.util.Timer;
There's another Timer class, javax.swing.Timer, that has a two-arg constructor. The javadoc for this class is here.
For a Swing application, the big advantage of using a javax.swing.Timer instead of a java.util.Timer is that when the Swing timer calls your listener, it does so on the Swing event thread, which means you can immediately call methods on all your UI objects.
if you want to move something on screen, you need to use a class that extends JPanel, and then implement paintComponent(Graphics g)
class Game extends JPanel{
private int x_axis = 0;
private int y_axis = 0;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// do your painting here
//e.g.
g.drawOval(x_axis, y_axis, 200, 150);
x_axis++;
y_axis++;
//
repaint();
}
}
after that you can add it to your JFrame
frame.add(new Game());
Related
I am a beginner. I am trying to add filled rectangle or any other graphic on JFrame using multiple inner classes. I am getting debugging errors. What are the problems here?. If this is a wrong way. Please tell me how to do the same using JFrame and JPanel only.
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
public class RainBow{
JFrame frame;
public static void main(String[] args){
RainBow bow = new RainBow();
bow.go();
}
public class Paint extends JPanel{
public void paintComponent(Graphics g){
g.setColor(Color.red);
g.fillRect(100, 100, 100, 100);
}
}
public void go(){
frame.addMouseListener(new ListenMouse());
frame.setSize(400, 400);
frame.setVisible(true);
}
public class ListenMouse implements MouseListener{
public void mosueClicked(MouseEvent a){
Paint p = new Paint();
frame.getContentPane().add(p);
frame.setVisible(true);
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#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
}
}
}
The code posted has multiple problems. See this working example with explanations in comments.
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class RainBow {
JFrame frame;
boolean paintRectangle = false;
public static void main(String[] args) {
RainBow bow = new RainBow();
bow.go();
}
public class Paint extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g); // should always be done
if (paintRectangle) {
g.setColor(Color.red);
g.fillRect(100, 100, 100, 100);
}
}
}
public void go() {
frame = new JFrame(); // otherwise NPE
Paint paint = new Paint();
paint.addMouseListener(new ListenMouse()); // add listner to paint
frame.add(paint); // add paint at start-up
frame.setSize(400, 400);
frame.setVisible(true);
// ensures JVM shuts down when frame is closed.
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public class ListenMouse extends MouseAdapter {
// this method is incorrectly spelled!
public void mosueClicked(MouseEvent a) {
}
#Override
public void mouseClicked(MouseEvent arg0) {
/* requires special handling to add components on the fly */
//Paint p = new Paint();
paintRectangle = true;
frame.repaint(); // forces the Paint to be painted as well.
}
}
}
I am creating a program in Java where you move a square. However, the square does not move. I have tried a lot of things, but none of them work. It seems to be a problem with repaint. How could I solve this?
package movingSquare;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class MovingSquare extends JComponent {
private static final long serialVersionUID = -3778627464016140311L;
public static JFrame f = new JFrame("Moving Square");
public static int x;
public static int y;
public static Rectangle r = new Rectangle(x, y, 20, 20);
public static MovingSquare mv = new MovingSquare();
public static KeyListener kl = new KeyListener() {
#Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getKeyCode() == KeyEvent.VK_UP) {
y += 1;
r.setLocation(x, y);
mv.repaint(r);
}
if(arg0.getKeyCode() == KeyEvent.VK_DOWN) {
y -= 1;
r.setLocation(x, y);
mv.repaint();
}
if(arg0.getKeyCode() == KeyEvent.VK_LEFT) {
x -= 1;
r.setLocation(x, y);
mv.repaint();
}
if(arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
x += 1;
r.setLocation(x, y);
mv.repaint();
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}};
public static void main(String[] args) {
// TODO Auto-generated method stub
f.setBackground(Color.BLUE);
f.setMinimumSize(new Dimension(720, 720));
f.setResizable(false);
f.setFocusable(true);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.addKeyListener(kl);
f.add(new MovingSquare());
f.pack();
f.setVisible(true);
boolean e = true;
while(e) {
System.out.println("x: " + x + " y: " + y);
}
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g1 = (Graphics2D) g;
g1.setColor(Color.BLUE);
g1.fillRect(0, 0, 720, 720);
g1.setColor(Color.RED);
g1.fill(r);
}
}
First of all custom painting is done by overriding paintComponent() not paint().
Get rid of all the static variables. The reason you create custom class is so you can define variables that contains the properties of the class.
There is no need for the frame variable as part of the class. The component only needs to know about itself, not the frame it belongs to.
f.add(new MovingSquare());
First you create a MovingSquare component and add it to the frame.
public static MovingSquare mv = new MovingSquare();
But then you create another MovingSquare component, but never add it do the frame so you will never be able to paint it.
Get rid of the above statement it is not needed since your class is already a MovingSquare.
mv.repaint();
As I said above that statement does nothing since that component is never added to the frame.
Instead the code should be:
repaint();
That is all you need to cause a component to repaint itself.
If you do use a KeyListener, then the KeyListener should be added to the component itself, not the frame. The component should be responsible for managing its own state.
So basically your design is wrong and needs to be fixed.
However, even that may not solve the problem as only the component with focus will receive events and as suggested in the comment you should be using Key Bindings.
So check out Motion Using the Keyboard for working examples to demonstrated the difference between KeyEvents and Key Bindings.
Recently I started making a Map Editor for my game and I came across a couple of issues that I've kind of have fixed. My current problem right now is that I have a JFrame (main interface). Within that JFrame I have a JScrollPane which holds my Client(a JPanel). Since I can't post picture I will post a link of the image.
Image of GUI: http://i.imgur.com/yPNAlYS.png
This is where I add my client(JPanel) to the JScrollPane.
//======== mainScrollPane ========
{
client.setPreferredSize(client.getSize());
mainScrollPane.setPreferredSize(client.getSize());
mainScrollPane.setViewportView(client);
mainScrollPane.add(client);
This is my Client.java|The MapEditor class is a little large to post here but feel free to ask for snippets or anymore information.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
public class Client extends JPanel implements Runnable, MouseListener, MouseMotionListener {
private static final long serialVersionUID = 1L;
private Thread animationThread;
protected Map map;
private Tile tile;
public int mX, mY;
public Client() {
init();
setVisible(true);
setFocusable(true);
animationThread = new Thread(this);
animationThread.start();
}
public void init() {
addMouseListener(this);
addMouseMotionListener(this);
ImageHandler.loadImages();
map = new Map();
setSize(1000, 500);
}
public void run() {
while (animationThread != null) {
repaint();
try {
Thread.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void paint(Graphics g) {
Graphics2D gg = (Graphics2D) g;
map.drawCurrentMap(gg);
}
#Override
public void mouseClicked(final MouseEvent e) {
//final Point p = e.getPoint();
//final int x = p.x / 25;
//final int y = p.y / 25;
//map.getTileAt(x, y).setGraphicId(MapEditor.id);
//map.getTileAt(x, y).setBlocked(true);
map.getTiles().set(map.getTileIndex(mX, mY), new Tile(mX, mY, true, MapEditor.id));
System.out.println(map.getTiles().get(map.getTileIndex(mX, mY)).toString());
}
#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 e) {;
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
mX = e.getX()/25;
mY = e.getY()/25;
}
}
This has nothing to do with scroll pane, but with how you've done your custom painting...
Basically, this...
public void paint(Graphics g) {
Graphics2D gg = (Graphics2D) g;
map.drawCurrentMap(gg);
}
Is breaking the paint chain requirements. A Graphics context is a shared resource, meaning that everything painting within a given paint cycle shares the same Graphics contents.
Painting is also a complex chain of methods which is, as you've discovered, really easy to break.
Instead, you should override paintComponent and perform your custom painting there, making sure you call super.paintComponent first
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details
I am currently writing a small program where I'm supposed to use basic transformations. Right now, I'm working on being able to move the polygon by using the arrow keys. Right now I can move it to the right by pressing the mouse, but I'd rather be able to use the right arrow key. However, I haven't been able to no matter which method I tried.
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
class PolygonPanel extends JPanel implements MouseListener{
Polygon p;
public PolygonPanel(){
p = new Polygon();
p.addPoint(10, 10);
p.addPoint(100,50);
p.addPoint(50,100);
addMouseListener(this);
addKeyListener(new MKeyListener());
}
class MKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e){
int keyCode = e.getKeyCode();
if(keyCode==e.VK_RIGHT){
System.out.println("FFFFUUUUU");
}
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
setBackground(Color.white);
g.fillPolygon(p);
}
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("hei");
for (int i = 0; i < p.npoints; i++) {
p.xpoints[i] = p.xpoints[i]+10;
repaint();
}
}
#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
}
}
class PolygonFrame extends JFrame{
public PolygonFrame(){
setTitle("Polygoner");
setSize(700, 600);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container contentPane = getContentPane();
contentPane.add(new PolygonPanel());
}
}
public class Polygonfun {
public static void main(String[] args) {
JFrame frame = new PolygonFrame();
frame.setVisible(true);
}
}
Nothing happens when I press the right arrow key. I also tried implementing it like this:
class PolygonPanel extends JPanel implements MouseListener,KeyAdapter
And then adding the unimplemented methods, but that didn't work either. I know i've probably overlooked something, but I cant seem to figure it out. Any advice?
Thanks
set this.setFocusable(true); for your panel.
Should be:
public PolygonPanel(){
p = new Polygon();
p.addPoint(10, 10);
p.addPoint(100,50);
p.addPoint(50,100);
addMouseListener(this);
this.setFocusable(true);
this.addKeyListener(new MKeyListener());
}
Here is the code.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
public class Paint extends JPanel implements MouseMotionListener, MouseListener {
public Paint() {
setBackground(Color.RED);
addMouseMotionListener(this);
addMouseListener(this);
}
private boolean clicked = false;
public void paintComponent (Graphics g) {
super.paintComponent(g);
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
int x = (int) b.getX() - 3;
int y = (int) b.getY() - 23;
if (clicked) {
g.drawLine(x, y-5000, x,y+5000);
g.drawLine(x+5000,y,x-5000,y);
g.setColor(Color.white);
}
g.drawLine(x, y-5000, x,y+5000);
g.drawLine(x+5000,y,x-5000,y);
g.setColor(Color.black);
// . . .
}
#Override
public void mouseDragged(MouseEvent e) {
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
clicked = true;
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
clicked = false;
repaint();
}
}
public class Frame extends JFrame {
public Frame() {
this.setSize(500,500);
this.setTitle("Test painting");
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
Paint panel = new Paint();
this.add(panel);
this.setVisible(true);
}
public static void main (String[] args) {
new Frame();
}
}
When I run the program, it looks like it works fine when the application is in the default position, but once I move the applet to where I like on the screen, the lines don't maintain the current mouse position on screen.
Can someone show me where I've gone wrong or how to fix this?
Painting is done from the context of the component. The Graphics context for any given component is translated so that the top, left corner is 0x0.
MouseInfo.getPointerInfo().getLocation() is returning the location of the mouse on the screen, not the position relative to the component.
While there is a way to fix it, a better solution would be to simply use a MouseMotionListener instead. The MouseEvent sent to this method has already been translated to the component coordinate space...
public void mouseMoved(MouseEvent me) {
myPoint = me.getPoint();
}
Then in you paintComponent method, simple refer to myPoint instead of trying to use MouseInfo
I think that you will be better off to change your class's state in the MouseAdapter, call repaint() and then have your paintComponent(...) method use this state to help it draw. This seems cleaner and safer to me than using MouseInfo in paintComponent(...).
Other than that, if you need more specific help, consider
telling us more about what it is exactly you're trying to do and how your program isn't working.
creating and posting an sscce, a small compilable and runnable program that demonstrates your problem for us.