Problem in generating the border of a rectangle in Java? - java

I am using java.awt.geom.Rectangle2D.Double class to generate a rectangle. I want to generate a rectangle which is filled with a color (say green) and have a border (outline).
Now the problem is if I call
g2.draw(new Rectangle2D.Double(....)); // g2 is an instance of Graphics2D
then it doesn't fill the rectangle and when I call
g2.fill(new Rectangle2D.Double(....)); // g2 is an instance of Graphics2D
then id doesn't generate border.

To do this, render the rectangle twice, first the fill and then the border (draw).
Rectangle2D rect = new Rectangle2D.Double(...);
g2.setColor(Color.white);
g2.fill(rect);
g2.setColor(Color.black);
g2.draw(rect);

How about doing both? Draw the filled rectangle first and then draw the outline one over the top.

Related

Draw Rectangle Over Buffered Image Java

I have a JPanel on which I draw the image of a map using a BufferedImage. I also have a button which, when clicked will highlight a part of the map by drawing a red rectangle over that part.
However, when I zoom in on the image, the rectangle stays where it was before. I assume the reason behind this is that the rectangle is being drawn over the panel and over the Image.
Is there a way to adjust the rectangle's position in accordance with the zoom?
Here's how I draw the rectangle and the image:
//the variable years[activeIndex] is an array which stores my Buffered Images
Graphics2D g2=(Graphics2D)g.create();
g.drawImage( years[activeIndex],0, 0,(int)width,(int)height,null);
g2.setColor(Color.red);
g2.setStroke(new BasicStroke(3));
g2.drawRect(this.getWidth()/2,this.getHeight()/2, 20, 20);
MapViewer.imagePanel.revalidate();
This is the rectangle when there is no zoom
This is the rectangle with the zoom, it stays in its place because its on the JPanel and not on the BufferedImage

Drawing a circle on a bufferedImage in Java

I want to draw a circle on a buffered image that act like a png
i want to use this circle in order to replace the mouse cursor for a paint application i am working on.
i cant download a circle png from google as i need to keep changing the size of this circle depending on the width of the tool i am using it for.
here is my attempt so far
public static BufferedImage getCircle() {
BufferedImage bufferedImage = new BufferedImage(30, 30, BufferedImage.TYPE_INT_RGB);
Color transparent = new Color(0x00FFFFFF, true);
Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
//trying to make the bufferedImage transparent
g.setComposite(AlphaComposite.Src);
g.setColor(transparent);
g.setBackground(transparent);
g.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
//drawing the circle
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.black);
g.drawOval(0, 0, 200, 200);
return bufferedImage;
}
it should look like:
However my code currently only creates a white square.
Your code has two problems (as already shown in the comments). The first is that you draw a circle with a radius of 200px into an image of dimensions 30px. If you closely look you can barely see a black pixel in the lower right corner.
Fix it by adjusting your dimensions such that it fits inside, for example like:
BufferedImage bufferedImage = new BufferedImage(60, 60, BufferedImage.TYPE_INT_RGB);
...
g.drawOval(5, 5, 50, 50);
Next is that you want to achieve a transparent background. To do so you need to set the type of the image to a color model which supports transparency, like ARGB (A = Alpha = transparency) instead of RGB:
BufferedImage bufferedImage = new BufferedImage(60, 60, BufferedImage.TYPE_INT_ARGB);
Last you probably want to increase the thickness of your border to achieve the image you showed. You do so by using g.setStroke(...):
g.setColor(Color.BLACK);
g.setStroke(new BasicStroke(5));
g.drawOval(5, 5, 50, 50);
With this setting you achieve the following result (with transparency):
Play with the values to adjust the circle to your exact needs.

Java - repeating a gradient image horizontally (Swing)

I'm new to Java GUI. I have two questions. Is there a way to repeat a gradient image horizontally like you would when working with CSS? If not, what is the conventional way of creating a gradient in Java?
In Swing, the GradientPaint class can be used to draw a gradient. Below is an example that will draw a square containing a linear gradient between white and red (assuming this code is within a class that extends JComponent):
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
GradientPaint gradient = new GradientPaint(0,0,Color.WHITE, 100, 0, Color.RED);
g2d.setPaint(gradient);
g2d.fillRect(0,0,100,100);
}

BasicStroke causes offcenter

Changing the BasicStroke of a Graphics2D object to anything other than 1 causes it to not draw something on the center of a JPanel on startup.
This is a JPanel which is on a JFrame. This is the basic idea of my project, but it is not the entire thing.
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
if(this.centered){
this.myShape.setCenterX(this.getWidth()/2);
this.myShape.setCenterY(this.getHeight()/2);
}
g2.setStroke(new BasicStroke(3)); //new BasicStroke(1) works fine
g2.draw(this.myShape);
}
When you click and drag the myShape, myShape will immediately jump to the center. But when I initially compile and run it, paintComponent() paints it about a centimeter above the center of the screen if the stroke is not 1.
Is there something wrong with how I'm centering? I defined the MyShape class, so there could be an error there. Maybe the distance between the center and the drawing point is the space between JPanel and the top of the JFrame? How do I fix it?
Edit: added picture
http://s21.postimage.org/dfpmz73et/Untitled_1.png
The first shape is right where I want it. The other two are above where I want it. But it appears the displacement from the center are the same regardless of stroke size.
Yes, I believe this is the normal behaviour for a shape. It assumes an outline of 1 pixel. So you need to change the center calculation when you know you are going to change the basic stroke size. Something like:
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
BasicStroke stroke = new BasicStroke(3);
int adjustment = stroke.getLineWidth() - 1;
if(this.centered){
this.myShape.setCenterX(this.getWidth() + adjustment / 2);
this.myShape.setCenterY(this.getHeight() + adjustment / 2);
}
g2.setStroke(stroke);
g2.draw(this.myShape);
}

Is there any way of drawing a variable rectangle using the Graphics class

I have coded a simple Java game where there are two rectangles on the screen, one of the rectangles moves and the other stays still, the moving Rectangle moves with keyboard arrow input and can move either up, down, left or right. The problem I am having is drawing my rectangles on the screen, I mean I have the 2 rectangles set up with my variables as shown:
Rectangle rectOne = new Rectangle(shiftX, shiftY,90,90);
Rectangle rectTwo = new Rectangle(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);
I have made a render method to draw the things on the screen which I want shown:
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
}
The problem I am having is showing my rectangles on the screen by writing the code in the render method, I could do the following:
g.fillRect(x, y,90,90);
g.fillRect(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);
Which makes 2 rectangles on the screen but I need the rectangles to be drawn using the Rectangle code written with the variables, I have been told this can be done using Graphics2D but I am wondering if there is a simpler way of just using the graphics function, if not could you please help me set this up?
Thank you in advance.
You can access attributes of the Rectangle instances easily:
g.fillRect(rectOne.getX(), rectOne.getY(), rectOne.getWidth(), rectOne.getHeight());
In any case mind that usually the Graphics object is a Graphics2D instance at runtime so this could work easily too:
Graphics2D g2d = (Graphics2D)g;
g2d.fill(rectOne);
Just use:
g.fillRect(myRect.getX(), myRect.getY(), myRect.getWidth(), myRect.getHeight());
where myRect is the rectangle you want to draw. You could even make a custom method drawRect(Graphics g, Rectangle myRect); if you have lots of rectangles to draw.
Using Graphics2D is not that difficult as well, as the provide Graphics object normally is a Graphics2D object:
Graphics2D g2d = (Graphics2D) g;
g2d.fill(myRect);

Categories

Resources