Reputation: 259
what I am trying to achieve in Java is to be able to paint random shapes from another method without having to have those shapes already drawn from the start (user picks x, y, w, h themselves)
Here is what I have so far:
public class Design extends JComponent {
private static final long serialVersionUID = 1L;
public void paint(Graphics g) {
super.paintComponent(g);
}
public void drawRect(int xPos, int yPos, int width, int height) {
Graphics g = null;
g.drawRect(width, height, xPos, yPos);
}
}
As you can see above, I have the drawRect function coded but do not understand how to make it so when I call the drawRect() function, it gets the paint() function to draw a rectangle instead which is EXACTLY what the paint function does, inside it, you type g.drawRect() and your x,y,w,h. The reason why I am doing this and not just straight up using paint() is because i'm trying to make a component so instead of having to type out the paint() function everytime, I just add this class to my Swing and it's done.
Hope you understand what I'm trying to achieve here. Thanks.
Upvotes: 1
Views: 5884
Reputation: 347194
The first thing you need to do is let go of the idea that you can control the paint process, you can't, you can respond to paint events and make requests to the RepaintManager
that an update might be needed.
Basically, you don't call paint
directly, paint is called in response to the RepaintManager
wanting something painted.
Take look at Painting in AWT and Swing and Performing Custom Painting.
On to your code. Don't override paint
and certainly don't circumvent the paint process, instead, it should look something more like this...
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawRect(g, 10, 10, 10, 10);
}
protected void drawRect(Graphics g, int xPos, int yPos, int width, int height) {
g.drawRect(xPos, yPos, width, height);
}
Graphics#drawRect
actually takes parameters x
, y
, width
, height
in that order...
The reason why I am doing this and not just straight up using paint() is because i'm trying to make a component so instead of having to type out the paint() function every time
Doesn't make sense, that's the point of having the paint
methods, so you can customise the way a component is paint, make lots of instances of it and add it your GUI...this is how all the Swing controls work...
Also, you might find 2D Graphics of interest
Updated based on comments
So, you want a method that some other object can call and it will enable them to add a "rectangle" to the the existing object/component...
Start by defining an instance variable of Rectangle
private Rectangle rectangle;
In your paintComponent
, check to see if rectangle
is null
or not and if it's not, paint it...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (rectangle != null) {
Graphics2D g2d = (Graphics2D)g;
g2d.draw(rectangle);
}
}
Now, update your drawRect
method to create an instance Rectangle
and request that the component be repainted
public void drawRect(int xPos, int yPos, int width, int height) {
rectangle = new Rectangle(xPos, yPos, width, height);
repaint();
}
For example...
public class Design extends JComponent {
private Rectangle rectangle;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (rectangle != null) {
Graphics2D g2d = (Graphics2D)g;
g2d.draw(rectangle);
}
}
public void drawRect(int xPos, int yPos, int width, int height) {
rectangle = new Rectangle(xPos, yPos, width, height);
repaint();
}
}
Now, if you want to support having multiple rectangles, you could simply use a List
and add as many instances Rectangle
as you want, iterating over the List
in the paintComponent
method
Upvotes: 2
Reputation: 10994
You need to do all paintings inside paintComponent()
method with calling super.paintComponent()
.
I suggest you to store all needed shapes in List
and draw all of them in paintComponent()
.
Instead of drawRect
use something like addRect
which adding new shape to your List
and call repaint()
method. Examine next simple example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class TestFrame extends JFrame {
public TestFrame() {
System.out.println("as".equalsIgnoreCase(null));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
init();
pack();
setVisible(true);
}
private void init() {
final Design d = new Design();
d.addRect(0,0,10,20);
JButton b = new JButton("add");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Random r = new Random();
int w = r.nextInt(100);
int h = r.nextInt(100);
d.addRect(0,0,w,h);
}
});
add(d);
add(b,BorderLayout.SOUTH);
}
public static void main(String... strings) {
new TestFrame();
}
private class Design extends JComponent {
private static final long serialVersionUID = 1L;
private List<Shape> shapes = new ArrayList<Shape>();
public void paint(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for(Shape s : shapes){
g2d.draw(s);
}
}
public void addRect(int xPos, int yPos, int width, int height) {
shapes.add(new Rectangle(xPos,yPos,width,height));
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(100,100);
}
}
}
Upvotes: 1