I'm trying to make a simple game in java where you can move the player (Defender) in the 4 directions. I tried to make the key detecting with a key adapter, but it doesn't work. What could be the problem (I tried to do a System.out.println at the key press to make sure that the problem isn't at the Defender)?
Code:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class DefenderComponent extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 160;
private static final int HEIGHT = 120;
private static final int SCALE = 4;
Defender player = new Defender();
public DefenderComponent() {
Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);
setMinimumSize(size);
setMaximumSize(size);
setPreferredSize(size);
addKeyListener(new TKeyListener());
Timer timer = new Timer(5, this);
timer.start();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Test2");
frame.add(new DefenderComponent());
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setFocusable(true);
new DefenderComponent();
}
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
Image i = player.getImage();
g2d.drawImage(i, player.getX(), player.getY(), i.getWidth(this) * SCALE, i.getHeight(this) * SCALE, this);
}
public void actionPerformed(ActionEvent e) {
player.move();
repaint();
}
}
KeyEvents are only generated for the component that has focus. A JPanel is not focusable by default.
Don't use a KeyListener. Instead you should be using Key Bindings which are more flexible.
See Motion Using the Keyboard for more information and examples.
frame.addActionListener(this);
is what you missed.
that line says. this class is an ActionListener. please call this class when you receive an action.
if you want to add the ActionListener to the JPanel
public DefenderComponent() {
addActionListener(this);
....
}
Related
I've been trying to create two layered images within a JFrame using JLayeredPane however I'm not able to draw a shape using the paint() function within the Canvas class.
Here is what I wrote:
package com.baduk.main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
public class Game extends Canvas implements Runnable {
private ImageIcon icon;
private JLabel back;
private JLayeredPane layer;
/**
*
*/
private static final long serialVersionUID = -3441156857004256039L;
public Game() {
//Background image with depth 0
icon = new ImageIcon("C:/Users/scaraven/Downloads/baduk_board.png");
back = new JLabel(icon);
back.setBounds(0,0,icon.getIconWidth(),icon.getIconHeight());
//Create JFrame
JFrame frame = new JFrame("BADUK");
frame.setSize(new Dimension(icon.getIconWidth()+5,icon.getIconHeight()+25));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
//Create JLayeredPane
layer = new JLayeredPane();
layer.add(back,new Integer(1));
layer.add(this,new Integer(0));
frame.setContentPane(layer);
frame.setVisible(true);
}
public static void main(String[] args) {
new Game();
}
#Override
public void run() {
// TODO Auto-generated method stub
}
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillRect(10, 10, 100, 100);
}
}
According to what I wrote, A Jframe should be generated with an image as the background and a black rectangle on top, however I only get the image. Does anyone know what is wrong with the code I wrote and what I need to change?
Image is not being confined to a direct area in this java code below. I want the java image to be displayed in its entirety in a 400 width by 400 height image. I tried to do that by frame.setSize(400, 400); and it is not working. My code includes drawImage which is what I was told I had to put in the code for this to work. I don't what to do next.
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class SwingSandbox {
public static void main(String[] args) throws IOException {
JFrame frame = buildFrame();
final BufferedImage image = ImageIO.read(new File("/Users/johnzalubski/Desktop/c.jpg"));
JPanel pane = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
};
frame.add(pane);
}
private static JFrame buildFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
return frame;
}
}
I reworked your Swing sandbox code a bit. Here's what I came up with.
The image is distorted because I made it fit a 400 x 400 drawing panel. You should reduce the image and maintain the aspect ratio.
Here are the changes I made.
I added the call to the SwingUtilities invokeLater method to put the Swing components on the Event Dispatch Thread.
I made the drawing panel a class, so I could set the preferred size. You set the size of the drawing panel, not the JFrame. Who cares how large or small the JFrame is?
I put the JFrame method calls in the correct order.
And here's the code.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class SwingSandbox implements Runnable {
public static void main(String[] args) throws IOException {
SwingUtilities.invokeLater(new SwingSandbox());
}
private BufferedImage image;
public SwingSandbox() {
try {
image = ImageIO.read(new File("C:\\Users\\Owner\\OneDrive\\Pictures\\Saved Pictures\\StockMarketGame.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
JFrame frame = new JFrame("Image Display");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
DrawingPanel panel = new DrawingPanel(image);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private BufferedImage image;
public DrawingPanel(BufferedImage image) {
this.image = image;
this.setPreferredSize(new Dimension(400, 400));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, 400, 400, null);
}
}
}
You are changing how big is frame. You should use something like this: g.drawImage(image, 0, 0, 400, 400, null);
If this help you please vote me up. I’am here new and want to have some basic reputation. Thanks! 😀
I am a java beginner and I'm having trouble with a simple swing animation I created. The animation lags when running unless something else is happening like mouse movement or a key being pressed down. I have searched for answers but none of them solve this problem.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Animation extends JPanel implements ActionListener {
Timer timer = new Timer(5, this);
int y = 0, velY = 2;
public void actionPerformed(ActionEvent e) {
y += velY;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(50, y, 50, 50);
timer.start();
}
public static void main(String[] args) {
Animation drawPanel = new Animation();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
frame.add(drawPanel);
}
}
First and foremost, get that timer.start() out of your paintComponent method since it does not belong there, and serves no purpose other than to slow the rendering down. Instead you should call that method once, and once only.
Next, 5 mSecs may be an unrealistic timer delay. Experiment with this number, but expect to get a decent functioning somewhere near 10 to 15 mSecs.
Next, base your position change on actual time slice differences that have been measured, not on what you're hoping the timer is doing.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Animation extends JPanel {
private static final int TIMER_DELAY = 16;
private static final double Y_VELOCITY = 0.05;
private double dY = 0.0;
private Timer timer = new Timer(TIMER_DELAY, new TimerListener());
public Animation() {
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(50, (int) dY, 50, 50);
// timer.start();
}
private class TimerListener implements ActionListener {
private long prevTime;
#Override
public void actionPerformed(ActionEvent e) {
if (prevTime == 0L) {
repaint();
prevTime = System.currentTimeMillis();
} else {
long currentTime = System.currentTimeMillis();
long deltaTime = currentTime - prevTime;
double deltaY = Y_VELOCITY * deltaTime;
dY += deltaY;
prevTime = currentTime;
repaint();
}
}
}
public static void main(String[] args) {
Animation drawPanel = new Animation();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
frame.add(drawPanel);
}
}
I'm trying to develop a simple game. The games is about the shapes. Shapes will move and we'll catch by mouse. I have already created a oval and given size of oval graphic. But I cannot move this shape repeatedly. I think I need to use timer class. I have been trying 2 hours myself but I didnt do yet.
The code;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class myshapestry extends JFrame implements ActionListener {
JFrame frame=new JFrame("Deneme");
Container l ;
private static int ballX=150;
private static int ballY=150;
myshapestry() {
l=this.getContentPane();
l.setLayout(null);
MyPanel panel=new MyPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.add(panel);
frame.setVisible(true);
frame.setSize(getPreferredSize());``
}
public Dimension getPreferredSize() {
return new Dimension(500,600);
}
public static void main (String args[]){
myshapestry tr=new myshapestry();
tr.setTitle("Game of Shapes");
}
private static class MyPanel extends JPanel {
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.fillOval(ballX, ballY,50 , 70);
}
public void actionPerformed(ActionEvent e){
ballX = ballX + 5;
ballY = ballY + 10;
repaint();
}
}
}
I was trying these code in the myshapestry code block;
Timer timer=new Timer(100,myshapestry);
t.start();
Add something like this
javax.swing.Timer timer=new javax.swing.Timer(100, panel) ;
timer.start();
Each 100msec the timer invokes actionPerformed() method of your MyPanel class
I am new to the swing and graphics and am trying to get this to work for drawing a string on a label by making an object class called DrawString. A panel currently pops up with nothing on it. I would like to thank you for any guidance you can give.
package view;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Run {
public static void main(String[] args) {
JPanel panel = new JPanel();
DrawString text = new DrawString();
JFrame window = new JFrame();
window.setVisible(true);
window.setSize(400, 400);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
text.display("Boo");
panel.setLocation(((window.getWidth()/2)-(panel.getWidth()/2)),
((window.getHeight()/2)-(panel.getHeight()/2)));
panel.setSize(200, 200);
window.add(panel);
panel.add(text);
}
}
package view;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JLabel;
#SuppressWarnings("serial")
public class DrawString extends JLabel{
String string;
Font font = new Font("TimesRoman",Font.PLAIN, 30);
public DrawString() {
super();
}
public void display(String string){
this.string=string;
repaint();
}
public void drawString(Graphics comp){
super.paintComponent(comp);
Graphics2D g = (Graphics2D) comp;
g.setFont(font);
g.drawString(string, JLabel.CENTER, JLabel.CENTER);
}
}
I am learning and experimenting…
It's not clear if you want to experiment with JLabel or custom painting. You might want to start with a working JLabel#setText() example or TextLayout#draw() example.