I am a beginner programmer trying to create a Pacman game using Java eclipse. I am at the beginning of the process and I'm simply trying to get my main "Princess Pacman" character on the JFrame screen, but, I have this Override error popping up. I have also tried it with out override but it doesn't seem to be working for me that way either.
Here is my code:
import java.awt.*;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import java.awt.event.KeyEvent;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Pacman extends JFrame {
public static final int WIDTH = 500;
public static final int HEIGHT = 500;
public static void main(String args[]){
Pacman gui = new Pacman();
gui.setVisible(true);
}
BufferedImage princess = null;
public Pacman(){
super("Princess Pacman");
//set size of playing space
setSize(WIDTH,HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try{
princess =ImageIO.read(new File("images/Elsa.jpeg"));
}
catch (IOException e){
System.out.println("image not found");
}
}
#Override
public void draw(Graphics2D g){
g.drawImage(princess.getScaledInstance(100, 100, Image.SCALE_DEFAULT), 0, 0, this);
}
}
draw is not a method defined by JFrame or any of its parent classes, therefore it can't be override
draw is never called by anything that actually paints
You should avoid painting directly to top level containers, there's just to many things been painted onto it.
You can use a JLabel, but there are issues with this. Instead, create a custom class extending from JPanel and override its paintComponent method, making sure you call super.paintComponent before you render the image
Take a closer look at Painting in AWT and Swing, Performing Custom Painting and this for example
You're trying to override a method that does not exist in the JFrame class. Remove the override annotation.
Related
I'm trying to create a simple application that draws graphics...
package Tests.Drawing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.EtchedBorder;
public class DrawingTest extends JFrame
{
private Canvas drwArea;
private JButton btnClear;
public static void main(String[] args)
{
DrawingTest StartForm = new DrawingTest();
StartForm.setVisible(true);
}
public DrawingTest()
{
//Window...
this.setTitle("Drawing objects test00");
this.setBounds(0,0,510,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
//Drawing area...
drwArea = new Canvas();
drwArea.setBounds(0, 0, 400, 450);
drwArea.setBackground(Color.WHITE);
drwArea.setOpaque(true);
drwArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
drwArea.addMouseMotionListener(new MouseMotionAdapter()
{
#Override
public void mouseDragged(MouseEvent e)
{
//Write code to paint on the image...
}
});
this.getContentPane().add(drwArea);
//Clear button...
btnClear = new JButton("Clear");
btnClear.setBounds(410,50,70,30);
btnClear.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//Write code to clear the image...
}
});
this.getContentPane().add(btnClear);
}
private class Canvas extends JLabel
{
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
//The idea of overriding this method is
//achieving persistence...
}
}
}
I have seen that the typical component to draw on is a Jlabel (Is there anyone better by the way?). Using the method “getGraphics” I can use an object that has several methods to paint on the component. My problem is that instead of painting directly on the JLabel, I would like to paint on an image (in memory) and once the painting has finished, send the result to the JLabel. How can I do this? I'm a bit lost...
Thanks in advance.
I would like to paint on an image (in memory)
I suggest that you then create a BufferedImage object of the desired size, get its Graphics2D object by calling createGraphics() on it, and draw on it using this Graphics2D object.
and once the painting has finished, send the result to the JLabel
Then create an ImageIcon out of the BufferedImage above by simply calling
Icon myIcon = new ImageIcon(myBufferedImage);
and then setting the JLabel's icon via myLabel.setIcon(myIcon);
Also you could draw to a BufferedImage that is being displayed within a JPanel's paintComponent method, and this may be an even better way to go if you want to update the image while the program is running. For more on this, please have a look at some of these examples.
Other comments:
Don't draw with a Graphics object obtained by calling getGraphics() on a component. This will return a Graphics object that is short lived, risking disappearing graphics or worse, a NullPointerException. Instead, draw in the JPanel's paintComponent(...) method either directly, or indirectly by drawing on a BufferedImage (yes, you can get its Graphics object via getGraphics()) and then drawing the BufferedImage to the GUI within the paintComponent method.
While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
So I finally got a Canvas to work the way I want it but it flickers constantly, repaint() is run 20 times a second and the flicking does lessen when I make it run 10 times a second.
package pd.data;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import pd.areas.MainMenu;
#SuppressWarnings("serial")
public class Main extends JFrame implements Runnable {
private JPanel contentPane = new JPanel();
private Thread gameThread = new Thread(this);
public boolean running = false;
#SuppressWarnings("unused")
private int current = PDU.PD_MAIN_MENU;
private MainMenu mainmenu;
public Main() {main.setTitle("PD");
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setLocation(SPU.screenWidth / 2 - SPU.windowSize.width / 2,
SPU.screenHeight / 2 - SPU.windowSize.height / 2);
main.setResizable(false);
main.setVisible(true);
contentPane.setLayout(new BorderLayout(0, 0));
contentPane.setPreferredSize(SPU.windowSize);
main.setContentPane(contentPane);
main.pack();
mainmenu = new MainMenu();
contentPane.add(mainmenu, BorderLayout.CENTER);
this.gameThread.start();
}
#Override
public void run() {
running = true;
while (running) {
{
mainmenu.repaint();
}
try {
Thread.sleep(SPU.TSU);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Main();
}
}
And below is my MainMenu class:
package pd.areas;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
#SuppressWarnings("serial")
public class MainMenu extends Canvas{
BufferedImage img = null;
public MainMenu() {
this.setBackground(Color.BLACK);
}
public void paint(Graphics graphics){
try {
img = ImageIO.read(this.getClass().getResource(
"/image.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
graphics.drawImage(img, this.getWidth() / 2 - img.getWidth()/2, 50, null);
}
}
Although the flicker is actually a nice effect, it's going to effect the whole canvas and not just the image I'm guessing, how can I fix the flicker?
Don't use java.awt.Canvas. Use a JPanel instead.
Draw in the JPanel's paintComponent method.
Don't forget to call your super's painting method which for paintComponent would be super.paintComponent(graphics)
Never try to read in an image from within any painting method. That will slow down painting and make your program seem unresponsive. Why keep reading in the same image over and over again anyway? Read it in once and save it to a variable.
Though this thread was opened 5 years ago, it's still going to be an issue for anyone new to Java SE.
I had the same problem with Canvas myself, but wasn't convinced enough to switch to javax components because I recalled a VLC project called JVLC which used Canvas to render videos flawlessly (granted jvlc uses some native code).
Tip 1: perhaps it's better to try JPanel instead.
Tip 2: in gaming systems, it's better to use a game engine (it'll save you lots of time).
Tip 3: in gaming systems, implement a fps mechanism rather than calling repaint() on every change.
Tip 4: if you have to call more than 10 lines of code in your paint() implementation you're going to slow it down. It's better to draw to a BufferedImage for every graphical change you need to make to your app, then have the paint() implementation itself draw just the image itself. This should play nicely with an fps mechanism and will reduce the chances of any flickering.
I am new to graphics.
I got this code from open source.It should paint String "HEeelo" on jframe,but it does not.Can anyone explain why it is not working properly and the principle of paint method?Why should it edit JFrame as it is just method which is not even called from main?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import javax.swing.JFrame;
public class view extends JFrame{
public view(){
this.setSize(new Dimension(250, 250));
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g){
g.drawString("heello", 10, 10);
}
public static void main(String []args){
new view();
}
}
Get rid of that tutorial, that is not the way to do painting.
First the basic problems are that you should always invoke super.paint(...) when overriding a method. Secondly the text won't show because it is being painted under the title bar. You need to increase the y offset:
super.paint(g);
g.drawString("heello", 10, 40);
and the principle of paint method
Read the section from the Swing tutorial on Custom Painting for the proper way to do this. Basically you override the paintComponent() method of a JPanel and then add the panel to the frame. You should not do custom painting on a frame directly.
Here is my code, I am wondering why it prints "test" two times!? every command I add in "paintcomponent" performs 2 times. I would appreciate if you could help me please!?
import java.awt.geom.*;// For Ellipse2D, etc.
import java.util.*;
import javax.swing.*; // For JPanel, etc.
import java.io.*;
import java.awt.*; // For Graphics, etc.
import java.lang.Object;
import java.util.Random;
public class hextopology extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("test");
}
public static void main(String[] args) throws Exception{
JFrame f = new JFrame();
f.add(new hextopology());
f.setSize(550,550);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
When you are doing resizing the window you are actually changing the window's properties, so your view elements should be painted again. That's why paintComponent() is getting called every time and as you have a print statement inside the method, it is printing as expected.
You are calling
f.setSize(550,550);
which is a resize, after the panel is created for the first time.
paintComponent
is called twice, because of this.
I have googled this and searched through this site to try and get an Image to show up using Swing, but every time i implement the code i find online it doesn't work. I have no idea what i am doing wrong, can anyone help me?
package Game;
import java.awt.Dimension;
import java.awt.Graphics;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Amazing {
private int width = 300;
private int height = width / 16 * 9;
private int scale = 3;
private static Graphics g;
private static JFrame frame = new JFrame();
private static JPanel panel = new JPanel();
public Amazing(){
Dimension size = new Dimension(width*scale, height*scale);
frame.setPreferredSize(size);
frame.setResizable(false);
frame.setTitle("Amazing!");
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args){
Amazing amazing = new Amazing();
Character character = new Character();
character.paintComponent(g);
}
}
package Game;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Character extends JPanel{
private BufferedImage image;
public Character(){
try {
image = ImageIO.read(new File("E:\\Libraries\\Documents\\Java Stuff\\workspace\\Java_Final\\narwhal.png"));
} catch (IOException ex) {
// handle exception...
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 50, 50, null); // see javadoc for more info on the parameters
}
}
Amazing amazing = new Amazing();
All that line of code does is create a frame and then add an empty panel to it. Since the panel is empty there is nothing to paint.
Character character = new Character();
character.paintComponent(g);
You should never invoke the paintComponent() method directly. Swing will invoke that method when a component needs to be repainted. Anyway, creating a Character object does nothing. That object is just sitting in memory. It is not added to a GUI so it can never be painted.
I suggest you forget about custom painting and just use a JLabel to display an image. Read the section from the Swing tutorial on How to Use Labels for a working example. Not only that, the tutorial will show you how to better structure your code. You should not be using static variables. Start with the working example and then customize it to use your image.