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);
}
}
-
1See Custom Painting Approaches for a complete examples that draws rectangles.camickr– camickr2020年02月10日 14:59:48 +00:00Commented Feb 10, 2020 at 14:59
2 Answers 2
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!
7 Comments
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).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. @HovercraftFullOfEelsYou 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.