1   package fi.jyu.mit.graphics;
2   
3   import java.awt.*;
4   import java.awt.event.WindowAdapter;
5   import java.awt.event.WindowEvent;
6   
7   import javax.swing.JFrame;
8   
9   /**
10   * Window-luokka, ikkuna joka näyttää avaruudet.
11   * Ikkunaan voi lisätä kuvioita, esimerkiksi:
12   * esimerkiksi:
13   * <pre>
14   *      window.add(new Line(0, 0, 1, 1)).setColor(255, 255, 0);
15   * </pre> 
16   * Ikkunaa voi skaalata, kiertää ja liikuttaa, esimerkiksi:
17   * <pre>
18   *      window.scale(-2.5, -2.2, 2.1, 2.7);
19   *      window.rotate(Axis.X, 45.2);
20   *      window.move(0, 1.5, -15);
21   * </pre>
22   * @author Markus Kivioja
23   */
24  public class Window extends JFrame  implements Transformable {
25  
26      private static final long serialVersionUID = 1L;
27      private SpacePanel panel;
28      private ControllerFrame touchPad, controlButtons;
29      
30      /**
31       * Luo uuden ikkunan jonka korkeus on 500 ja leveys 500
32       *
33       */
34      public Window() {
35          this(500, 500);
36      }
37      
38      /**
39       * Luo uuden ikkunan
40       * @param width leveys
41       * @param height korkeus
42       */
43      public Window(int width, int height) {
44          super();
45          this.setSize(width, height);
46          initialize();
47          setBackground(Color.WHITE);
48      }
49      
50      /**
51       * Alustaa uuden ikkunan asetukset
52       */
53      private void initialize() {
54          Container contentPane = this.getContentPane();
55          contentPane.setLayout(new BorderLayout());
56          panel = new SpacePanel();
57          panel.setSize(getWidth(), getHeight());
58          contentPane.add(panel);
59          addWindowListener(new CloseWindow());
60      }
61      
62      /**
63       * Skaalaa ikkunan sisällön annettujen reuna-arvojen mukaisesti, 
64       * esimerkiksi:
65       * <pre>
66       *     window.scale(-2.5, -2.2, 2.1, 2.7);
67       * </pre>
68       * @param left sisällön x-koordinaatin arvo ikkunan vasemmassa reunassa
69       * @param bottom sisällön y-koordinaatin arvo ikkunan alareunassa 
70       * @param right sisällön x-koordinaatin arvo ikkunan oikeassa reunassa
71       * @param top sisällön y-koordinaatin arvo ikkunan yläreunassa
72       */
73      public void scale(double left, double bottom, double right, double top) {
74          panel.scale(left, bottom, right, top);
75          redraw();
76      }
77      
78      /**
79       * Kiertää ikkunan sisältöä annetun akselin ympäri, esimerkiksi:
80       * <pre>
81       *     window.rotate(Axis.X, 45.2);
82       * </pre>
83       * @param axis akseli jonka ympäri pyöritetään (Axis.X/Axis.Y/Axis.Z)
84       * @param deg kierrettävän kulman suuruus asteina
85       */
86      public void rotate(int axis, double deg) {
87          panel.rotate(axis, deg);
88      }
89      
90      /**
91       * Liikuttaa ikkunan sisältöä, esimerkiksi:
92       * <pre>
93       *     window.move(0, 1.5, -15);
94       * </pre>
95       * @param dx liikutettava matka x-akselin suunnassa
96       * @param dy liikutettava matka y-akselin suunnassa
97       * @param dz liikutettava matka z-akselin suunnassa
98       */
99      public void move(double dx, double dy, double dz) {
100         panel.move(dx, dy, dz);
101     }
102     
103     /**
104      * Skaalaa ikkunan sisällön annettujen kertoimien mukaan
105      * <pre>
106      *      window.scale(2, 1, 1); venyttää kuviot kaksinkertaiseksi x-suunnassa
107      * </pre>
108      * @param sx sisällön x-suuntainen kerroin
109      * @param sy sisällön y-suuntainen kerroin
110      * @param sz sisällön z-suuntainen kerroin
111      */
112     public void scale(double sx, double sy, double sz) {
113         panel.scale(sx, sy, sz);
114     }
115     
116     @Override
117     public Transformable transform(Matrix m) {
118         panel.transform(m);
119         return this;
120     }
121     
122     /**
123      * Asettaa ikkunan uudeksi muunnosmatriisiksi annetun matriisin
124      * @param m uusi muunnosmatriisi
125      */
126     public void setTransform(Matrix m) {
127         panel.setTransform(m);
128     }
129     
130     @Override
131     public void setRotator(Matrix m) {
132         panel.setRotator(m);
133     }
134     
135     @Override
136     public Matrix getRotator() {
137         return panel.getRotator();
138     }
139     
140     /**
141      * Asettaa ikkunan näyttämään annettua avaruutta
142      * @param space näytettävä avaruus
143      */
144     public void setSpace(Space space) {
145         panel.setSpace(space);
146     }
147     
148     /**
149      * Lisää ikkunaan kuvion joka on Drawable-olio ja palauttaa sen,
150      * esimerkiksi:
151      * <pre>
152      *      window.add(new Line(0, 0, 1, 1)).setColor(255, 255, 0);
153      * </pre>
154      * @param shape lisättävä kuvio
155      * @return lisätty kuvio
156      */
157     public Drawable add(Drawable shape) {
158         return panel.add(shape);
159     }
160 
161     /**
162      * Antaa Drawable-olion joka muodostuu kaikista 
163      * tämän ikkunan näyttämistä kuvioista
164      * @return kokoelma tämän ikkunan näyttämistä kuvioista
165      */
166     public Drawable getSavedPath() {
167         return panel.getSavedPath();
168     }
169     
170     /**
171      * Antaa ikkunan kokonaismuunnosmatriisin
172      * @return ikkunan kokonaismuunnosmatriisi
173      */
174     public Matrix getFullTransform() {
175         return panel.getFullTransform();
176     }
177     
178     /**
179      * Poistaa ikkunasta kuvion joka on Drawable-olio
180      * @param shape poistettava kuvio
181      */
182     public void remove(Drawable shape) {
183         panel.remove(shape);
184     }
185     
186     /**
187      * Poistaa ikkunasta kaikki kuviot
188      *
189      */
190     public void clear() {
191         panel.removeAll();
192     }
193     
194     /**
195      * Piirtää ikkunan sisällön uudelleen
196      */
197     public void redraw() {
198         repaint();
199     }
200     
201     /**
202      * Tuo ikkunan näkyville näyttöön
203      */
204     public void showWindow() {
205         this.setVisible(true);
206     }
207     
208     /**
209      * Asettaa isotrooppisuuden päälle/pois
210      * @param isotrophic isotrooppisuus tosi/epätosi
211      */
212     public void setIsotrophic(boolean isotrophic) {
213         panel.setIsotrophic(isotrophic);
214     }
215     
216     /**
217      * Lisää ikkunaan ruudun jonka avulla voi pyörittää
218      * ikkunan sisältöä liikuttamalla hiirtä ruudun sisässä
219      * @param touchPadOn ruutu näkyvillä tosi/epätosi
220      * @param move tuleeko hiiren napin olla pohjassa tosi/epätosi
221      */
222     public void setTouchPad(boolean touchPadOn, boolean move) {
223         if (touchPadOn) {
224             if ( touchPad == null ) 
225                 touchPad = new ControllerFrame(new TouchPad(panel, move),0,350,150,150);
226             touchPad.showController();
227         }
228         else {
229             if (touchPad != null) touchPad.hideController();
230         }
231     }
232     
233     /**
234      * Lisää ikkunaan ruudun jonka avulla voi pyörittää
235      * ikkunan sisältöä liikuttamalla hiirtä ruudun sisässä
236      * siten, että hiiren nappia ei paineta
237      * @param touchPadOn ruutu näkyvillä tosi/epätosi
238      */
239     public void setTouchPad(boolean touchPadOn) {
240         this.setTouchPad(touchPadOn, false);
241     }
242     
243     /**
244      * Lisää ikkunaan jokaiselle akselille kiertopainikkeet joilla
245      * ikkunan sisältöä voi kiertää vastaavien akselien ympäri
246      * @param controlButtonsOn painikkeet näkyvillä tosi/epätosi
247      */
248     public void setControlButtons(boolean controlButtonsOn) {
249         if (controlButtonsOn) {
250             if ( controlButtons == null ) 
251                 controlButtons = new ControllerFrame(new ControlButtons(panel),150,350,150,150);
252             controlButtons.showController();
253         }
254         else {
255             if (controlButtons != null) controlButtons.hideController();
256         }
257     }
258     
259     /**
260      * Palauttaa tämän ikkunan sisältämän paneelin johon
261      * kuviot piirretään
262      * @return tämän ikkunan paneeli
263      */
264     public SpacePanel getPanel() {
265         return panel;
266     }
267     
268     /**
269      * Luokka ikkunan sulkemiseen
270      */
271     protected class CloseWindow extends WindowAdapter {
272 
273         /**
274          * Käsittelijä ikkunan sulkemiselle.
275          * @param event ei käytössä
276          */
277         @Override
278         public void windowClosing(WindowEvent event) {
279             
280             System.exit(0); // NOPMD EI ole J2EE ohjelma
281         }
282     }
283 
284     /**
285      * Vaihtaa ikkunan muunnosmatriisin annetuksi matriisiksi
286      * @param m uusi muunnosmatriisi
287      */
288     @Override
289     public void changeTransform(Matrix m) {
290         panel.changeTransform(m);   
291     }
292 
293     /**
294      * Antaa ikkunan muunnosmatriisin
295      * @return ikkunan muunnosmatriisi
296      */
297     @Override
298     public Matrix getTransform() {
299        return panel.getTransform();
300     }
301 }
302