Rotating Rectangle with Color - java

I am starting to build a simulation in java and using a rectangle as a plane. But as I rotate the rectangle its foreground color won't stick to it. Can someone help me?
Screenshot:Here
Source Code:
private void drawTransform(Graphics g, double modifier) {
Rectangle rect = new Rectangle(130,350, 350, 15);
AffineTransform at = new AffineTransform();
at.rotate(-Math.toRadians(modifier), rect.getX(), rect.getY() + rect.height);
// Transform the shape and draw it to screen
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.red);
g2d.fillRect(130, 350, 350, 15);
g2d.draw(at.createTransformedShape(rect));
}

Use fill instead of draw:
g2d.fill(at.createTransformedShape(rect));

Related

How to use a setStroke on a graphics object?

I am trying to make a program where when you click a check box saying that you want an object to be drawn with a dashed line you can, but when I create a stroke and try to use it my graphics does not acknowledge it. The code is set to double buffer so the image doesn't disappear when you are creating it. I am not sure how to make the objects draw in with the dashed line and would appreciate any help!
Graphics bgg = bg.getGraphics();
if(!jCheckBox1.isSelected()){
bgg.drawImage(fg, jPanel1.getX(), jPanel1.getY()-50, null);
}
else{
Graphics2D g2d = (Graphics2D) bgg;
float[] fa = {10, 10, 10};
BasicStroke bs = new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, fa, 10);
g2d.setStroke(bs);
g2d.drawImage(fg, jPanel1.getX(), jPanel1.getY()-50, null);
}
In order to draw a rectangle onto your image you will need to use the Graphics.drawRect() method something like this (just off the top of my head with what you've already got):
Graphics bgg = bg.getGraphics();
if(!jCheckBox1.isSelected()){
bgg.drawImage(fg, jPanel1.getX(), jPanel1.getY()-50, null);
}
else{
Graphics2D g2d = (Graphics2D) bgg;
//Draw image into panel...
g2d.drawImage(fg, jPanel1.getX(), jPanel1.getY()-50, null);
//Draw dashed rectagle in center of panel...
int pW = jPanel1.getWidth(); // Get panel Width
int pH = jPanel1.getHeight(); // Get panel Height
float[] fa = {10, 10, 10}; // The dash pattern
// Set Brush thickness (5)
BasicStroke bs = new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, fa, 10);
g2d.setStroke(bs);
Dimension rectangle = new Dimension(200, 50); // Our desired rectangle dimensions
// Center locations for rectangle...
int x1 = (pW / 2) - (rectangle.width / 2);
int y1 = (pH / 2) - (rectangle.height / 2);
int x2 = rectangle.width;
int y2 = rectangle.height;
g2d.setColor(Color.RED); // Set the dashed shape line color
g2d.drawRect(x1, y1, x2, y2); // Draw the dashed rectangle
// free resourses
bgg.dispose();
g2d.dispose();
jPanel1.revalidate(); // update panel graphics
}
A brush stroke of 5 makes for a pretty heavy dash :)

How to use graphics2D from BufferedImage object, with "getGraphics()" method?

I'm trying to make a 2D game, but I can't figure out why my graphics from precedent frames are still there. The effect is when moving a rectangle on x with 1 pixel / frame, I get a long bar drawn on my screen.
In the class body I declared the objects beneath like that:
private int x, y;
private BufferedImage image;
private Graphics2D g;
This is how I'm initializing:
x = 10, y = 25;
image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_BGR);
g = (Graphics2D) image.getGraphics();
r = new Rectangle(x, y, 10, 10);
I have method where I draw graphics:
Graphics g2 = this.getGraphics();
g2.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.draw(r);
g2.dispose();
I also have a tick method where I move the rectangle:
x++;
The class extends Canvas and implements Runnable for the game loop and I use a JFrame object .
This is the result of 10x10 rectangle movement:
capture

How can I paint a custom circular JComponent without an "invisible box" around it?

I'm writing a JApplet that displays a diagram with numbers in circles and lines connecting the circles. I've created a class that extends JComponent to act as the circles. I overrode the paintComponent() method to draw a circle with the numbers inside, and I placed these circles on my applet, on which I drew the lines in the paint() method.
However, if the lines hit the circle at an angle, they cut out early, before the circle, at the square that outlines the entire JComponent, even though the background should be transparent. this forms an "invisible box" around the circle.
I've prepared a smaller program to demonstrate the issue:
And here is the code for that example:
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import javax.swing.*;
public class Circle extends JApplet {
private static final long serialVersionUID = 1L;
myCircle myC = new myCircle(10, 215, 215); // custom circle
Container c;
public void init() {
setSize(500, 500);
c = getContentPane();
c.setLayout(null);
c.setBackground(Color.lightGray);
c.add(myC);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
//draw lines
g2d.draw(new Line2D.Double(0f, 0f, 500f, 500f));
g2d.draw(new Line2D.Double(0f, 500f, 500f, 0f));
g2d.draw(new Line2D.Double(0f, 250f, 500f, 250f));
g2d.draw(new Line2D.Double(250f, 0f, 250f, 500f));
g2d.draw(new Line2D.Double(150f, 0f, 350f, 500f));
myC.repaint(); // put the circle on top
}
public class myCircle extends JComponent {
private static final long serialVersionUID = 1L;
int number; // number to display
public myCircle(int num, int x, int y) {
this.number = num;
this.setLocation(x, y);
this.setSize(75, 75);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
g2d.setColor(Color.white);
g2d.fill(new Ellipse2D.Float(1f, 1f, 70f, 70f));
g2d.setColor(Color.black);
g2d.draw(new Ellipse2D.Float(1f, 1f, 70f, 70f));
g2d.drawString(Integer.toString(number), 15f, 20f);
}
}
}
I wouldn't use a component to represent the circle shape alone. Instead, just paint it all on one JPanel (I'm using a JFrame instead of an applet):
public class Circle extends JPanel {
int number = 10;
float size = 500f;
float rad = 70f;
float stringLocX = 15f, stringLocy = 20f;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
g2d.setColor(Color.BLACK);
g2d.draw(new Line2D.Double(0f, 0f, size, size));
g2d.draw(new Line2D.Double(0f, size, size, 0f));
g2d.draw(new Line2D.Double(0f, size / 2, size, size / 2));
g2d.draw(new Line2D.Double(size / 2, 0f, size / 2, size));
g2d.draw(new Line2D.Double(150f, 0f, 350f, 500f));
Ellipse2D.Float circle = new Ellipse2D.Float((size - rad) / 2, (size - rad) / 2, rad, rad);
g2d.setColor(Color.WHITE);
g2d.fill(circle);
g2d.setColor(Color.BLACK);
g2d.draw(circle);
g2d.drawString(Integer.toString(number), (size - rad) / 2 + stringLocX,
(size - rad) / 2 + stringLocy);
}
#Override
public Dimension getPreferredSize() {
return new Dimension((int) size, (int) size);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.add(new Circle());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
});
}
}
Depending on how many circles you have and what data they must contain, you can just keep a list of those numbers, then iterate over the list in painComponent and draw them.
Notes:
Don't use null layout.
Better to keep the hard coded numbers as fields so you can change them more easily, possibly make them final.
You need to look at the length of the line being drawn. From the edge of your figure to the circle is longer at an angle than at the sides. Recall for a triangle with 45 degrees, 45 degree, and 90 degree angles the ratio of the length of the sides is 1:1:sqrt(2)

Inner-Transparent Selection Window in Java using GlassPane

I am trying to achieve the following
http://www.qksnap.com/i/3hunq/4ld0v/screenshot.png
I am currently able to draw rectangles successfully on a semi-transparent glasspane background using the following code:
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.black); // black background
g.fillRect(0, 0, frame.getWidth(), frame.getHeight());
g2.setColor(Color.GREEN.darker());
if (getRect() != null && isDrawing()) {
g2.draw(getRect()); // draw our rectangle (simple Rectangle class)
}
g2.dispose();
}
Which works great, however, I would love to have the area within the rectangle be completely transparent while the outside was still darken much like the screenshot above.
Any ideas?
..have the area within the rectangle be completely transparent while the outside was still darken much like the screenshot above.
Create a Rectangle (componentRect) that is the size of the component being painted.
Create an Area (componentArea) of that shape (new Area(componentRect)).
Create an Area (selectionArea) of the selectionRectangle.
Call componentArea.subtract(selectionArea) to remove the selected part.
Call Graphics.setClip(componentArea)
Paint the semi-transparent color.
(Clear the clipping area if more paint operations are required).
As Andrew has suggested (just beat me while I was finishing off my example)
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g.setColor(Color.black); // black background
Area area = new Area();
// This is the area that will filled...
area.add(new Area(new Rectangle2D.Float(0, 0, getWidth(), getHeight())));
g2.setColor(Color.GREEN.darker());
int width = getWidth() - 1;
int height = getHeight() - 1;
int openWidth = 200;
int openHeight = 200;
int x = (width - openWidth) / 2;
int y = (height - openHeight) / 2;
// This is the area that will be uneffected
area.subtract(new Area(new Rectangle2D.Float(x, y, openWidth, openHeight)));
// Set up a AlphaComposite
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2.fill(area);
g2.dispose();
}

Java awt draw circle border

Using java awt, how to make the code draw a border for a circle. The henceforth code has performance issues, and maybe it would run faster if it just painted the outline.
g.fillOval(gameLogic.getParticleXCoor(i) - 3,
gameLogic.getParticleYCoor(i) - 3,
gameLogic.getParticleSize(i) + 6,
gameLogic.getParticleSize(i) + 6);
g.setColor(gameLogic.getParticleColor(i));
g.fillOval(gameLogic.getParticleXCoor(i),
gameLogic.getParticleYCoor(i),
gameLogic.getParticleSize(i),
gameLogic.getParticleSize(i));
You could try drawOval instead of fillOval.
If you want paint circle use Ellipse2D class:
Ellipse2D.Double circleBorder = new Ellipse2D.Double(x, y, 15, 15);
After just call draw() methid from Graphics2D
g2.draw(circleBorder);
Full code for draw circle icons as example is here:
#Override
public void paintIcon(#Nonnull Component c, #Nonnull Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
BasicStroke dashed =new BasicStroke(3.0f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,10.0f);
Ellipse2D.Double circle = new Ellipse2D.Double(x+1, y+1, 14, 14);
Ellipse2D.Double circleBorder = new Ellipse2D.Double(x, y, 15, 15);
g2.setColor(getColor());
g2.setRenderingHints(hints);
g2.fill(circle);
Composite oldComposite=g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0));
g2.setColor(new Color(1,1,1,1));
g2.setStroke(dashed);
g2.draw(circleBorder);
g2.setComposite(oldComposite);
}

Categories