44import org .teachingextensions .logo .Turtle ;
55import org .teachingextensions .logo .Turtle .Animals ;
66import org .teachingextensions .logo .utils .ColorUtils .PenColors ;
7- import org .teachingextensions .logo .utils .LineAndShapeUtils .LineSegment ;
7+ import org .teachingextensions .logo .utils .InterfaceUtils .MultiTurtlePainter ;
8+ import org .teachingextensions .logo .utils .InterfaceUtils .MultiTurtleTrailPainter ;
9+ import org .teachingextensions .logo .utils .LineAndShapeUtils .Paintable ;
810
911import java .awt .*;
10- import java .awt .geom .AffineTransform ;
11- import java .awt .geom .Line2D ;
1212import java .util .ArrayList ;
1313import java .util .List ;
1414
1515/**
1616 * Use this window when you want to put more than one turtle on the same window
1717 */
18- public class MultiTurtleWindow extends TurtlePanel
19- {
20- private List < Turtle > turtles = new ArrayList < Turtle >() ;
21- private Image image ;
22- private Animals animal = Animals . Turtle ;
23- public MultiTurtleWindow ()
24- {
18+ public class MultiTurtleWindow extends TurtlePanel {
19+ private List < Turtle > turtles = new ArrayList < Turtle >();
20+ private Animals animal = Animals . Turtle ;
21+ private Paintable multiTurtlePainter ;
22+ private Paintable multiTurtleTrailPainter ;
23+
24+ public MultiTurtleWindow () {
2525 super ("Turtles, Turtles, Turtles!" );
2626 this .image = loadAnimal ();
27+ this .getWindow ()
28+ .add (this .createTurtlePainter ())
29+ .add (this .createTurtleTrailPainter ())
30+ .setBackground (PenColors .Blues .DarkSlateBlue );
2731 }
32+
2833 /**
2934 * Adds a turtle instance to a window
3035 * NOTE: this method must be called BEFORE calling any other methods on turtle instances
@@ -33,102 +38,50 @@ public MultiTurtleWindow()
3338 * @param turtle
3439 * A turtle instance
3540 */
36- public void addTurtle (Turtle turtle )
37- {
38- if ( turtle == null ) { return ; }
39- this . turtles . add ( turtle );
41+ public void addTurtle (Turtle turtle ) {
42+ if ( turtle == null ) {
43+ return ;
44+ }
4045 turtle .setFrame (this .getWindow ().getFrame ());
4146 turtle .setPanel (this );
47+
48+ this .turtles .add (turtle );
49+ this .getWindow ()
50+ .remove (this .multiTurtlePainter )
51+ .remove (this .multiTurtleTrailPainter )
52+ .add (this .createTurtlePainter ())
53+ .add (this .createTurtleTrailPainter ());
4254 }
43- // @Override
44- // public void paint(Graphics g)
45- // {
46- // // We must call JPanel paint to get the correct behavior on windows...
47- // super.getWindow().paint(g);
48- // Graphics2D g2d = TkpPanel.configureGraphics2D(g);
49- // super.setBackground(PenColors.Blues.DarkSlateBlue);
50- // paintLines(g2d);
51- // paintTurtle(g2d);
52- // g2d.dispose();
53- // }
54- @ Override
55- public synchronized Image getImage ()
56- {
57- return image ;
58- }
59- /**
60- * Sets the Animal type on the window
61- * <p><b>Example:</b> {@code multiTurtlePanel.setAnimal(animal)} </p>
62- *
63- * @see Animals
64- */
65- @ Override
66- public synchronized void setAnimal (Animals animal )
67- {
68- this .animal = animal ;
69- this .image = loadAnimal ();
70- }
71- private Image loadAnimal ()
72- {
55+
56+ private Image loadAnimal () {
7357 return ObjectUtils .loadImage (MultiTurtleWindow .class , this .animal + ".png" );
7458 }
75- private void paintLines (Graphics2D g2d )
76- {
77- // Paint can be called before the constructor finishes when super() shows the window.
78- if (this .turtles == null ) { return ; }
79- for (Turtle turtle : turtles )
80- {
81- paintTrail (g2d , turtle .getTrail ());
82- }
83- }
84- private void paintTrail (Graphics2D g2d , LineSegment [] trail )
85- {
86- for (LineSegment l : trail )
87- {
88- //g2d.setColor(l.getColor());
89- g2d .setColor (PenColors .Yellows .Gold );
90- g2d .setStroke (new BasicStroke (l .getWidth (), BasicStroke .CAP_BUTT , BasicStroke .JOIN_MITER ));
91- g2d .draw (new Line2D .Double (l .getStart ().x , l .getStart ().y , l .getEnd ().x , l .getEnd ().y ));
92- }
59+
60+ private Paintable createTurtleTrailPainter () {
61+ return this .multiTurtleTrailPainter = new MultiTurtleTrailPainter (this .turtles );
9362 }
94- private void paintTurtle (Graphics2D g )
95- {
96- for (Turtle turtle : turtles )
97- {
98- if (turtle .isHidden ())
99- {
100- continue ;
101- }
102- Image image = getImage ();
103- int xCenter = image .getWidth (null ) / 2 ;
104- int yCenter = image .getHeight (null ) / 2 ;
105- int x = turtle .getX () - xCenter ;
106- int y = turtle .getY () - yCenter ;
107- AffineTransform rotate = AffineTransform .getRotateInstance (Math .toRadians (turtle .getHeadingInDegrees ()),
108- xCenter , yCenter );
109- AffineTransform move = AffineTransform .getTranslateInstance (x , y );
110- move .concatenate (rotate );
111- g .drawImage (image , move , null );
112- }
63+
64+ private Paintable createTurtlePainter () {
65+ return this .multiTurtlePainter = new MultiTurtlePainter (this .turtles , this .getImage ());
11366 }
114- public int getTurtleCount ()
115- {
67+
68+ public int getTurtleCount () {
11669 return this .turtles .size ();
11770 }
71+
11872 /**
11973 * Adds a turtle instance to a window and shows it on the window
12074 * <p><b>Example:</b> {@code multiTurtleWindow.addAndShowTurtle(myTurtle)}</p>
12175 *
12276 * @param turtle
12377 * A turtle instance
12478 */
125- public void addAndShowTurtle (Turtle turtle )
126- {
79+ public void addAndShowTurtle (Turtle turtle ) {
12780 this .addTurtle (turtle );
12881 this .showTurtle (turtle );
12982 }
130- private void showTurtle ( Turtle turtle )
131- {
83+
84+ private void showTurtle ( Turtle turtle ) {
13285 turtle .show ();
13386 }
13487}
0 commit comments