I've been working on a simple paint program and I have recently run into a snag when redrawing shapes in my paint component.
#Override
public void paintComponent(final Graphics theGraphics) {
super.paintComponent(theGraphics);
final Graphics2D g2d = (Graphics2D) theGraphics;
if (!preDrawnShapes.isEmpty() && !preDrawnShapeThickness.isEmpty()) {
for (int i = 0; i < preDrawnShapes.size(); i++) {
g2d.setStroke(new BasicStroke(preDrawnShapeThickness.get(i)));
g2d.draw(preDrawnShapes.get(i));
}
}
g2d.setStroke(new BasicStroke(currentThickness));
if (myShape != null) {
g2d.draw(myShape);
preDrawnShapeThickness.add(currentThickness);
}
}
This paintComponenent is supposed to first redraw the shapes previously drawn before before then drawing the new shape created from user input.
For some reason, the shape thickness when drawing the new shape is set to the current thickness but any shape that I drew before had a default thickness of 1.
preDrawnShapes is a Shapes ArrayList and preDrawnShapeThickiness is a Float Arraylist.
Am I missing something here?
UPDATE: I've discovered that PreDrawnShapeThickness stores only Floats of zero. I am unsure why.
There are two common ways to do incremental painting:
Keep a List of Objects that you want to paint. Then the paintComponent() method iterates through the List and paints each object. So in your case the custom object would contain the Shape you want to paint and an int value for the thickness of the shape.
Just paint each Object directly to a BufferedImage. Then you can just use a JLabel to display the BufferedImage as an Icon, or do custom painting to paint the BufferedImage.
Check out Custom Painting Approaches for examples of both approaches.
Related
Ok so this is a shape drawn with a random color, however I'd like that shape to stay that color while being repainted. Right now with this draw method it just draws a new random color every repaint() so it looks like a rainbow shape. How would I make it grab a random color then stick with that for that particular shape?
public void draw(Graphics g) {
g.setColor(new Color(randomNum.nextInt(256), randomNum.nextInt(256), randomNum.nextInt(256)));
g.fillOval((int)getX(),(int)getY(), getRadius(), getRadius());
}
By saving the color you're drawing.
So you'll only randomly generate it once, and then keep using that color to redraw each time.
Either generate it before the draw like Color c = new Color(randomNum.nextInt(256), randomNum.nextInt(256), randomNum.nextInt(256)); or only generate the variable and test if it has been initialized in your draw method. If it hasn't (the first time running your code), you generate a random color, if it has been initialized, you just skip generating the color and go straight to your g.fillOval
You keep a list of shapes. every shape has his color and radius.
when repaint, you draw every shape in the list.
static class OvalShape {Color color; int radius;}
List<OvalShape> shapeList = new ArrayList<>();
public void draw(Graphics g) {
for(Shape s : shapeList) {
g.setColor(s.color);
g.fillOval((int)getX(),(int)getY(), s.radius, s.radius);
}
}
Im making a small program that needs previous graphics to stay "put" and visible, even after a repaint causes a variable location to change.
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.red);
g.fillOval(mouseLocX,mouseLocY,30,30);
}
this is all i have in the paint class, and i want to change the mouseLocX and mouseLocY values, and call repaint without having the previous location there. Ive done this before, and most people want the opposite, but i forgot how. Im calling repaint from a MouseMotionListener using mouseDragged();
If you want to preserve what's already been painted so that you get a trail of red ovals instead of a single red oval as the mouse moves, then you shouldn't paint directly on the Graphics object provided by paint(). Instead, use a BufferedImage to store your state. Then render the BufferedImage onto the Graphic provided by paint().
private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
public void paint(Graphics g) {
super.paint(g);
Graphics imageGraphics = image.getGraphics();
imageGraphics.setColor(Color.red);
imageGraphics.fillOval(mouseLocX,mouseLocY,30,30);
g.drawImage(image, 0, 0, null);
}
The BufferedImage provides the persistence for the previous draw operations.
i have created a simple program in Java for painting Graphic primitives (Lines,Rectangles,Ellipses,etc.).The shapes are drawn on the screen with dragging the mouse and stored into an array of Shapes,so i have added a slider for getting the stroke size (from 1 to 20 with 1 being default value) dynamically,but it updates all the shapes that are previously drawn as well.
//NOTE1: Graphics2D graph; is defined in the class extending JFrame
//NOTE2: strokeSize value is dynamically changing with the slider
public void paint(Graphics g)
{
graph = (Graphics2D)g;
graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
graph.setStroke(new BasicStroke(strokeSize));
for (Shape currentShape : shapes)
{
graph.setPaint(strokeCounter.next());
graph.draw(currentShape);
graph.setPaint(fillCounter.next());
graph.fill(currentShape);
}
//What follows are If statements for choosing a shape
//and actual methods for drawing them...
So my question is:How to update the strokeSize,but only for shapes currently being drawn?
Store the stroke size along with the shape. Set the stroke size before issuing the draw command.
Add graph.setStroke(new BasicStroke(currentShape.getStrokeSize())); before graph.draw(currentShape);
You'll need to add a property called StrokeSize to your Shape class.
I am making a simple game where there are two rectangles drawn on the screen and with user input from the keyboard arrow keys one of the rectangles (the player) will move. I have made a Main class and a Play class which consists of all my game code, this code includes methods such as init(), update() and render(), the init() deals with all the initial conditions, the update() deals with the movement and key inputs from the input and the render() method deals with drawing the stuff onto the screen such as the background and rectangles.
The problem I am having is drawing my rectangles (which are set up with my variables) on my screen by putting them in my render class, my method is set up with Graphics and I have been told I require Graphics2D so I am attempting to change my graphics to Graphics2D so that I can draw my rectangles.
Here are my Rectangles which have been set up with my variables at the top of my ode:
Rectangle rectOne = new Rectangle(shiftX, shiftY,90,90);
Rectangle rectTwo = new Rectangle(500 + buckyPositionX, 330 + buckyPositionY, 210, 150);
and here is my render method where I am trying to draw my rectangles using the graphics2D:
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
if(rectOne.intersects(rectTwo)){
g.drawString("Intersect", 100, 100);}
if(g instanceof Graphics2D){//error: Incompatible conditional operand type Graphics and Graphics2D
Graphics2D g2 = (Graphics2D)g;}//cannot cast from Graphics to Graphics2D
((Graphics2D)g).fill(rectOne);//cannot cast from Graphics to Graphics2D
((Graphics2D)g).fill(rectTwo);//cannot cast from Graphics to Graphics2D
}
The comments next to my code shows the errors that are appearing when I try to use this code. If any more code or information is required from my Play class please tell me and I will post it.
I have a String and I want to paint it onto an image. I am able to paint points and draw lines, however, even after reading the Text part of the 2D Graphics tutorial, I can't figure out how I can take a String and paint it onto my drawing.
Unless I'm looking at the wrong tutorial (but it's the one I get whenever I search for anything about Java and painting Strings using Graphics or Graphics2D), I'm still stumped.
Check out the following method.
g.drawString();
The drawString() method will do what you need.
An example use:
protected void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.drawString(5, 40, "Hello World!");
}
Just remember, the coordinates are regarding the bottom left of the String you are drawing.
if you want to play with the shape of your string (eg: fill:red and stroke:blue):
Graphics2D yourGraphicsContext=(...);
Font f= new Font("Dialog",Font.PLAIN,14);
FontRenderContext frc = yourGraphicsContext.getFontRenderContext();
TextLayout tl = new TextLayout(e.getTextContent(), f, frc);
Shape shape= tl.getOutline(null);
//here, you can move your shape with AffineTransform (...)
yourGraphicsContext.setColor(Color.RED);
yourGraphicsContext.fill(shape);
yourGraphicsContext.setColor(Color.BLUE);
yourGraphicsContext.draw(shape);