Reputation: 41
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);
}
}
Upvotes: 0
Views: 3279
Reputation: 137
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!
Upvotes: 1
Reputation: 285415
You would have to modify the JPanel of interest in order to use that code by:
List<DrawRectangle>
and draw those in a for loop within paintComponentFor 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.
Upvotes: 1