Related
So, if I try to move the shape, it actually moves, but there is no motion animation. In order for the moved shape to be drawn, the application window must be minimized or maximized.
Here is the PentaminoShape class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
public class PentominoShape extends JFrame implements MouseListener, MouseMotionListener {
JPanel shapePane;
Container contentPane;
private Polygon currPolygon;
private int x, y;
ArrayList<Polygon> polygons = new ArrayList<Polygon>();
JFrame frame;
public PentominoShape(JFrame frame){
this.frame = frame;
initShape();
}
private void initShape() {
Polygon fig1 = new Polygon(new int[]{10, 50, 50, 10}, new int[]{10, 10, 200, 200}, 4);
Polygon fig2 = new Polygon(new int[]{130, 210, 210, 170, 170, 130, 130, 90, 90, 130}, new int[]{80, 80, 120, 120, 200, 200, 160, 160, 120, 120}, 10);
Polygon fig3 = new Polygon(new int[]{290, 330, 330, 250, 250, 290}, new int[]{50, 50, 200, 200, 160, 160}, 6);
Polygon fig4 = new Polygon(new int[]{10, 90, 90, 50, 50, 10}, new int[]{280, 280, 400, 400, 360, 360}, 6);
Polygon fig5 = new Polygon(new int[]{170, 210, 210, 170, 170, 130, 130, 170}, new int[]{240, 240, 360, 360, 400, 400, 320, 320}, 8);
Polygon fig6 = new Polygon(new int[]{250, 370, 370, 330, 330, 290, 290, 250}, new int[]{280, 280, 320, 320, 400, 400, 320, 320}, 8);
Polygon fig7 = new Polygon(new int[]{10, 50, 50, 90, 90, 130, 130, 10}, new int[]{480, 480, 520, 520, 480, 480, 560, 560}, 8);
Polygon fig8 = new Polygon(new int[]{170, 250, 250, 290, 290, 170}, new int[]{520, 520, 440, 440, 560, 560}, 6);
Polygon fig9 = new Polygon(new int[]{330, 370, 370, 410, 410, 450, 450, 410, 410, 330}, new int[]{520, 520, 480, 480, 440, 440, 520, 520, 560, 560}, 10);
Polygon fig10 = new Polygon(new int[]{10, 50, 50, 90, 90, 130, 130, 90, 90, 50, 50, 10}, new int[]{680, 680, 640, 640, 680, 680, 720, 720, 760, 760, 720, 720}, 12);
Polygon fig11 = new Polygon(new int[]{170, 210, 210, 250, 250, 210, 210, 170}, new int[]{640, 640, 600, 600, 760, 760, 680, 680}, 8);
Polygon fig12 = new Polygon(new int[]{330, 410, 410, 370, 370, 290, 290, 330}, new int[]{640, 640, 680, 680, 760, 760, 720, 720}, 8);
polygons.add(fig1);
polygons.add(fig2);
polygons.add(fig3);
polygons.add(fig4);
polygons.add(fig5);
polygons.add(fig6);
polygons.add(fig7);
polygons.add(fig8);
polygons.add(fig9);
polygons.add(fig10);
polygons.add(fig11);
polygons.add(fig12);
Color[] c = new Color[12];
c[0] = new Color(25, 165, 25);
c[1] = new Color(255, 165, 25);
c[2] = new Color(255, 50, 50);
c[3] = new Color(150, 45, 90);
c[4] = new Color(25, 165, 150);
c[5] = new Color(25, 165, 255);
c[6] = new Color(255, 40, 190);
c[7] = new Color(180, 90, 60);
c[8] = new Color(90, 80, 70);
c[9] = new Color(70, 80, 90);
c[10] = new Color(150, 30, 20);
c[11] = new Color(80, 80, 80);
shapePane = new JPanel(){
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(c[0]); g2.fill(fig1);
g2.setColor(c[1]); g2.fill(fig2);
g2.setColor(c[2]); g2.fill(fig3);
g2.setColor(c[3]); g2.fill(fig4);
g2.setColor(c[4]); g2.fill(fig5);
g2.setColor(c[5]); g2.fill(fig6);
g2.setColor(c[6]); g2.fill(fig7);
g2.setColor(c[7]); g2.fill(fig8);
g2.setColor(c[8]); g2.fill(fig9);
g2.setColor(c[9]); g2.fill(fig10);
g2.setColor(c[10]); g2.fill(fig11);
g2.setColor(c[11]); g2.fill(fig12);
}
};
/*contentPane = this.getContentPane();
contentPane.add(shapePane);
this.pack();*/
frame.add(shapePane);
shapePane.addMouseListener(this);
shapePane.addMouseMotionListener(this);
/*shapePane.addMouseListener(this);
shapePane.addMouseMotionListener(this);*/
}
public void mousePressed(MouseEvent e) {
for(Polygon polygon: polygons) {
if (polygon.contains(e.getPoint())) {
System.out.println("Pressed");
currPolygon = polygon;
x = e.getX();
y = e.getY();
}
}
}
public void mouseDragged(MouseEvent e) {
try {
if (currPolygon.contains(x, y)) {
System.out.println("Dragged");
int dx = e.getX() - x;
int dy = e.getY() - y;
currPolygon.translate(dx, dy);
x += dx;
y += dy;
repaint();
}
}catch (NullPointerException ex){
}
}
public void mouseReleased(MouseEvent e){
currPolygon = null;
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseMoved(MouseEvent e){}
}
And the main Pentamino class:
import javax.swing.*;
public class Pentomino extends JFrame {
JFrame frame;
PentominoShape shape;
PentominoPanel panel;
public Pentomino(){
initUI();
}
private void initUI(){
frame = new JFrame("Пентамино");
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setSize(1500, 900);
setResizable(false);
shape = new PentominoShape(frame);
panel = new PentominoPanel(frame);
/*frame.add(shape);
frame.add(panel);*/
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
Pentomino game = new Pentomino();
}
}
I'm new to Java and I don't understand how to solve this problem. Tried searching the internet for a similar problem but couldn't find anything.
Your bug is here:
public void mouseDragged(MouseEvent e) {
try {
if (currPolygon.contains(x, y)) {
System.out.println("Dragged");
int dx = e.getX() - x;
int dy = e.getY() - y;
currPolygon.translate(dx, dy);
x += dx;
y += dy;
repaint(); // ***** here ****
}
}catch (NullPointerException ex){
}
}
You're calling repaint() on the enclosing class, a JFrame, one that is never displayed, and this will have not have the effect desired.
In fact, ask yourself, why this...
public class PentominoShape extends JFrame // ...
Why is PentominoShape extending JFrame at all, when it isn't behaving as a JFrame, when it shouldn't be behaving as a JFrame?
Instead, call repaint on the JPanel that holds the shapes, the shapePane JPanel, and yes, get rid of catching the NullPointerException. That should never be in your code:
public void mouseDragged(MouseEvent e) {
if (currPolygon == null) {
return;
}
if (currPolygon.contains(x, y)) {
System.out.println("Dragged");
int dx = e.getX() - x;
int dy = e.getY() - y;
currPolygon.translate(dx, dy);
x += dx;
y += dy;
shapePane.repaint(); // now we're repainting the correct JPanel!
}
}
Side note: I'd clean things up a bit including
Not having any class extend JFrame if possible
Create my own polygon type of class:
public class PentominoShape2 {
private Polygon polygon;
private Color color;
public PentominoShape2(Polygon polygon, Color color) {
this.polygon = polygon;
this.color = color;
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(color);
g2.fill(polygon);
}
public Polygon getPolygon() {
return polygon;
}
public Color getColor() {
return color;
}
public boolean contains(Point p) {
return polygon.contains(p);
}
}
and then in the drawing JPanel
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (PentominoShape2 poly : polys) {
poly.draw(g);
}
}
same for the mouse listener
I have this code:
import javax.swing.*;
import java.awt.*;
public class Test {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 300, 300);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
class MyCanvas extends JComponent {
public void paint(Graphics g) {
g.drawRect (10, 10, 100, 100);
Polygon triangle = new Polygon(new int[] {100, 150, 200}, new int[] {200, 100, 200}, 3);
g.drawPolygon(triangle);
}
}
It draws this:
I want to scale only Triangle, so it becomes thrice is big:
I understand that I need to use AffiniteTransform, but I don't understand how.
I only know that I need the scaling instance:
AffineTransform at = AffineTransform.getScaleInstance(3, 3);
All answers I've seen were very confusing or just used g2d.setTransform(at) which doesn't seem to be what I need, seeing as the square is supposed to stay the same size.
EDIT: And how do I scale a Triagle, while keeping its leftmost coordinate at the same location? (leftmost (x,y) stays the same)
New code:
public class Test {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 300, 300);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
class MyCanvas extends JComponent {
public void paint(Graphics g) {
g.drawRect (10, 10, 100, 100);
Polygon triangle = new Polygon(new int[] {100, 150, 200}, new int[] {200, 100, 200}, 3);
AffineTransform at = AffineTransform.getScaleInstance(1.5, 1.5);
((Graphics2D) g).setTransform(at);
g.drawPolygon(triangle);
((Graphics2D) g).setTransform(AffineTransform.getScaleInstance(1,1));
validate();
}
}
gives this:
The triangle shifts as it gets scaled.
Is it possible to keep the triangle at the same spot - that is to keep its leftmost bottom corner at the same spot?
The graphics should repaint with a new color after a mouse click, but they don´t.
I´ve already implemented the MouseListener in the component and in the frame, but in both versions it did´nt work.
The Frame and MouseListener:
public class frame extends Frame
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
String string = new String("1 2 3 4 5 6 7");
final int FRAME_WIDTH = 527;
final int FRAME_HEIGHT = 77;
frame.setAlwaysOnTop(true);
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Praxis");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
// JFrame zentriert positionieren; selbst berechnet:
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getScreenSize();
frame.setLocation((int) ((d.width)-700), (int) (0));
Font font = new Font("Jokerman", Font.BOLD, 35);
JLabel textLabel = new JLabel(string);
textLabel.setFont(font);
test component = new test();
frame.add(component);
MouseListener listen = new MouseListener()
{
public void mouseClicked(MouseEvent e) {
GlobalVar obj = new GlobalVar();
obj.fillColor1 = obj.farben[1];
component.repaint();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
};
component.addMouseListener(listen);
frame.setVisible(true);
}
}
The File where they get the Color from:
public class GlobalVar{
public static final Color[] farben = new Color[4];{
farben[0] = Color.LIGHT_GRAY;
farben[1] = Color.RED;
farben[2] = Color.GREEN;
farben[3] = Color.PINK;
}
Color fillColor1 = farben[0];
Color fillColor2 = farben[0];
Color fillColor3 = farben[0];
Color fillColor4 = farben[0];
Color fillColor5 = farben[0];
Color fillColor6 = farben[0];
Color fillColor7 = farben[0];
}
The Component which draws the graphics:
public class test extends JComponent
{
GlobalVar obj = new GlobalVar();
#Override
public void paintComponent(Graphics g)
{
if(g instanceof Graphics2D) {
// Recover Graphics2D
Graphics2D g2 = (Graphics2D) g;
// Construct a rectangle and draw it
Rectangle box1 = new Rectangle(2, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box1);
g2.setColor(obj.fillColor1);
g2.fill(box1);
Rectangle box2 = new Rectangle(77, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box2);
g2.setColor(obj.fillColor2);
g2.fill(box2);
Rectangle box3 = new Rectangle(152, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box3);
g2.setColor(obj.fillColor3);
g2.fill(box3);
Rectangle box4 = new Rectangle(227, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box4);
g2.setColor(obj.fillColor4);
g2.fill(box4);
Rectangle box5 = new Rectangle(302, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box5);
g2.setColor(obj.fillColor5);
g2.fill(box5);
Rectangle box6 = new Rectangle(377, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box6);
g2.setColor(obj.fillColor6);
g2.fill(box6);
Rectangle box7 = new Rectangle(452, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box7);
g2.setColor(obj.fillColor7);
g2.fill(box7);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Font f = new Font("Dialog", Font.PLAIN, 30);
g2.setFont(f);
g2.setColor(Color.BLACK);
g2.drawString("1", 30, 48);
g2.drawString("2", 105, 48);
g2.drawString("3", 180, 48);
g2.drawString("4", 255, 48);
g2.drawString("5", 330, 48);
g2.drawString("6", 405, 48);
g2.drawString("7", 480, 48);
}
}
private Color fillColor1;
private Color fillColor2;
private Color fillColor3;
private Color fillColor4;
private Color fillColor5;
private Color fillColor6;
private Color fillColor7;
}
As I said, I expected the graphics to repaint with the first square to be filled with the color red, but the actual result is, that nothing happens when I click on the frame.
Instead of having the test class extending JComponent, I would make it into a JPanel and then put the JPanel on top of the JFrame.
Then I would remove the mouselistener from the JFrame and add it onto the JPanel, by doing this the only command needed to repaint is repaint();.
I believe that this way is more simple and more organized than what you are currently doing.
This should do the trick (note: I made this in netbeans, that is why there is some autogenerated code.):
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
public class Test extends javax.swing.JPanel {
/**
* Creates new form Test
*/
public Test() {
initComponents();
}
GlobalVar obj = new GlobalVar();
#Override
public void paintComponent(Graphics g)
{
if(g instanceof Graphics2D) {
// Recover Graphics2D
Graphics2D g2 = (Graphics2D) g;
// Construct a rectangle and draw it
Rectangle box1 = new Rectangle(2, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box1);
g2.setColor(obj.fillColor1);
g2.fill(box1);
Rectangle box2 = new Rectangle(77, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box2);
g2.setColor(obj.fillColor2);
g2.fill(box2);
Rectangle box3 = new Rectangle(152, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box3);
g2.setColor(obj.fillColor3);
g2.fill(box3);
Rectangle box4 = new Rectangle(227, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box4);
g2.setColor(obj.fillColor4);
g2.fill(box4);
Rectangle box5 = new Rectangle(302, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box5);
g2.setColor(obj.fillColor5);
g2.fill(box5);
Rectangle box6 = new Rectangle(377, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box6);
g2.setColor(obj.fillColor6);
g2.fill(box6);
Rectangle box7 = new Rectangle(452, 2, 71, 71);
g2.setColor(Color.BLACK);
g2.draw(box7);
g2.setColor(obj.fillColor7);
g2.fill(box7);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Font f = new Font("Dialog", Font.PLAIN, 30);
g2.setFont(f);
g2.setColor(Color.BLACK);
g2.drawString("1", 30, 48);
g2.drawString("2", 105, 48);
g2.drawString("3", 180, 48);
g2.drawString("4", 255, 48);
g2.drawString("5", 330, 48);
g2.drawString("6", 405, 48);
g2.drawString("7", 480, 48);
}
}
private Color fillColor1;
private Color fillColor2;
private Color fillColor3;
private Color fillColor4;
private Color fillColor5;
private Color fillColor6;
private Color fillColor7;
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
formMouseClicked(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>
private void formMouseClicked(java.awt.event.MouseEvent evt) {
GlobalVar obj = new GlobalVar();
obj.fillColor1 = obj.farben[1];
repaint();
// TODO add your handling code here:
}
// Variables declaration - do not modify
// End of variables declaration
}
I am creating a Towers of Hanoi game and have sucedded in printing the shapes with a time delay (that part of the code has been removed while I try to get all the ovals where they are supposed to be) I am wondering how I would go about removing the circle. As you can see I have tried the clearRect(); method but that doesn't work. Is there a way I can set if the method is visible on JPanel since each circle has its own method? I think that would be the easiest way but if anyone has a better idea go for it! Thanks for any help and I have attached my code
package towersofhanoi;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.Object;
/*g.fillOval(60 = horizontal distance , 540= vertical distance, 400 = width, 60 = height) */
public class TowersOfHanoi extends JPanel {
private int clock = 0;
private Color circles = new Color(176, 56, 251);
public static void main(String[] args) {
// Print the shapes and frame
TowersOfHanoi drawRectangle = new TowersOfHanoi();
JFrame frame = new JFrame("Towers of Hanoi");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(drawRectangle);
frame.setSize(1250, 800);
frame.setVisible(true);
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
drawRectangle.nextFrame();
drawRectangle.repaint();
}
});
timer.setRepeats(true);
timer.start();
}
public void nextFrame() {
clock++;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
frame1(g);
frame2(g);
frame3(g);
frame4(g);
frame5(g);
frame6(g);
frame7(g);
frame8(g);
frame9(g);
}
private Color frame1(Graphics g) {
Color pegs = new Color(251, 129, 56);
g.setColor(pegs);
// peg 1
g.fillRect(250, 300, 25, 450);
// peg 2
g.fillRect(600, 300, 25, 450);
// peg 3
g.fillRect(950, 300, 25, 450);
// bottom
g.fillRect(200, 700, 825, 50);
// create a color for circles
// cirle 7 (Labeled from bottom to top)
g.setColor(circles);
g.fillOval(60, 640, 400, 60);
g.setColor(Color.BLACK);
g.drawOval(60, 640, 400, 60);
return circles;
}
private void frame2(Graphics g) {
// circle 6
g.setColor(circles);
g.fillOval(85, 580, 350, 60);
g.setColor(Color.BLACK);
g.drawOval(85, 580, 350, 60);
}
private void frame3(Graphics g) {
// circle 5
g.setColor(circles);
g.fillOval(110, 520, 300, 60);
g.setColor(Color.BLACK);
g.drawOval(110, 520, 300, 60);
}
private void frame4(Graphics g) {
// circle 4
g.setColor(circles);
g.fillOval(135, 465, 250, 55);
g.setColor(Color.BLACK);
g.drawOval(135, 465, 250, 55);
}
private void frame5(Graphics g) {
// circle 3
g.setColor(circles);
g.fillOval(160, 420, 200, 45);
g.setColor(Color.BLACK);
g.drawOval(160, 420, 200, 45);
}
private void frame6(Graphics g) {
// circle 2
g.setColor(circles);
g.fillOval(185, 380, 150, 40);
g.setColor(Color.BLACK);
g.drawOval(185, 380, 150, 40);
}
private void frame7(Graphics g) {
// circle 1
g.setColor(circles);
g.fillOval(210, 345, 100, 35);
g.setColor(Color.BLACK);
g.drawOval(210, 345, 100, 35);
}
public void frame8(Graphics g) {
g.clearRect(210, 345, 100, 35);
g.setColor(circles);
g.fillOval(560, 665, 100, 35);
g.setColor(Color.BLACK);
g.drawOval(560, 665, 100, 35);
}
public void frame9(Graphics g) {
g.clearRect(185, 380, 150, 40);
g.setColor(circles);
g.fillOval(890, 660, 150, 40);
g.setColor(Color.BLACK);
g.drawOval(890, 660, 150, 40);
}
}
I am wondering how I would go about removing the circle.
The super.paintComponent(...) will clear the painting on the panel so that is all the is needed.
As you can see I have tried the clearRect();
It is not needed (see my comment above), but then you invoke the fillOval(...) and drawOval(...) methods again so the painting is redone. So the code is doing exactly as you asked it to do.
Is there a way I can set if the method is visible on JPanel
You need a Boolean indicator telling the paint method what to do. Something like:
if (paintOval1)
frame1(g);
if (paintOval2)
frame2(g);
Of course that is approach is very brute force and not a very good approach if for say you have 100 circles to paint. The code become too big.
So, instead you should create a custom class that contains four properties (x, y, width, height, isPainted). Then you create an instance of this class for each circle and add the class to an ArrayList. Something like:
ArrayList<CustomClass> circles = new ArrayList<CustomClass>();
circles.add( new CustomClass(60, 640, 400, 60, true) );
circles.add( new CustomClass(85, 580, 350, 60, true) );
Then in the paintCompnent() method your code becomes simpler:
for (CustomClass circle: circles.get)
{
if (circle.isPainted())
{
g.setColor(...);
g.fillOval(circle.getX(), circle,getY(), circle.getWidth(), circle.getHeight());
...
}
}
Finally you would need a method to change the state of painting a circle. Something like:
pubic void setCirclePainted(int circle, Boolean isPainted)
{
CustomClass circle = circles.get(circle);
circle.setPainted( isPainted );
}
So the key for you is to create your "CustomClass" and give it a proper name. Then you need to implement all the getter/setter methods of the class so you can access the properties of the class.
I actually found that the easiest way for me to understand and do was to use else and else if statements to display the shape based on time. Thanks for the other suggestions though!
public void paintComponent(Graphics g) {
super.paintComponent(g);
frame1(g);
frame2(g);
frame3(g);
frame4(g);
if (clock<= 5) {
frame5(g);
}
else if(clock >= 6) {
frame9(g);
}
frame6(g);
frame7(g);
frame8(g);
}
I have a 2d graph with an x and y axis and im trying to rotate a shape (series of points) around an axis. This rotation will need to include a scale function.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import javax.swing.*;
import java.lang.reflect.Array;
public class test extends JPanel implements ActionListener {
int[] p1x = {200, 200, 240, 240, 220, 220, 200};
int[] p1y = {200, 260, 260, 240, 240, 200, 200};
int[] p2x = {600, 600, 620, 620, 640, 640, 660, 660, 600};
int[] p2y = {400, 420, 420, 460, 460, 420, 420, 400, 400};
int[] p3x = {400, 400, 460, 460, 440, 440, 420, 420, 400};
int[] p3y = {400, 460, 460, 400, 400, 440, 440, 400, 400};
int delay = 1000;
int dx = 0;
int dy = 5;
int steps = 121;
Polygon t;
Timer tim = new Timer(delay, this);
public void actionPerformed(ActionEvent event) {
for (int i = 0; i < Array.getLength(p2x); i++) {
//p2x[i] = (int) (p2x[i]*Math.cos(Math.toRadians(1))- p2y[i]*Math.sin(Math.toRadians(1)));
//p2y[i] = (int) (p2x[i]*Math.sin(Math.toRadians(1))+ p2y[i]*Math.cos(Math.toRadians(1)));;
Point2D original = new Point2D.Double(p2x[i], p2y[i]);
AffineTransform at = new AffineTransform();
//at.setToRotation(.02, 250, 250);
at.scale(1, -1);
Point2D rotated = at.transform(original, null);
p2x[i] = (int) rotated.getX();
p2y[i] = (int) rotated.getY();
}
repaint();
if (--steps == 0) {
tim.stop();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.white);
g.drawLine(this.getWidth() / 2, 0, this.getWidth() / 2, this.getWidth());
g.drawLine(0, this.getHeight() / 2, this.getHeight(), this.getHeight() / 2);
Polygon t = new Polygon(p2x, p2y, 9);
g.drawPolygon(t);
Letters u = new Letters(p3x, p3y, 9);
u.draw(g);
Letters l = new Letters(p1x, p1y, 7);
l.draw(g);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Drawing line and a moving polygon");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test sl = new test();
frame.getContentPane().add(sl);
frame.setSize(700, 700);
frame.setVisible(true);
sl.tim.start();
}
}
Absent a clear question, a simple animation using your coordinate arrays is shown below. In general you can transform the graphics context (g2d) or the polygonal Shape itself (p3); the example shows both. Resize the window to see the effect of each.
Note the last-specified-first-applied order of the transformations in at. First, a suitable point on p3 is translated to the origin, then p3 is scaled, and then p3 is translated to the center of the panel. The + 10 fudge factor applied to p3 is an artifact of having no symmetric rotation point. It may be easier to define your polygons relative to the origin, as shown in this example.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;
/** #see http://stackoverflow.com/questions/3405799 */
public class AffineTest extends JPanel implements ActionListener {
private static final double DELTA_THETA = Math.PI / 45; // 4°
private static final double DELTA_SCALE = 0.1;
private int[] p1x = {200, 200, 240, 240, 220, 220, 200};
private int[] p1y = {200, 260, 260, 240, 240, 200, 200};
private int[] p2x = {600, 600, 620, 620, 640, 640, 660, 660, 600};
private int[] p2y = {400, 420, 420, 460, 460, 420, 420, 400, 400};
private int[] p3x = {400, 400, 460, 460, 440, 440, 420, 420, 400};
private int[] p3y = {400, 460, 460, 400, 400, 440, 440, 400, 400};
private Polygon p1 = new Polygon(p1x, p1y, p1x.length);
private Polygon p2 = new Polygon(p2x, p2y, p2x.length);
private Polygon p3 = new Polygon(p3x, p3y, p3x.length);
private AffineTransform at = new AffineTransform();
private double dt = DELTA_THETA;
private double theta;
private double ds = DELTA_SCALE;
private double scale = 1;
private Timer timer = new Timer(100, this);
public AffineTest() {
this.setPreferredSize(new Dimension(700, 700));
this.setBackground(Color.white);
p1.translate(-50, +100);
p2.translate(-100, -100);
}
#Override
public void actionPerformed(ActionEvent event) {
theta += dt;
scale += ds;
if (scale < .5 || scale > 4) {
ds = -ds;
}
repaint();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = this.getWidth();
int h = this.getHeight();
g2d.drawLine(w / 2, 0, w / 2, h);
g2d.drawLine(0, h / 2, w, h / 2);
g2d.rotate(theta, w / 2, h / 2);
g2d.drawPolygon(p1);
g2d.drawPolygon(p2);
at.setToIdentity();
at.translate(w / 2, h / 2);
at.scale(scale, scale);
at.translate(-p3x[5] + 10, -p3y[5]);
g2d.setPaint(Color.blue);
g2d.fill(at.createTransformedShape(p3));
}
public void start() {
timer.start();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Affine Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AffineTest sl = new AffineTest();
frame.add(sl);
frame.pack();
frame.setVisible(true);
sl.start();
}
}