0

I am trying to draw a rectangle. But I am not sure how, it paints in certain panel. Would like to see an example for, How I can supply the panel and position for drawing the rectangle. I have the following template, I would like to see what modifications I need to make to use this class to draw rectangle on any Panels. My intention is to use panels width, and heights and add a rectangle to that position. Goal is to be able to use this class any where with any JPanels.

import java.awt.Color;
import java.awt.Graphics; 
import javax.swing.JPanel; 
public class DrawRectangle{
 private int startX;
 private int startY;
 private int width;
 private int height;
 private Color color;
 private JPanel panel;
 public DrawRectangle(JPanel panel, int startX, int startY, int width, int height, Color color) {
 this.startX = startX;
 this.startY = startY;
 this.width = width;
 this.height = height;
 this.color = color;
 this.panel = panel; 
 }
 public void paint(Graphics g) {
 g.setColor(this.color);
 g.fillRect(this.startX, this.startY, this.width, this.height);
 g.drawRect(this.startX, this.startY, this.width, this.height);
 }
}
asked Feb 10, 2020 at 14:20
1
  • 1
    See Custom Painting Approaches for a complete examples that draws rectangles. Commented Feb 10, 2020 at 14:59

2 Answers 2

1

Check out the Graphics2D class it is meant for exactly what you are trying to do and is better suited for drawing than the regular paintComponent method. You can read about how to use Graphics2D here.

Firstly note that you cannot have a Graphics2D object without casting it from a Graphics object like I did here Graphics2D g2 = (Graphics2D) g;.

This is an example that should help you to get started, keep in mind I'm using absolute layout so no layout manager. This is code I was using to create a blackjack game so thats why things are names are not generic.

Also I added smoothing so your shapes with Graphics2D will look really nice and the methods center the shapes on screen which will probably work well with your JPanels.

Notice how I created specific methods for the Graphics2D objects I wanted to draw and then drew them using the Graphics class. That seemed to work the best for me so that my paintComponent wasn't just littered with endless repeated code. frame in my code was getting the width and height of the JFrame I had the JPanel in so for you simply refer to the JPanel you would have it in instead.

class DrawTable extends JPanel
{
 DrawTable()
 {
 super();
 System.out.println("Looks good to me pal!");
 }
 @Override
 public void paintComponent(Graphics g)
 {
 super.paintComponent(g);
 //Setup background
 drawRectangle(g, Color.BLACK,
 frame.getWidth() / 2, frame.getHeight() / 2,
 frame.getWidth(), frame.getHeight());
 // Create table at center
 drawRectangle(g, new Color(206, 187, 158),
 frame.getWidth() / 4, frame.getHeight(), //left table leg
 50, 600);
 drawRectangle(g, new Color(206, 187, 158),
 frame.getWidth() / 1.5, frame.getHeight(), //right table leg
 50, 600);
 drawEllipse(g, new Color(153, 154, 104),
 frame.getWidth() / 2, frame.getHeight() / 2, //Draws outer circle
 1200, 400);
 drawEllipse(g, new Color(53, 101, 77),
 frame.getWidth() / 2, frame.getHeight() / 2, //Draws inner circle
 1125, 350);
 }
 private void drawEllipse(Graphics g, Color color, double x, double y, double width, double height) //centers ellipse
 {
 Graphics2D g2 = (Graphics2D) g;
 double centerX = (double) x - width / 2;
 double centerY = (double) y - height / 2;
 Ellipse2D ellipse = new Ellipse2D.Double(centerX, centerY, width, height);
 RenderingHints render = new RenderingHints(
 RenderingHints.KEY_ANTIALIASING,
 RenderingHints.VALUE_ANTIALIAS_ON);
 render.put(
 RenderingHints.KEY_RENDERING,
 RenderingHints.VALUE_RENDER_QUALITY);
 g2.setRenderingHints(render);
 g2.setColor(color);
 g2.fill(ellipse);
 g2.draw(ellipse);
 }
 private void drawRectangle(Graphics g, Color color, double x, double y, double width, double height) //centers rectangle
 {
 Graphics2D g2 = (Graphics2D) g;
 double centerX = (double) x - width / 2;
 double centerY = (double) y - height / 2;
 Rectangle2D rect = new Rectangle2D.Double(centerX, centerY, width, height);
 RenderingHints render = new RenderingHints(
 RenderingHints.KEY_ANTIALIASING,
 RenderingHints.VALUE_ANTIALIAS_ON);
 render.put(
 RenderingHints.KEY_RENDERING,
 RenderingHints.VALUE_RENDER_QUALITY);
 g2.addRenderingHints(render);
 g2.setColor(color);
 g2.fill(rect);
 }
}

Let me know if you need anymore help!

answered Feb 10, 2020 at 17:57
Sign up to request clarification or add additional context in comments.

7 Comments

"Firstly note that you cannot have a Graphics2D object without casting it from a Graphics object like I did here Graphics2D g2 = (Graphics2D) g;" -- this is not strictly true
When overriding paintComponent(GRAPHICS g) it is. @HovercraftFullOfEels
Agree, when you get the Graphics object from the JVM, such as within paint, paintComponent, or paintComponents, then the Graphics2D object can often be obtained by casting. One can also be obtained directly from a BufferedImage by way of its .createGraphics() method, and then this image can be drawin within the paintComponent method. Also, your code appears to be repurposed GUI code, one that won't compile due to residual lines of code that in the current context have no meaning (or variable declaration).
I think I explained pretty well what the variables are for and they explain themselves, frame.getHeight(). However, I may edit my answer to include a bit more of an explanation for RenderingHints. It will definitely compile if op just follows my my code and I have it inheriting from the base class op asked for. @HovercraftFullOfEels
? I edited my post a while ago to remove that. @HovercraftFullOfEels
|
1

You would have to modify the JPanel of interest in order to use that code by:

  • Overriding its paintComponent method
  • First calling the super's paintComponent method in your override
  • And then drawing your own DrawRectangle class's paint method
  • If you want to be able to draw multiple rectangles, then give the JPanel a List<DrawRectangle> and draw those in a for loop within paintComponent

For example, for one rectangle:

public class DrawingPanel extends JPanel {
 private DrawRectangle drawRectangle;
 public DrawingPanel(DrawRectangle drawRectangle) {
 this.drawRectangle = drawRectangle;
 }
 @Override
 protected void paintComponent(Graphics g) {
 super.paintComponent(g);
 if (drawRectangle != null) {
 drawRectangle.paint(g);
 }
 }
}

and for many rectangles:

public class DrawingManyRectPanel extends JPanel {
 private List<DrawRectangle> drawRectangles;
 public DrawingManyRectPanel(List<DrawRectangle> drawRectangles) {
 this.drawRectangles = drawRectangles;
 }
 @Override
 protected void paintComponent(Graphics g) {
 super.paintComponent(g);
 if (drawRectangles != null) {
 for (DrawRectangle rectangle : drawRectangles) {
 rectangle.paint(g);
 }
 }
 }
}

In these classes, the constructor is overridden to allow injection of rectangles into the class via constructor call. For the second class, I'd also add a method that allows addition of further rectangles:

public void addRectangle(DrawRectangle rectangle) {
 drawRectangles.add(rectangle);
 repaint();
}

similar for removing rectangles


An alternate way to do this, if you don't plan to remove rectangles or modify the ones already drawn, is to draw them in a BufferedImage, and then draw that image in the drawing JPanel's paintComponent method.

answered Feb 10, 2020 at 14:28

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.