Drawing Hexagon Using Java error - java

i written a code to draw a hexagon. First i plot the 6 points using this formula :
(x + r*cos(i*2*pi/6), y + r*sin(i*2*pi/6))
then after i plot these points i tried to match between the points using Bresnham's Algorithm for drawing lines which i had implemented it in a method.
Unfortunately the Code doesn't work successfully and i get this instead of the hexagon. I think there is an error with Bresnham's algorithm implementation. In addition, I tried to plot each point alone but it wont work.
If anyone can help me?
Also this is my Code :
package javaapplication1;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.geom.Line2D;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class LinesDrawingExample extends JFrame {
public LinesDrawingExample() {
super("Lines Drawing Demo");
//Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
void drawLines(Graphics g , int x,int y) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
g2d.drawLine(x, y, x,y);
//g2d.draw(new Line2D.Double(59.2d, 99.8d, 419.1d, 99.8d));
// g2d.draw(new Line2D.Float(21.50f, 132.50f, 459.50f, 132.50f));
}
public void getvalue(Graphics g,double x1,double y1 ,double x2,double y2){
int x=(int)x1;
int y=(int)y1;
int deltax=(int)x2-(int)x1;
int deltay=(int)y2-(int)y1;
int twodeltay=2*deltay;
int var1=twodeltay-(2*deltax);
int p=twodeltay-deltax;
drawLines(g,x,y);
while(x<x2)
{
drawLines(g,x,y);
if(p>0)
{
y=y+1;
p=p+twodeltay-(2*deltax);
}
else
{
p=p+twodeltay;
}
x++;
}
}
public void paint(Graphics g) {
super.paint(g);
double r=50;
double pi=3.14;
int [] xval =new int [6];
int [] yval=new int [6];
int x=100,y=100;
for(int i=0; i<6; i++) {
getvalue(g,x + r*cos(i*2*pi/6), y + r*sin(i*2*pi/6),x + r*cos(i*2*pi/6),y + r*cos(i*2*pi/6));
xval[i]=(int)(x + r*cos(i*2*pi/6));
yval[i]=(int)(y + r*sin(i*2*pi/6));
}
getvalue(g,xval[4],yval[4],xval[5],yval[5]);
getvalue(g,xval[2],yval[2],xval[1],yval[1]);
getvalue(g,xval[3],yval[3],xval[2],yval[2]);
getvalue(g,xval[3],yval[3],xval[3],yval[3]);
getvalue(g,xval[4],yval[4],xval[4],yval[4]);
getvalue(g,xval[5],yval[5],xval[5],yval[5]);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new LinesDrawingExample().setVisible(true);
}
});
}
}

You were drawing on the JFrame. Never draw on a JFrame. Always draw on a JPanel.
Here's the GUI.
Here are the major changes I made.
I moved the creation of the hexagon into its own class, Hexagon. That way, you can create a List of Hexagons if you want.
I moved the creation of the drawing panel into its own class, DrawingPanel. That way, I have a GUI view class that draws the hexagon, and a GUI model class that generates the hexagons. A nice, clean separation of concerns.
This left the JFrame code and the instantiation of a Hexagon object in the constructor of the LinesDrawingExample class.
Here's the code.
package com.ggl.testing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class LinesDrawingExample extends JFrame {
private static final long serialVersionUID = 3775690273871048733L;
private DrawingPanel drawingPanel;
public LinesDrawingExample() {
super("Lines Drawing Demo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Hexagon hexagon = new Hexagon(new Point(250, 250), 200);
drawingPanel = new DrawingPanel(hexagon);
add(drawingPanel);
pack();
setLocationByPlatform(true);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new LinesDrawingExample();
}
});
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 5701311351092275287L;
private Hexagon hexagon;
public DrawingPanel(Hexagon hexagon) {
this.hexagon = hexagon;
this.setPreferredSize(new Dimension(500, 500));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.drawPolygon(hexagon.getHexagon());
}
}
public class Hexagon {
private final int radius;
private final Point center;
private final Polygon hexagon;
public Hexagon(Point center, int radius) {
this.center = center;
this.radius = radius;
this.hexagon = createHexagon();
}
private Polygon createHexagon() {
Polygon polygon = new Polygon();
for (int i = 0; i < 6; i++) {
int xval = (int) (center.x + radius
* Math.cos(i * 2 * Math.PI / 6D));
int yval = (int) (center.y + radius
* Math.sin(i * 2 * Math.PI / 6D));
polygon.addPoint(xval, yval);
}
return polygon;
}
public int getRadius() {
return radius;
}
public Point getCenter() {
return center;
}
public Polygon getHexagon() {
return hexagon;
}
}
}

You shouldn't override paint(g). Override paintComponent(g) instead. You can use a loop to plots all the points needed for a polygon.
Plot the points and create a Polygon object, then draw the polygon object:
public class DrawPolyPanel extends JPanel{
public DrawPolyPanel(){
setPreferredSize(new Dimension(200, 200));
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Polygon p = new Polygon();
for (int i = 0; i < 6; i++)
p.addPoint((int) (100 + 50 * Math.cos(i * 2 * Math.PI / 6)),
(int) (100 + 50 * Math.sin(i * 2 * Math.PI / 6)));
g.drawPolygon(p);
}
public static void main(String[] args){
JFrame frame = new JFrame("DrawPoly");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawPolyPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

Related

How to rotate something with Graphics2D

So I want to rotate this Rectangle I made
public void paint (Graphics g)
{
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.fillRect(10, 10, 30, 30);
g2.rotate(Math.toRadians(45)); //I tried this but doesn't seem to work...
}
How do I do that? Rotate as in rotate in 45* angle or 200* angle.
It really isn't that hard to rotate objects. Most of the code below is simply boiler plate to create the frames and panels. Here is a demo that shows two methods that were mentioned in the comments.
the left panel simply rotates the graphics context. This is, imo, the easiest method but it does not alter the object.
the right panel uses the AffineTransform to rotate the object. This actually changes the contents of the shape.
If the desire is to rotate an object in place it is necessary to ensure one is rotating about the middle of the image that is under rotation. In both cases below that would be (125,125) or the center of both the panels and the rectangle.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
public class RotateRectangle extends JPanel {
JFrame frame = new JFrame();
double angle = 0;
MyPanel mypanel = new MyPanel();
public static void main(String[] args) {
SwingUtilities
.invokeLater(() -> new RotateRectangle().start());
}
public void start() {
Timer t = new Timer(0, (ae) -> {mypanel.rotateit(); frame.repaint();});
t.setDelay(30);
t.start();
}
public RotateRectangle() {
frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.add(mypanel);
setBorder(new LineBorder(Color.red,2));
mypanel.setBorder(new LineBorder(Color.red, 2));
frame.pack();
// center on screen
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
// visually smooth the lines
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.BLACK);
g2d.rotate(angle, 125,125);
g2d.drawRect(75, 75, 100, 100);
// adjust the amount of rotation per timer interval
angle += Math.PI / 200;
g2d.dispose();
}
public Dimension getPreferredSize() {
return new Dimension(250, 250);
}
}
class MyPanel extends JPanel {
Polygon polygon = new Polygon();
// amount to rotate
double angle = Math.PI / 200;
Shape shape = polygon;
AffineTransform af = new AffineTransform();
public MyPanel() {
af.rotate(angle, 125,125);
polygon.addPoint(75,175);
polygon.addPoint(175,175);
polygon.addPoint(175,75);
polygon.addPoint(75,75);
}
public void rotateit() {
shape = af.createTransformedShape(shape);
}
public void paintComponent(Graphics g) {
if (shape == null) {
return;
}
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
// visually smooth the lines
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.BLACK);
g2d.draw(shape);
}
public Dimension getPreferredSize() {
return new Dimension(250, 250);
}
}
Following up on my comment, I created the following GUI.
I used math to calculate the four endpoints of a rotated rectangle and used the Graphics2D fillPolygon method to draw the rectangle.
The buttons at the bottom of the GUI allow you to rotate the rectangle on the center point or the upper left endpoint.
I created a drawing JPanel to draw the rectangle. All the paintComponent method of the drawing JPanel does is draw the Polygon returned by the application model.
The application model is a key part of this application. I create a plain Java getter / setter class. I start with a java.awt.Rectangle and use polar coordinates to rotate the rectangle. I convert the polar coordinates back to cartesian coordinates to get the four endpoints of the Polygon.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class RotatingRectangle implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new RotatingRectangle());
}
private DrawingPanel drawingPanel;
private JButton centerButton;
private JButton endPointButton;
private RotatedRectangle rotatedRectangle;
public RotatingRectangle() {
this.rotatedRectangle = new RotatedRectangle(Color.BLUE,
new Rectangle(200, 200, 100, 50));
}
#Override
public void run() {
JFrame frame = new JFrame("Rotating Rectangle");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.drawingPanel = new DrawingPanel(rotatedRectangle);
frame.add(drawingPanel, BorderLayout.CENTER);
frame.add(createButtonPanel(), BorderLayout.AFTER_LAST_LINE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public JPanel createButtonPanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
ButtonListener listener = new ButtonListener(this, rotatedRectangle);
centerButton = new JButton("Rotate on center point");
centerButton.addActionListener(listener);
panel.add(centerButton);
endPointButton = new JButton("Rotate on end point");
endPointButton.addActionListener(listener);
endPointButton.setPreferredSize(centerButton.getPreferredSize());
panel.add(endPointButton);
return panel;
}
public void repaint() {
drawingPanel.repaint();
}
public JButton getCenterButton() {
return centerButton;
}
public JButton getEndPointButton() {
return endPointButton;
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private RotatedRectangle rotatedRectangle;
public DrawingPanel(RotatedRectangle rotatedRectangle) {
this.rotatedRectangle = rotatedRectangle;
this.setBackground(Color.WHITE);
this.setPreferredSize(new Dimension(400, 400));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Polygon polygon = rotatedRectangle.getRectangle();
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(rotatedRectangle.getColor());
g2d.fillPolygon(polygon);
}
}
public class ButtonListener implements ActionListener {
private final RotatingRectangle frame;
private final RotatedRectangle model;
private Timer timer;
public ButtonListener(RotatingRectangle frame, RotatedRectangle model) {
this.frame = frame;
this.model = model;
}
#Override
public void actionPerformed(ActionEvent event) {
if (timer != null) {
timer.stop();
}
JButton button = (JButton) event.getSource();
if (button.equals(frame.getEndPointButton())) {
model.setCenterPoint(false);
model.setAngle(180);
} else {
model.setCenterPoint(true);
model.setAngle(0);
}
timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
model.incrementAngle(1);
frame.repaint();
}
});
timer.start();
}
}
public class RotatedRectangle {
private boolean centerPoint;
private int angle;
private final Color color;
private final Rectangle rectangle;
public RotatedRectangle(Color color, Rectangle rectangle) {
this.color = color;
this.rectangle = rectangle;
this.angle = 0;
this.centerPoint = true;
}
public int getAngle() {
return angle;
}
public void setAngle(int angle) {
this.angle = angle;
}
public void incrementAngle(int increment) {
this.angle += increment;
this.angle %= 360;
}
public Polygon getRectangle() {
Point rotatePoint = new Point(rectangle.x, rectangle.y);
if (isCenterPoint()) {
int x = rectangle.x + rectangle.width / 2;
int y = rectangle.y + rectangle.height / 2;
rotatePoint = new Point(x, y);
}
Point[] point = new Point[4];
int width = rectangle.x + rectangle.width;
int height = rectangle.y + rectangle.height;
point[0] = new Point(rectangle.x, rectangle.y);
point[1] = new Point(width, rectangle.y);
point[2] = new Point(width, height);
point[3] = new Point(rectangle.x, height);
Polygon polygon = new Polygon();
for (int i = 0; i < point.length; i++) {
point[i] = calculatePoint(rotatePoint, point[i], angle);
polygon.addPoint(point[i].x, point[i].y);
}
return polygon;
}
private Point calculatePoint(Point rotatePoint, Point point, int angle) {
double theta = Math.toRadians(angle);
int xDistance = rotatePoint.x - point.x;
int yDistance = rotatePoint.y - point.y;
double distance = Math.sqrt(xDistance * xDistance + yDistance * yDistance);
double alpha = Math.atan2(yDistance, xDistance);
theta += alpha;
int x = (int) Math.round(Math.cos(theta) * distance) + rotatePoint.x;
int y = (int) Math.round(Math.sin(theta) * distance) + rotatePoint.y;
return new Point(x, y);
}
public Color getColor() {
return color;
}
public boolean isCenterPoint() {
return centerPoint;
}
public void setCenterPoint(boolean centerPoint) {
this.centerPoint = centerPoint;
}
}
}

Drawing Circles to JFrame

I'm having issues drawing some circles to my JFrame. I originally had it using the default layout and realized this was only adding the most recent circle, so I changed the layout to null, and now nothing gets drawn. I've also tried frame.setLayout(new FlowLayout()) which also doesn't draw anything. Any help would be appreciated!
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
/**
* #author Christopher Nielson
*
*/
public class Main {
private static JFrame frame;
private static Random rand;
private static Jiggler jiggler;
private static ArrayList<JComponent> circles;
private static int fps;
public static void main(String[] args) {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setBounds(100, 100, 450, 450);
rand = new Random();
circles = new ArrayList<JComponent>();
int x = frame.getWidth();
int y = frame.getHeight();
for (int i = 0; i < Integer.parseInt(args[0]); i++) {
circles.add(new Circle(rand.nextInt(frame.getWidth()), rand.nextInt(frame.getHeight()),
rand.nextInt(frame.getWidth() / 10) + 100, rand.nextInt(frame.getHeight() / 10) + 100, null));
}
circles.forEach(current -> {
frame.add(current);
});
frame.setVisible(true);
jiggler = new Jiggler(circles, new JLabel("FPS: ")); // TODO add fps
jiggler.run();
}
}
And this is one reason you'll see us recommending time and time again to avoid using null layouts like the plague.
Having said that, your main problem is a design problem, not a layout problem, and that problem being that your Circle class shouldn't extend JComponent or any component for that matter, since if you want to draw multiple circles, you should have only one component, probably a JPanel doing the drawing, and the Circles should be logical classes, classes that have a public void draw(Graphics g) method, not component classes. You would pass the List of Circles to your drawing JPanel, and it would draw the Circles in its paintComponent method by calling the draw(g) methods of each Circle in the list.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class DrawChit extends JPanel {
private static final int PREF_W = 900;
private static final int PREF_H = 700;
private static final int MAX_SHAPES = 30;
private List<MyShape> shapes = new ArrayList<>();
public DrawChit() {
setBackground(Color.WHITE);
for (int i = 0; i < MAX_SHAPES; i++) {
double x = (PREF_W - 100) * Math.random();
double y = (PREF_H - 100) * Math.random();
double w = 100 + (Math.random() * PREF_W) / 10;
double h = 100 + (Math.random() * PREF_H) / 10;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
float hue = (float) Math.random();
double delta = 0.3;
float saturation = (float) (Math.random() * delta + (1 - delta));
float brightness = (float) (Math.random() * delta + (1 - delta));
Color color = Color.getHSBColor(hue, saturation, brightness);
shapes.add(new MyShape(ellipse, color));
}
// we'll throw a black square in the middle!
int rectW = 200;
int rectX = (PREF_W - rectW) / 2;
int rectY = (PREF_H - rectW) / 2;
shapes.add(new MyShape(new Rectangle(rectX, rectY, rectW, rectW), Color.BLACK));
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// use anti-aliasing to make graphics smooth
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// iterate through the shapes list, filling all
for (MyShape shape : shapes) {
shape.fill(g2);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyMouse extends MouseAdapter {
private Point p0 = null;
private MyShape shape = null;
#Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// iterate *backwards* so get top-most Shape
for (int i = shapes.size() - 1; i >= 0; i--) {
if (shapes.get(i).contains(e.getPoint())) {
p0 = e.getPoint();
shape = shapes.get(i);
// move selected shape to the top!
shapes.remove(shape);
shapes.add(shape);
repaint();
return;
}
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (p0 != null) {
moveShape(e.getPoint());
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (p0 != null) {
moveShape(e.getPoint());
p0 = null;
shape = null;
}
}
// translates the shape
private void moveShape(Point p1) {
int deltaX = p1.x - p0.x;
int deltaY = p1.y - p0.y;
shape.translate(deltaX, deltaY);
p0 = p1;
repaint();
}
}
private static void createAndShowGui() {
DrawChit mainPanel = new DrawChit();
JFrame frame = new JFrame("Draw Chit");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MyShape {
private Path2D path = new Path2D.Double();
private Color color;
public MyShape(Shape shape, Color color) {
path.append(shape, true);
this.color = color;
}
public boolean contains(Point p) {
return path.contains(p);
}
public void draw(Graphics2D g2) {
g2.setColor(color);
g2.draw(path);
}
public void fill(Graphics2D g2) {
g2.setColor(color);
g2.fill(path);
}
public void translate(int deltaX, int deltaY) {
path.transform(AffineTransform.getTranslateInstance(deltaX, deltaY));
}
}

GUI button placement

I am trying to design a GUI with triangle shaped buttons. I have create the triangle button class correctly in so far as creating a JButton with my class constructor results in a triangle button on the page, but I fall short when it comes to placement of the button.
Could any direct me or have an example for creating a hexagonal shape from triangle buttons?
Here is my TriangleButton class for reference:
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
class TriangleButton extends JButton {
final static double side_len = 52; //Change for variable triangle size
final static double y_offset = (Math.sqrt(3) * side_len / 2);
private Shape triangle;
public TriangleButton(int spot){
triangle = createTriangle(spot);
}
public void paintBorder( Graphics g ) {
((Graphics2D)g).draw(triangle);
}
public void paintComponent( Graphics g ) {
((Graphics2D)g).fill(triangle);
}
public Dimension getPreferredSize() {
return new Dimension((int)side_len, (int)y_offset);
}
public boolean contains(int x, int y) {
return triangle.contains(x, y);
}
private Shape createTriangle(int spot) {
Polygon p = new Polygon();
p.addPoint( 0 , 0 );
p.addPoint( (int)side_len , 0 );
p.addPoint( (int)side_len/2, (int)(y_offset) );
return p;
}
}
The look I had in mind would be something like..
With space between the buttons.. basically just up-pointing and down-pointing triangles lined up.
But anything to put me in the right direction would be appreciated!
As an alternative, due to the complexities of generating a suitable layout to allow components to overlap, you could simply create a single button which housed all the triangles and which provided centralised control, for example
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Path2D;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractButton;
import javax.swing.DefaultButtonModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
HexagonButton btn = new HexagonButton();
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(Arrays.toString(btn.getSelectedObjects()));
System.out.println(e.getActionCommand());
}
});
add(btn);
}
}
public class HexagonButton extends AbstractButton {
public static final String TOP_RIGHT_QUAD = "Top.right";
public static final String TOP_QUAD = "Top";
public static final String TOP_LEFT_QUAD = "Top.left";
public static final String BOTTOM_LEFT_QUAD = "Bottom.left";
public static final String BOTTOM_QUAD = "Bottom";
public static final String BOTTOM_RIGHT_QUAD = "Bottom.right";
private Shape top;
private Shape topRight;
private Shape topLeft;
private Shape bottomLeft;
private Shape bottomRight;
private Shape bottom;
private Map<String, Shape> paths;
private String selectedQuad;
public HexagonButton() {
setModel(new DefaultButtonModel());
createPaths();
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
String previousQuad = selectedQuad;
selectedQuad = null;
for (String quad : paths.keySet()) {
Shape shape = paths.get(quad);
if (shape.contains(e.getPoint())) {
getModel().setPressed(true);
getModel().setArmed(true);
selectedQuad = quad;
if (!selectedQuad.equals(previousQuad)) {
fireActionPerformed(new ActionEvent(HexagonButton.this, ActionEvent.ACTION_PERFORMED, selectedQuad));
}
break;
}
}
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
getModel().setArmed(false);
getModel().setPressed(false);
}
});
}
#Override
public Object[] getSelectedObjects() {
return new Object[]{selectedQuad};
}
#Override
public void invalidate() {
super.invalidate();
createPaths();
}
protected void createPaths() {
topRight = create(0d, -60d);
top = create(-60d, -120d);
topLeft = create(-120d, -180d);
bottomLeft = create(-180d, -240d);
bottom = create(-240d, -300d);
bottomRight = create(-300d, -360d);
paths = new HashMap<>(6);
paths.put(TOP_RIGHT_QUAD, topRight);
paths.put(TOP_QUAD, top);
paths.put(TOP_LEFT_QUAD, topLeft);
paths.put(BOTTOM_LEFT_QUAD, bottomLeft);
paths.put(BOTTOM_QUAD, bottom);
paths.put(BOTTOM_RIGHT_QUAD, bottomRight);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(104, 104);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
Graphics2D g2d = (Graphics2D) g.create();
if (selectedQuad != null) {
Shape path = paths.get(selectedQuad);
g2d.setColor(UIManager.getColor("List.selectionBackground"));
g2d.fill(path);
}
g2d.setColor(getForeground());
g2d.draw(topRight);
g2d.draw(top);
g2d.draw(topLeft);
g2d.draw(bottomLeft);
g2d.draw(bottom);
g2d.draw(bottomRight);
g2d.dispose();
}
public Shape create(double startAngle, double endAngle) {
double width = getWidth();
double height = getHeight();
double radius = Math.min(width, height) / 2;
double xOffset = width - radius;
double yOffset = height - radius;
double startX = xOffset + radius * (Math.cos(Math.toRadians(startAngle)));
double startY = yOffset + radius * (Math.sin(Math.toRadians(startAngle)));
double endX = xOffset + radius * (Math.cos(Math.toRadians(endAngle)));
double endY = yOffset + radius * (Math.sin(Math.toRadians(endAngle)));
Path2D path = new Path2D.Double();
path.moveTo(xOffset, yOffset);
path.lineTo(startX, startY);
path.lineTo(endX, endY);
path.closePath();
return path;
}
}
public static class TriangleButton extends JButton {
final static double side_len = 52; //Change for variable triangle size
final static double y_offset = (Math.sqrt(3) * side_len / 2);
private Shape triangle;
public TriangleButton(int spot) {
triangle = createTriangle(spot);
}
#Override
public void paintBorder(Graphics g) {
super.paintBorder(g);
((Graphics2D) g).draw(triangle);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).fill(triangle);
}
#Override
public Dimension getPreferredSize() {
return new Dimension((int) side_len, (int) y_offset);
}
#Override
public boolean contains(int x, int y) {
return triangle.contains(x, y);
}
private Shape createTriangle(int spot) {
Polygon p = new Polygon();
p.addPoint(0, 0);
p.addPoint((int) side_len, 0);
p.addPoint((int) side_len / 2, (int) (y_offset));
return p;
}
}
}
Using your class I made some changes and came up with the following:
import java.awt.*;
import java.awt.Shape;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class TriangleButton2 extends JButton {
final static double side_len = 52; //Change for variable triangle size
final static double y_offset = (Math.sqrt(3) * side_len / 2);
private Shape triangle;
public TriangleButton2(int degrees){
triangle = createTriangle(degrees);
setRolloverEnabled( false );
setContentAreaFilled( false );
setBorderPainted( false );
}
public void paintBorder( Graphics g ) {
((Graphics2D)g).draw(triangle);
}
public void paintComponent( Graphics g ) {
super.paintComponent(g);
((Graphics2D)g).fill(triangle);
}
public Dimension getPreferredSize() {
return new Dimension((int)side_len, (int)y_offset);
}
public boolean contains(int x, int y) {
return triangle.contains(x, y);
}
private Shape createTriangle(int degrees) {
Polygon p = new Polygon();
p.addPoint( 0 , 0 );
p.addPoint( (int)side_len , 0 );
p.addPoint( (int)side_len/2, (int)(y_offset) );
return ShapeUtils.rotate(p, degrees);
// return p;
}
private static void createAndShowGUI()
{
JPanel panelNorth = new JPanel( new FlowLayout(FlowLayout.CENTER, -22, 2) );
panelNorth.add( new TriangleButton2(180) );
panelNorth.add( new TriangleButton2(0) );
panelNorth.add( new TriangleButton2(180) );
JPanel panelSouth = new JPanel( new FlowLayout(FlowLayout.CENTER, -22, 1) );
panelSouth.add( new TriangleButton2(0) );
panelSouth.add( new TriangleButton2(180) );
panelSouth.add( new TriangleButton2(0) );
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panelNorth, BorderLayout.NORTH);
frame.add(panelSouth, BorderLayout.SOUTH);
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
The above code uses the ShapeUtils class found in Playing With Shapes.
Not sure of the exact functionality you want from the button. Your current implantation doesn't have any visual effects when you click on the button or mouse over the button.
In this case you might want to consider just creating an Icon to represent your triangle. you can use the ShapeIcon class found in Playing With Shapes to create your triangle icons. Then you can use the ShapeComponent class also found in Playing With Shapes to create an actual component that you add to the panel.
The FlowLayout shows how you can overlap the buttons to get your desired layout effect.
Check out this page for some relatable information:
Creating custom JButton from images containing transparent pixels
It just might be easier creating JButtons from triangle images.

Sensing hover over outer edge of a Path2D circle in JPanel [duplicate]

This question already has an answer here:
Collision detection with complex shapes
(1 answer)
Closed 8 years ago.
So, I have a program that draws Path2D circles onto JPanel. What I am trying to do is resize the circle when the user clicks and drags the bottom right of the circle. So, what I want is to detect when they are on the bottom-right outer edge of the circle, not the bottom-right of the bounds around the circle. Basically, I need to figure out how to do something like this:
I know how to do this with rectangles using getBounds() but when you use getBounds() on a circle, it will return the square around the circle and not the bounds of the actual circle. Any ideas on how I can get this to work? Thanks!
Here is a shortened, runnable version of my program:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Editor {
public static void main(String[] args) {
JFrame frame = new UMLWindow();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(30, 30, 1000, 700);
frame.getContentPane().setBackground(Color.white);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class UMLWindow extends JFrame {
Shapes shapeList = new Shapes();
Panel panel;
private static final long serialVersionUID = 1L;
public UMLWindow() {
addMenus();
panel = new Panel();
}
public void addMenus() {
getContentPane().add(shapeList);
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
shapeList.addCircle(100, 100);
}
}
// Shapes class, used to draw the shapes on the panel
// as well as implements the MouseListener for dragging
class Shapes extends JPanel {
private static final long serialVersionUID = 1L;
private List<Path2D> shapes = new ArrayList<Path2D>();
int currentIndex;
public Shapes() {
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
}
public void addCircle(int width, int height) {
Path2D circ = new Path2D.Double();
circ.append(new Ellipse2D.Double(442, 269, width, height), true);
shapes.add(circ);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2));
for (Path2D shape : shapes) {
g2.draw(shape);
}
}
class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
}
}
You'll want to brush up your trig (or google search like I did ;)). The basic concept is "relatively" easy, but I created a nice method to all the work for me...
This method...
public Point2D getPointOnEdge(float angel, Rectangle bounds) {
float radius = Math.max(bounds.width, bounds.height) / 2;
float x = radius;
float y = radius;
double rads = Math.toRadians((angel + 90));
// Calculate the outter point of the line
float xPosy = (float) (x + Math.cos(rads) * radius);
float yPosy = (float) (y + Math.sin(rads) * radius);
return new Point2D.Float(xPosy + bounds.x, yPosy + bounds.y);
}
Will calculate the x/y point that a given angle will appear on a circle, remember, this will ONLY work for circles!
I then use another method...
public Rectangle2D getActiveBounds(float angel, Rectangle bounds) {
Point2D p = getPointOnEdge(angel, bounds);
return new Rectangle2D.Double(p.getX() - 4, p.getY() - 4, 8, 8);
}
To calculate the "mouse zone" in which I would consider to be the bottom/right area, cause a single pixel is hard to find and simply use Rectangle#contains, passing it the current mouse location...
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Editor {
public static void main(String[] args) {
new Editor();
}
public Editor() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new UMLWindow();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(30, 30, 1000, 700);
frame.getContentPane().setBackground(Color.white);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class UMLWindow extends JFrame {
Shapes shapeList = new Shapes();
Panel panel;
private static final long serialVersionUID = 1L;
public UMLWindow() {
addMenus();
panel = new Panel();
}
public void addMenus() {
getContentPane().add(shapeList);
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
shapeList.addCircle(100, 100);
}
}
// Shapes class, used to draw the shapes on the panel
// as well as implements the MouseListener for dragging
public static class Shapes extends JPanel {
private static final long serialVersionUID = 1L;
private List<Path2D> shapes = new ArrayList<Path2D>();
int currentIndex;
private Point mousePoint;
public Shapes() {
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
}
public void addCircle(int width, int height) {
Path2D circ = new Path2D.Double();
circ.append(new Ellipse2D.Double(442, 269, width, height), true);
shapes.add(circ);
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(2));
for (Path2D shape : shapes) {
g2.setColor(Color.BLACK);
g2.draw(shape);
g2.setColor(Color.RED);
Rectangle2D bottomRight = getActiveBounds(-45, shape.getBounds());
g2.draw(bottomRight);
if (mousePoint != null) {
if (bottomRight.contains(mousePoint)) {
g2.fill(bottomRight);
}
}
}
}
public Rectangle2D getActiveBounds(float angel, Rectangle bounds) {
Point2D p = getPointOnEdge(angel, bounds);
return new Rectangle2D.Double(p.getX() - 4, p.getY() - 4, 8, 8);
}
public Point2D getPointOnEdge(float angel, Rectangle bounds) {
float radius = Math.max(bounds.width, bounds.height) / 2;
float x = radius;
float y = radius;
double rads = Math.toRadians((angel + 90));
// Calculate the outter point of the line
float xPosy = (float) (x + Math.cos(rads) * radius);
float yPosy = (float) (y + Math.sin(rads) * radius);
return new Point2D.Float(xPosy + bounds.x, yPosy + bounds.y);
}
class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
mousePoint = e.getPoint();
repaint();
}
}
}
}
This example does all the work within the paint method, because I wanted to see the "area of effect", you can easily use the same logic to change the mouse cursor within the MouseMoitionListener
Not sure if this will work but you can try something like:
Create a Shape circle that is a couple of pixels smaller than your original Shape
Create a Shape circle that is a couple of pixels larger than your original Shape
Create an Area object using the larger Shape
Create an Area object using the smaller Shape and subtract this Area from the larger Area
Use the contains(...) method to determine if the mouse point is within this Area.

Adding a force based on mouse position

I want a point to move towards the mouse position. Currently the point just is the mouse location. But I want it so that the bigger the distance between mouse and center of the screen, the less force get´s added to the point. So if the mouse is enough distance away from the center, the point will just stop moving further outwards because it´s force away from the center is to small. The center should always be the point which is looked at. So no repositioning.
I am really stuck here because I am pretty young and I didn´t have had vector calculation in school (I think this is what you need here). I have no idea how to do what I am trying to archive. The only thing I tried was using the distance between center and mouse (Math.hypot(width / 2 - mouseX , height / 2 - mouseY)). But it didn´t work.
This is my minimal reproducible example:
import javax.swing.*;
import java.awt.*;
public class Example extends JPanel {
private static final int size = 500;
public Example() {
this.setPreferredSize(new Dimension(size, size));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.fillOval(getWidth() / 2 - 3, getHeight() / 2 - 3, 6, 6); // center
Point point = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(point, this);
// Do calculations with the point here
g2d.fillOval(point.x - 5, point.y - 5, 10, 10);
repaint();
}
private static void createFrame() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Example());
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(Example::createFrame);
}
}
It would look like this:
You can declare an attraction ratio value, which will strech the circle to the center of the screen, based on its value.
You need also be able to know for each cursor position how far it is from the center in percentages.
import javax.swing.*;
import java.awt.*;
public class Example extends JPanel {
private static final int SIZE = 500;
private static final int CENTER_CIRCLE_RADIUS = 3;
private static final int CIRCLE_RADIUS = 5;
private static final double ATTRACTION_RATIO = 0.75;
public Example() {
this.setPreferredSize(new Dimension(SIZE, SIZE));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
final int xCenterPoint = getWidth() / 2;
final int yCenterPoint = getHeight() / 2;
g2d.fillOval(xCenterPoint - CENTER_CIRCLE_RADIUS, yCenterPoint - CENTER_CIRCLE_RADIUS,
CENTER_CIRCLE_RADIUS * 2, CENTER_CIRCLE_RADIUS * 2); // center
Point point = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(point, this);
final double xNearToCenter = 1 - ((double) (xCenterPoint - point.x) / xCenterPoint);
final double yNearToCenter = 1 - ((double) (yCenterPoint - point.y) / yCenterPoint);
g2d.fillOval((int) (xCenterPoint * (ATTRACTION_RATIO + xNearToCenter * (1 - ATTRACTION_RATIO))),
(int) (yCenterPoint * (ATTRACTION_RATIO + yNearToCenter * (1 - ATTRACTION_RATIO))),
CIRCLE_RADIUS * 2, CIRCLE_RADIUS * 2);
repaint();
}
private static void createFrame() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Example panel = new Example();
f.add(panel);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(Example::createFrame);
}
}
I modified your code somewhat to create the following GUI.
The circle will follow your mouse around the drawing JPanel.
The first thing I did was create a Circle class. This class holds the center point, radius, and color of the circle. I use a Point2D class to hold the center point so I can move the circle in fractional pixel increments. This makes the animation smoother.
Next, I used your code to create a JFrame and a drawing JPanel. I like to separate the JFrame code from the JPanel code. It makes it easier for me to focus on one Swing component at a time.
The drawing JPanel draws the circle. Period. The controller classes are responsible for calculating the new position of the circle and calling the repaint method of the drawing JPanel.
I created a MouseMotionListener to listen for the mouse movement. This class keeps track of the mouse position.
I created a Swing Timer to animate the motion of the circle.
I used polar geometry to calculate the direction that the circle moves. The polar geometry is in the MoveListener class, the actionPerformed method. I use an arc-tangent to calculate the angle to the mouse position in radians, then take the cosine to get the X movement, and the sine to get the Y movement.
Here's the complete runnable code.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class MouseMoveExample implements Runnable {
public static void main(String[] args) {
EventQueue.invokeLater(new MouseMoveExample());
}
private final int size = 500;
private Circle circle;
private DrawingPanel drawingPanel;
public MouseMoveExample() {
this.circle = new Circle(new Point(size / 2, size / 2), 12,
Color.BLACK);
}
#Override
public void run() {
JFrame f = new JFrame("Mouse Move Example");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.drawingPanel = new DrawingPanel();
f.add(drawingPanel);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
public DrawingPanel() {
this.setBackground(Color.WHITE);
this.setPreferredSize(new Dimension(size, size));
this.addMouseMotionListener(new MoveListener());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(circle.getColor());
Point centerPoint = circle.getCenterPoint();
int radius = circle.getRadius();
int diameter = radius + radius;
g2d.fillOval(centerPoint.x - radius, centerPoint.y - radius,
diameter, diameter);
}
}
public class MoveListener extends MouseAdapter {
private MoveTimer moveTimer;
private Timer timer;
public MoveListener() {
this.moveTimer = new MoveTimer();
this.timer = new Timer(20, moveTimer);
this.timer.start();
}
#Override
public void mouseMoved(MouseEvent event) {
moveTimer.setEventPoint(event.getPoint());
}
}
public class MoveTimer implements ActionListener {
private Point eventPoint;
public void setEventPoint(Point eventPoint) {
this.eventPoint = eventPoint;
}
#Override
public void actionPerformed(ActionEvent event) {
Point centerPoint = circle.getCenterPoint();
if (eventPoint != null) {
double theta = Math.atan2(eventPoint.y - centerPoint.y,
eventPoint.x - centerPoint.x);
int increment = 1;
double x = Math.cos(theta) * increment;
double y = Math.sin(theta) * increment;
circle.incrementCenterPoint(x, y);
drawingPanel.repaint();
}
}
}
public class Circle {
private final int radius;
private final Color color;
private Point2D centerPoint;
public Circle(Point centerPoint, int radius, Color color) {
setCenterPoint(centerPoint);
this.radius = radius;
this.color = color;
}
public Point getCenterPoint() {
return new Point((int) Math.round(centerPoint.getX()),
(int) Math.round(centerPoint.getY()));
}
public void setCenterPoint(Point centerPoint) {
this.centerPoint = new Point2D.Double(
centerPoint.x, centerPoint.y);
}
public void incrementCenterPoint(double x, double y) {
centerPoint.setLocation(centerPoint.getX() + x,
centerPoint.getY() + y);
}
public int getRadius() {
return radius;
}
public Color getColor() {
return color;
}
}
}

Categories