I'm making a space game that renders objects onto a JPanel.
These objects' render method is called in my Space class.
I have 2 objects, alienShip and myShip with respective classes. Each class has a render method. I can't get both ships to render onto my JPanel simultaneously, it's either one or the other. I only see the object that calls the .render(g2) method first.
SPACE CLASS:
spaceImage=new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
foregroundImage=new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
//create the space Image background and instantiate ships (myShip, alienShip)
//Below render() method is called in my Game class using a standard game loop with
update method and rendor method.
public void render(Graphics2D g) {
Graphics2D g2=(Graphics2D) foregroundImage.getGraphics();
g2.drawImage(spaceImage, 0, 0, null);
myShip.render(g2); <---alienShip does not appear, only myShip.
alienShip.render(g2); <---If I swap these 2 commands, then alienShip appears,
and myShip does not
g.drawImage(foregroundImage, x, x, null);
}
ALIENSHIP AND MYSHIP CLASS:
public void render(Graphics2D g) {
g.drawImage(shipImage, x, y, null);
g.dispose();
}
I've tried to create a Drawable interface, and loop through all drawable objects calling DrawableObject.render(g2), but doesn't fix it. Furthermore, I have bullets that DO rendor simultaneously with myShip.
myShip and alienShip does extend an abstract class called Ship as well. Hope this makes sense.
You're .dispose()ing the graphics object after drawing one item, then trying to draw another item with it.
Related
I'm pretty new to Java and the GUI world. Right now I'm trying to create a really basic space shooter. To create it I started creating a JFrame, in which I've later on put a personal extension of a JPanel called GamePanel, on which I'm now trying to display all my components. Until here it's all pretty clear, the problem comes now: I have my GamePanel in which I display my player, and on the KeyEvent of pressing S the player should shoot the Bullets. I've managed the bullets as an Array, called Shooter[], of Bullet Objects, created by myself this way:
public class Bullet implements ActionListener{
Timer Time = new Timer(20, this);
private int BulletY = 430;
public int PlayerX;
public Rectangle Bound = new Rectangle();
public Bullet(int playerx) {
this.PlayerX = playerx;
Time.start();
}
public void draw(Graphics g){
g.setColor(Color.RED);
g.fillRect(PlayerX + 2, BulletY, 3, 10);
g.dispose();
}
#Override
public void actionPerformed(ActionEvent e) {
if (Time.isRunning()) {
BulletY = BulletY - 5;
Bound = new Rectangle (PlayerX + 2, BulletY, 3, 10);
}
}
}
I thought that calling the draw method in the GamePanel's paint() method would have allowed me to display both all the bullets shot and the player. What actually happens is that at the start it seems allright, but when I press S the player disappears and just one bullet is shot. Can you explain me why? This is how my paint() method looks like:
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, 500, 500);
for(int i = 0; i < BulletsCounter; i++) {
Shooter[i].draw(g);
}
g.setColor(Color.RED);
g.fillRect(PlayerX, PlayerY, 20, 20);
//System.out.println("Here I should have painted the player...");
g.dispose();
}
BulletsCounter is a counter I've created to avoid any NullPointerExceptions in painting the whole array, it increases when S is pressed and so another bullet of the array is initialized and shot.
Thank you for your patience, I'm new to the site, so warn me for any mistake.
You've several significant problems, the biggest given first:
You're disposing a Graphics object given to you by the JVM. Never do this as this will break the painting chain. Instead, only dispose of a Graphics object that you yourself have created.
You're drawing within paint which is not good for several reasons, but especially bad for animation since you don't have automatic double buffering of the image
You don't call the super painting method within your override and thus don't allow the JPanel to do house-keeping painting.
Recommendations:
Don't dispose of the Graphics object, not unless you, yourself, create it, for example if you extract one from a BufferedImage.
Override the JPanel's paintComponent method, not its paint method to give you double buffering and smoother animation.
And call super.paintComponent(g) first thing in your override to allow for housekeeping painting
I have the following task for my school in Java:
Create a GUI window with your own graphic. This graphic should be created in a separate JPanel class and drawn using the draw and fill methods of the java.awt.Graphics class (e.g. a house with a garden, a car, ...). The graphic should contain at least 5 different types of graphics (rectangle, oval, ...), at least one polygon (draw or fillPolygon (polygon p) method) and an arc (draw or fillArc method (int x, int y, int width, int height, int startAngle, int arcAngle)). The graphic should also contain at least 10 drawing elements and consist of at least 4 different colors.
But I don´t know how to use the class Graphics, so I don´t know how to create a Grahpics object and edit it. Does anyone know how to solve this? Thank you
You can use graphics with a JPanel;
class exampleclass extends JPanel {
exampleClass() {
...
}
#Override
public void paintComponent(Graphics g) {
...your code here...
}
}
For more information, look at; https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html
You can call paint method with, repaint();
Hello I'm trying to add an Image that I have on my desktop to my JFrame that I have created i have imported all the necessary functions and the correct variables the only trouble i have is with Image observer I set my x and y values for my image but it causes an error in my drawImage component and it asks for an Image observer which i don't know what it is and if i auto fill something my Image doesn't appear on my JFrame. If one of you can look at my code or answer what an Image observer does i would be greatly appreciated
public class Window2 extends JPanel {
// Image Import
ImageIcon i = new ImageIcon("C: / Class Pokemon Game/ src / GameTitle (1).psd");
Image title = i.getImage();
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setBackground(Color.BLACK);
g.setColor(Color.RED);
g.fillRect(0, 40, 5000, 20);
g.**drawImage**(title, 500, 500);
}
}
the error is
add argument to match 'drawImage(Image, int, int, ImageObserver)'
ImageObserver is an interface that has methods for handling notification of state of image loading. It can use this for redisplay as needed. JFrame and Applet both implement ImageObserver interface.
To keep users informed regarding the loading of an image
ImageObserver interface – Enables the monitoring of the loading process so that
users can be informed and the image can be used asap once it is loaded.
Loading an image asynchronously – how to know when the image is ready.
An image is ready – getImage() method returns, long before anything is
known about the image.
imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
Note: java.awt.Component implements ImageObserver, all the subclasses do as
well!
g.drawImage(imge, 0,0, this) -- this refers to the ImageObserver instance.
imageUpdate() – Called by the ImageObserver whenever necessary. You do not call
it explicitly!
If the image is complete, returns false.
If the image is not complete and needs to be updated, returns true.
ImageObserver.ALLBITS = 32
Various constants are combined to form the infoflags argument, which indicates
whether all information is available or not.
You can skip using an ImageObserver by putting it as null
for example (Using Graphics2D)
g2.drawImage(Image texture, x, y, width, height, null);
I create an object called "City"
City city = new City (name, rec, g);
The object's constructor looks like this:
public City (String name, Rectangle r, Graphics g){
this.name = name;
this.r = r;
this.g = g;
}
By creating this object i also draw an oval on an uploaded picture, and set it's colour to BLUE. Here's how I draw the object:
g = (Graphics2D) window.lblNewLabel.getGraphics();
g.setColor(Color.BLUE);
g.fillOval(mouseX, mouseY, 15, 15);
I would like to be able to change that colour later, after clicking on the oval itself.
I try to call this function, but it doesn't work:
public void isClicked(){
clicked = true;
this.color = Color.RED;
this.g.setColor(Color.PINK);
}
How to change a colour of an existing object?
Using getGraphics() on a component causes a transient graphics Object to be used on the component itself. Any subsequent calls to repaint will erase the painting done using that object.
Change the color by overriding the paintComponent method. Save the Color variable as a class member variable and use it to determine the oval color in the method.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(savedColor);
g.fillOval(mouseX, mouseY, 15, 15);
}
Don't use getGraphics() to do painting, that painting is only temporary and will be lost the next time Swing determines a components needs to be repainted.
Check out Playing With Shapes for other ideas on doing painting.
You could use a ShapeIcon which allows you to change the color of the icon. The icon could be painted in the paintComponent() method of your label.
Or you could use ShapeComponent which uses a ShapeIcon. Then you can just add the component to the label like any other component.
I would like to be able to change that colour later, after clicking on the oval itself
The ShapeIcon would be added to a JLabel. Then you can just add a MouseListener to the label of the ShapeComponent to change the color of the icon.
When you have drawn objects with a Graphics object, they are then rendered on the screen. You can't change the color of them directly, instead you will have to repaint your graphics any time when you want to change them. If you want to keep track of the colors for the objects, you will have to store the data in some kind of variable and use it when drawing.
I'm trying to make a tower of hanoi solver which simply solves the hanoi without any mouse events. The problem is when I move the rectangle the original remains, even after I repaint. I've searched the net and tried changing the code around but nonthing worked. I am using a JFrame with a JPanel inside of it if that changes anything.
I have my disk class here which is just a rectangle with colour.
class Disk extends Rectangle {
Color diskColour;
public Disk(int a, int b, int c, int d, Color colour) {
x = a;
y = b;
width = c;
height = d;
diskColour = colour;
}
public Color getColour() {
return diskColour;
}
public void paintSquare(Graphics g) {
repaint();
g.setColor(diskColour);
g.fillRect(x, y, width, height);
repaint();
}
}
Here is my code where I actually call the paintSquare method:
public void simpleMoveDisk(Disk[] disks, int n, Graphics g) {
disks[n].setLocation(30,25);
disks[n].paintSquare(g);
repaint();
}
The paintSquare method paints the disk, while the setLocation method changes its coordinates.
When this runs the rectangle occurs in the new location, however the old one still remains. Any help is appreciated, thanks in advance.
You are calling repaint() in several places and you shouldn't be.
Have your the top level class that is doing the painting, call the paintSquare method and any other method that is needed. Those methods should not be calling repaint().
Also your simple move disk is really strange in the fact that it passes an array of Disks, an index, and a graphics object. Instead make it just take in a Disk. Just pass it the one out of the array that is needed to be updated. Then let whatever class that calls simpleMoveDisk, separately make a call to repaint instead of trying to paint and update the model in the same method.