Drawing Rectangle on a JPAnel

draw rectangle in Jpanel

Your newrect RectDraw's size is likely going to be quite small, probably [0, 0], since it has been added to a FlowLayout using JPanel and doesn't have a preferredSize set. Consider overriding its getPreferredSize() method and returning a suitable Dimension so that its drawing can be seen.

private static class RectDraw extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(230,80,10,10);
g.setColor(Color.RED);
g.fillRect(230,80,10,10);
}

public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H); // appropriate constants
}
}

Also,

  • The paintComponent method should be protected, not public
  • Don't forget to use @Override before your method overrides.
  • Aim for much less code in the main method and more code in the "instance" world, not the static world.
  • Take care with your code formatting. Poor code formatting, especially misleading indentations, leads to silly errors.

Drawing rectangle on a JPanel

I had tried drawing a square and circle, dynamically varying the size at runtime....attaching the complete code ..if it helps.

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.*;
import java.*;
import java.awt.Canvas;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

class DisplayCanvas extends Canvas
{
static boolean clip = false;
static boolean clipfurther = false;
static boolean isReset = false, isSlider = false;
int w, h;
static int wi = 300, hi = 300;
public DisplayCanvas()
{
//setSize(300, 300);
setBounds(20, 40, 300, 300);
setBackground(Color.white);
}
public void paint(Graphics g)
{
Graphics2D g2=(Graphics2D) g;
w = getSize().width;
h = getSize().height;

if(clip)
{
// Ellipse2D e = new Ellipse2D.Float(w/4.0f,h/4.0f,w/2.0f,h/2.0f);
Rectangle2D r = null;
if(isSlider)
{
r = new Rectangle2D.Float((w)/(4.0f), (h)/(4.0f), wi/2.0f, hi/2.0f);
// isSlider=false;
}
else
r = new Rectangle2D.Float(w/4.0f, h/4.0f, wi/2.0f, hi/2.0f);
//g2.setClip(e);

System.out.println("Width : "+ wi +" Height : "+ hi);
g2.setClip(r);
System.out.println(g2.getClipBounds());

if(shape.selectedcolor == "red")
{
g2.setColor(Color.red);
}
else if(shape.selectedcolor == "blue")
{
g2.setColor(Color.BLUE);
}
else if(shape.selectedcolor == "yellow")
{
g2.setColor(Color.yellow);
}

//g2.setColor(Color.RED);
g2.fillRect(0, 0, w, h);
}
else if(clipfurther)
{
//Rectangle r = new Rectangle(w/4, h/4, w/4, h/4);
Ellipse2D r = new Ellipse2D.Float(w/4.0f, h/4.0f, wi/2.0f, hi/2.0f);
g2.clip(r);
//g2.setColor(Color.green);
//g2.setColor(Color.getColor(shape.selectedcolor));

if(shape.selectedcolor == "red")
{
g2.setColor(Color.red);
}
else if(shape.selectedcolor == "blue")
{
g2.setColor(Color.BLUE);
}
else if(shape.selectedcolor == "yellow")
{
g2.setColor(Color.yellow);
}

g2.fillRect(0, 0, w, h);
}
}
}

class RadioListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == shape.circle)
{
shape.selectedcolor = shape.selectedcolor_reset;
System.out.println("Inside circle "+ shape.selectedcolor_reset);
System.out.println("2222222222");
DisplayCanvas.clip = true;
DisplayCanvas.clipfurther = false;
shape.canvas.repaint();
}
if (e.getSource() == shape.square)
{
shape.selectedcolor = shape.selectedcolor_reset;
System.out.println("333333333333333");
DisplayCanvas.clip = false;
DisplayCanvas.clipfurther = true;
shape.canvas.repaint();
}
}
}

class shape extends JFrame implements ActionListener
{
static String fname;
static JPanel panel, draw;
static Container contentpane, draw_pane;
static JFrame frame;
static JLayeredPane layer, draw_layer;
static JTextField user;
static JButton reset, cancel;

static JLabel file1, file2;
static JTextField text1;
static JRadioButton circle, square;
static JInternalFrame iframe, errmessage;
static JComboBox colors;
static JEditorPane sqc;
static JScrollPane scroller;
static JSlider slider;
String colors_array[]={"...", "red", "blue", "yellow"};
static DisplayCanvas canvas;
static String selectedcolor, selectedcolor_reset;

shape()
{
canvas=new DisplayCanvas();

panel= new JPanel();
panel.setBounds(20,20,250,140);
//panel.setLayout(new FlowLayout(10, 10, 10));
panel.setLayout(null);
contentpane = getContentPane();
contentpane.add(canvas);
//draw_pane=getContentPane();

layer = new JLayeredPane();
layer.setBounds(50,245,300,205);
layer.setForeground(Color.blue);

draw_layer = new JLayeredPane();
draw_layer.setBounds(200, 200, 80, 30);
draw_layer.setForeground(Color.BLACK);

draw = new JPanel();
draw.setBounds(20, 20, 250, 300);
draw.setLayout(null);

reset = new JButton("RESET");
reset.setBounds(360, 60, 100, 25);

circle = new JRadioButton("Square");
circle.setBounds(400, 100, 100, 40);
circle.setActionCommand("encryption");

square = new JRadioButton("Circle");
square.setBounds(330,100, 60, 40);
square.setActionCommand("decryption");

colors = new JComboBox(colors_array);
colors.setBounds(405, 140, 80, 30);
colors.setVisible(true);

file1 = new JLabel(" Select Color :");
file1.setBounds(320, 130, 150, 50);
//defining the Button Group for the Radio Buttons

ButtonGroup group = new ButtonGroup();
group.add(circle);
group.add(square);

cancel = new JButton("Exit");
cancel.setBounds(365, 250, 85, 25);

file2 = new JLabel("SIZE :");
file2.setBounds(336, 180, 150, 50);
setslider(0, 100, 100, 25, 5);
slider.setBounds(386, 190, 100, 50);

slider.setVisible(true);

panel.add(file2);
panel.add(layer);
panel.add(circle);
panel.add(square);
panel.add(colors);
panel.add(slider);
panel.add(file1);
panel.add(reset);
panel.add(cancel);
//panel.add(new CircleDraw());

//draw.add(draw_layer);
// draw_pane.add(draw);
contentpane.add(panel);
// contentpane.add(draw);
// contentpane.add(scroller);
RadioListener radio = new RadioListener();
circle.addActionListener(radio);
square.addActionListener(radio);
reset.addActionListener(this);
cancel.addActionListener(this);

colors.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JComboBox cb = (JComboBox)ae.getSource();
selectedcolor = (String)cb.getSelectedItem();
System.out.println(selectedcolor);
selectedcolor_reset = selectedcolor;
System.out.println("SELECTED "+ cb.getSelectedIndex());
canvas.repaint();
}
});

addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}

public void actionPerformed(ActionEvent e)
{
if(e.getSource()== cancel)
{
System.exit(0);
}
if (e.getSource() == reset)
{
System.out.println("111111111");
DisplayCanvas.clip = true;
DisplayCanvas.clipfurther = false;
DisplayCanvas.isReset = true;
shape.selectedcolor = "...";
System.out.println(" PREVIOUS " + selectedcolor_reset);
DisplayCanvas.hi = DisplayCanvas.wi = 300;
canvas.repaint();
}
}
public class SliderListener implements ChangeListener
{
public SliderListener()
{
}
public void stateChanged(ChangeEvent e)
{
JSlider slider = (JSlider)e.getSource();
System.out.println(slider.getValue());
DisplayCanvas.wi = slider.getValue() * 3;
DisplayCanvas.hi = DisplayCanvas.wi;
DisplayCanvas.isSlider = true;
canvas.repaint();
}
}
public void setslider(int min,int max,int init,int mjrtk,int mintk)
{
slider = new JSlider(JSlider.HORIZONTAL, min, max, init);
slider.setPaintTicks(true);
slider.setMajorTickSpacing(mjrtk);
slider.setMinorTickSpacing(mintk);
slider.setPaintLabels(true);
slider.addChangeListener((ChangeListener) new SliderListener());
}
}

public class display
{
static JFrame frame;
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
// TODO code application logic here
frame=new shape();

frame.setBounds(380, 200, 500, 400);
frame.setTitle("SHAPE AND COLOR");
frame.setVisible(true);

}
}

How can you draw rectangles on a JPanel?

You cannot draw directly on top of a JFrame. For "custom painting" (as this is called) you need to create a subclass of a component that overrides the paintComponent method. For example a JPanel:

class RectanglePanel extends JPanel {

int numberOfRectangles = 2;

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

g.setColor(Color.BLACK);
Random random = new Random(42);

for (int i = 0; i < numberOfRectangles; i++) {
x = random.nextInt(540);
y = random.nextInt(290);
g.drawRect(x, y, 60, 10);
}

}
}

You use this custom component the same way you would use a JPanel:

    rectanglePanel = new RectanglePanel();
rectanglePanel.setPreferredSize(new Dimension(600, 300));
add(rectanglePanel, BorderLayout.CENTER);

To draw fewer or more rectangles, the simplest thing you can do is change the numberOfRectangles of the custom component and then ask it to repaint itself.

int numberOfRectangles = RectangleSlider.getValue();
rectanglePanel.numberOfRectangles = numberOfRectangles;
rectanglePanel.repaint();

Note that this is a simplified demo and does not demonstrate "good practices" such as encapsulation. A more advanced technique is to using the model-view-controller pattern, and create a "model" object that encapsulates what is supposed to be drawn. You can read more about how that works for example here: The MVC pattern and Swing

Drawing rectangles on a JPanel

still no idea,

for example

Sample Image

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class CustomComponent extends JFrame {

private static final long serialVersionUID = 1L;

public CustomComponent() {
setTitle("Custom Component Graphics2D");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public void display() {
add(new CustomComponents());
pack();
// enforces the minimum size of both frame and component
setMinimumSize(getSize());
setVisible(true);
}

public static void main(String[] args) {
CustomComponent main = new CustomComponent();
main.display();
}
}

class CustomComponents extends JComponent {

private static final long serialVersionUID = 1L;

@Override
public Dimension getMinimumSize() {
return new Dimension(100, 100);
}

@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}

@Override
public void paintComponent(Graphics g) {
int margin = 10;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
}
}

How to draw rectangles as Objects on JPanel that are related to the code (can be selected, removed,...etc like Photoshop)

Now this drawn rectangle is associated with the upper-left vertex position and width and height. It's not associated with Rectangle object so there is no way to refer to the rectangle after it's drawn.

Create an ArrayListe of Shape objects. A Shape object can be a Rectangle, Ellipse, Polygon etc. Then in your paintComponent(...) method you iterated through the ArrayList to paint each Shape.

So the ArrayList contains the reference to your Rectangle.

Check out the Draw on Component example found in Custom Painting Approaches

If you want to get really fancy then check out Playing With Shapes. You can make your shape a real component.

How to keep the rectangle that I drew on the Jpanel when I draw another rectangle?

There are a few useful things to remember writing Swing graphics programs:

  • paintComponent repaints the entire component every time it is called, so you need to draw everything that you want to appear. The operations you do with the Graphics object will only persist until the next call to paintComponent.
  • Graphics2D is more capable than Graphics. It draws nicely antialiased shapes with floating-point co-ordinates, various line styles and so on. The Graphics parameter to paintComponent is in fact always a Graphics2D instance and you can cast it to one without worrying.
  • The inheritance hierarchy of components is also a painting hierarchy, so you need to call super.paintComponent(g) at the start of your paintComponent method. See this question for more details.

So I've made some changes to you program:

  • Added a field, List<Rectangle2D> rectangles to remember the rectangles the user has created. A rectangle is added to this list each time the mouse button is raised.
  • Added a call to super.paintComponent
  • Used Graphics2D to draw the rectangles, with a more interesting line style (Stroke)
  • Changed your paintComponent to draw each of the rectangles in the list, plus the 'rubber-band' rectangle the user is currently drawing.

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

public class DrawRect extends JPanel {

int x, y, x2, y2;
// this is the list of all the rectangles the user has drawn so far
List<Rectangle2D> rectangles = new ArrayList<>();

public static void main(String[] args) {
JFrame f = new JFrame("Draw Box Mouse 2");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new DrawRect());
f.setSize(300, 300);
f.setVisible(true);
}

DrawRect() {
x = y = x2 = y2 = 0; //
MyMouseListener listener = new MyMouseListener();
addMouseListener(listener);
addMouseMotionListener(listener);
}

public void setStartPoint(int x, int y) {
this.x = x;
this.y = y;
}

public void setEndPoint(int x, int y) {
x2 = (x);
y2 = (y);
}

// this creates a new rectangle object instead of drawing one
public Rectangle2D makePerfectRect(int x, int y, int x2, int y2) {
int px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
return new Rectangle2D.Float(px, py, pw, ph);
}

class MyMouseListener extends MouseAdapter {

public void mousePressed(MouseEvent e) {
setStartPoint(e.getX(), e.getY());
}

public void mouseDragged(MouseEvent e) {
setEndPoint(e.getX(), e.getY());
repaint();
}

public void mouseReleased(MouseEvent e) {
setEndPoint(e.getX(), e.getY());
// when the mouse is released, we add the current rectangle to our list
rectangles.add(makePerfectRect(x,y,x2,y2));
repaint();
}
}

public void paintComponent(Graphics g) {
// use Graphics2D, you can draw much nicer lines
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g);
g.setColor(Color.RED);
// draw the rectangle the user is currently drawing
g2d.draw(makePerfectRect(x,y,x2,y2));
g.setColor(Color.BLUE);

Stroke oldStroke = g2d.getStroke();
g2d.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0.0f));
for (Rectangle2D r : rectangles) {
g2d.draw(r);
}
g2d.setStroke(oldStroke); // restore the original Stroke
}

}

Trying to draw a simple rectangle with JPanel, but nothing is showing up

You will need to instantiate a DrawPanel and add it to frame in DrawTest. First include a constructor for DrawPanel, then add these lines in the go() method:

DrawPanel panel = new DrawPanel();
frame.add(panel);

Drawing on a JPanel inside a JFrame using fillRect - rectangle sizing and position issues?

When you do custom painting:

  1. You should override paintComponent() not paint() and invoke super.paintComponent(g) as the first statement to make sure the background is cleared.

  2. Override the getPreferredSize() method of the class to return the size of the panel so layout managers can do there job. So in your case it should be (300, 300).

In your code you should not be setting the preferred size of any components. It is the job of the layout manager to determine the preferred size of a component.

panel.setPreferredSize(new Dimension(300,300));

You currently set the preferred size of the panel holding the jumping ball. This doesn't help because the preferred size of the jumping ball has not been set. You see a (10, 10) square because the FlowLayout of the panel determines the preferred size of your jumping ball panel is only (10, 10).

Also, there is no need to create a separate panel. You can just add the JumpingBall panel directly to the frame.

Drawing a rectangle on JPanel

The problem is that the y coordinate for your racket is greater then the preferred size height of the panel ScreenPanel:- 250 > 200:

    racket = new Racket(120, 250, 70, 10);
^
setPreferredSize(new Dimension(200, 200));

making the racket draw offscreen.



Related Topics



Leave a reply



Submit