I wanted to add background image to my JFrame.
Background image means I can later add Components on the JFrame or JPanel
Although I coudn't find how to add background image to a JFrame,
I found out how to add background image to a JPanel from here:
How to set background image in Java?
This solved my problem, but now since my JFrame is resizable I want to keep the image in center.
The code I found uses this method
public void paintComponent(Graphics g) { //Draw the previously loaded image to Component.
g.drawImage(img, 0, 0, null); //Draw image
}
Can anyone say how to align the image to center of the JPanel.
As g.drawImage(img, 0, 0, null); provides x=0 and y=0
Also if there is a method to add background image to a JFrame then I would like to know.
Thanks.
Assuming a suitable image, you can center it like this:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int x = (this.getWidth() - image.getWidth(null)) / 2;
int y = (this.getHeight() - image.getHeight(null)) / 2;
g2d.drawImage(image, x, y, null);
}
If you want the other components to move with the background, you can alter the graphics context's affine transform to keep the image centered, as shown in this more complete example that includes rotation.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.translate(this.getWidth() / 2, this.getHeight() / 2);
g2d.translate(-image.getWidth(null) / 2, -image.getHeight(null) / 2);
g2d.drawImage(image, 0, 0, null);
}
Related
The purpose of the black JPanel is drawing.
How can I restrict the drawing to the radius of the circle formed by the lines?
Is there a way to save the graphics object state so that more drawing can be added to it as well as adding an undo function?
public void paintComponent(Graphics g)
{
super.paintComponent(g);
sectors = 12;
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
sector = new Line2D.Double(getWidth()/2, 0, getWidth()/2, getHeight());
//g2d.setClip(new Ellipse2D.Double(getWidth()/2,getHeight()/2, radius, radius));
//draws the sectors on the screen
for(int i=0; i<sectors; i++)
{
g2d.draw(sector);
g2d.rotate(Math.toRadians(30),getWidth()/2,getHeight()/2);
}
//draws the doily
if(dragging)
{
for(int i=0; i<sectors; i++)
{
g2d.fillOval((int) draw.getX(), (int) draw.getY(),20, 20);
g2d.rotate(Math.toRadians(30), getWidth()/2, getHeight()/2);
}
//saves the current drawing in a stack
graphics.push(g2d);
}
}
For your first question,
You would need to read up on Java's Custom Painting http://docs.oracle.com/javase/tutorial/uiswing/painting/
Not to discourage you but this is a tricky process,
To answer your question there is a similar post here
Java Change shape of JPanel
I'm trying to make a 2D game, but I can't figure out why my graphics from precedent frames are still there. The effect is when moving a rectangle on x with 1 pixel / frame, I get a long bar drawn on my screen.
In the class body I declared the objects beneath like that:
private int x, y;
private BufferedImage image;
private Graphics2D g;
This is how I'm initializing:
x = 10, y = 25;
image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_BGR);
g = (Graphics2D) image.getGraphics();
r = new Rectangle(x, y, 10, 10);
I have method where I draw graphics:
Graphics g2 = this.getGraphics();
g2.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.draw(r);
g2.dispose();
I also have a tick method where I move the rectangle:
x++;
The class extends Canvas and implements Runnable for the game loop and I use a JFrame object .
This is the result of 10x10 rectangle movement:
capture
Specifically, I am trying to display only the rotated object. I have a drawn rectangle and I rotate it.
How to I display only the rotated rectangle and dispose of the old one?
EDITED:
The following is the code to rotate my rectangle:
private void rotateRectangle(Graphics g, Rectangle rect, Color c){
Graphics2D g2d = (Graphics2D) g.create();
x = rect.x;
y = rect.y;
g2d.setColor(c);
g2d.rotate(Math.PI/6, PANEL_WIDTH/2,PANEL_HEIGHT/2);
g2d.drawRect(PANEL_WIDTH/2-x/2, PANEL_HEIGHT/2-y/2, x, y);
}
And this is the paintComponent where I call it from:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setStroke(new BasicStroke(3));
//these are declared before
rect.x = x;
rect.y = y;
if(rotateClicked){
rotateRectangle(g2d,rect,squareColor);
rotateClicked = false;
}
drawRectangle(g2d, rect, squareColor);
getArea(x,y);
}
If custom rendering shapes with a Graphics object by overwriting paintComponent(Graphics g), ensure you use super.paintComponent(g) as the first line to clear the drawing area
From there draw your Rectangle/rotated Rectangle
Without using super.paintComponent(g), your previous drawings (the unrotated Rectangle) will remain visible
EDIT
With the update of source code: you are drawing both the new and the old rectangle because your if statement does not have an else clause
Try inserting an else clause so that it will draw one rectangle or the other, currently it maybe draws a rotated rectangle and then draws the unrotated rectangle
if(rotateClicked)
{
rotateRectangle(g2d,rect,squareColor);
rotateClicked = false;
}
else
drawRectangle(g2d, rect, squareColor);
You may or may not want a rotateClicked = true in the else so it will flip back and forth between rotated and unrotated
How can I fill the following rectangle using an image? Can anyone help me please?
public void paintComponent(Graphics g) {
setOpaque(false);
//Paint a filled rectangle at user's chosen point.
if (point != null) {
g.drawRect(0, 0,
rectWidth - 1, rectHeight - 1);
g.setColor(Color.yellow);
g.fillRect(1, 1,
rectWidth - 2, rectHeight - 2);
}}
I tried this code but I couldn't find a way to make it work:
File imageFile = new File("duck.jpg");
BufferedImage img;
Graphics2D graph = img.createGraphics();
graph.setColor(Color.BLACK);
graph.fill(new Rectangle(1, 2, rectWidth, rectHeight));
graph.dispose();
ImageIO.write(img, "jpg", new File("duck.jpg"));
You have to load an image into an Image object (like BufferedImage) and then call
graphics.drawImage()
on that image, giving the coordinates and other info.
Look in the tutorial for more info
I am trying to achieve the following
http://www.qksnap.com/i/3hunq/4ld0v/screenshot.png
I am currently able to draw rectangles successfully on a semi-transparent glasspane background using the following code:
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.black); // black background
g.fillRect(0, 0, frame.getWidth(), frame.getHeight());
g2.setColor(Color.GREEN.darker());
if (getRect() != null && isDrawing()) {
g2.draw(getRect()); // draw our rectangle (simple Rectangle class)
}
g2.dispose();
}
Which works great, however, I would love to have the area within the rectangle be completely transparent while the outside was still darken much like the screenshot above.
Any ideas?
..have the area within the rectangle be completely transparent while the outside was still darken much like the screenshot above.
Create a Rectangle (componentRect) that is the size of the component being painted.
Create an Area (componentArea) of that shape (new Area(componentRect)).
Create an Area (selectionArea) of the selectionRectangle.
Call componentArea.subtract(selectionArea) to remove the selected part.
Call Graphics.setClip(componentArea)
Paint the semi-transparent color.
(Clear the clipping area if more paint operations are required).
As Andrew has suggested (just beat me while I was finishing off my example)
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g.setColor(Color.black); // black background
Area area = new Area();
// This is the area that will filled...
area.add(new Area(new Rectangle2D.Float(0, 0, getWidth(), getHeight())));
g2.setColor(Color.GREEN.darker());
int width = getWidth() - 1;
int height = getHeight() - 1;
int openWidth = 200;
int openHeight = 200;
int x = (width - openWidth) / 2;
int y = (height - openHeight) / 2;
// This is the area that will be uneffected
area.subtract(new Area(new Rectangle2D.Float(x, y, openWidth, openHeight)));
// Set up a AlphaComposite
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2.fill(area);
g2.dispose();
}