001    /**
002    * @author Václav Mikolášek
003    * nicklaus@students.zcu.cz
004    */
005    
006    package animace.panel;
007    
008    import animace.*;
009    import javax.swing.*;
010    import java.awt.*;
011    import java.awt.image.*;
012    import java.awt.event.*;
013    
014    /**
015     * Třída TestPanel ukazuje použití připravených tříd PicturePanel a PictureButton.
016     * Vzhledem k tomu, že obě třídy nejsou nic jiného, než potomky třídy ze Swingu, 
017     * potažmo z AWT, je jejich použití snadné a zcela standardní. V tomto systému, kdy
018     * JButtony nesou obrázky a jsou umístěny na panel (s obrázkem na pozadí) máme velice
019     * málo práce s implementací.
020     */
021    public class TestPanel {
022            private static JFrame frame;
023            private static PicturePanel scr;
024            private static PictureButton[] pButtons = new PictureButton[0];
025                    
026            /**
027             * Rozeběhne test
028             */
029            public static void main(String[] args) {
030                    if (args.length > 0) {
031                            try {
032                                    pButtons = new PictureButton[Integer.valueOf(args[0]).intValue()];
033                            }
034                            catch (NumberFormatException e) {
035                                    System.out.println("Parametrem aplikace je pocet obrazku");
036                                    System.exit(1);
037                            }
038                    }
039                    
040                    initFrame();
041                    initPictures();
042                    frame.setVisible(true);
043            }
044            
045            /**
046             * Inicializační metoda pro okno a obrázky. Obrázek na pozadi se tahá z ImageSource
047             */
048            private static void initFrame() {
049                    frame = new JFrame("Test PicturePanelu - obrazky na buttonech");
050                    JTextArea napoveda = new JTextArea();
051                    napoveda.setFont(new Font("Arial Bold", Font.PLAIN,12));
052                    napoveda.setBorder( new javax.swing.plaf.BorderUIResource.BevelBorderUIResource(1));
053                    napoveda.setEditable(false);
054                    napoveda.setText(" Nápověda:\n"+
055                            " Stisknutím kláves F1 az F12 uvedete do pohybu nebo zastavíte\n" +
056                            " obrázky s odpovídajícím pořadovým číslem. Kliknutím na konkrétní\n"+
057                            " obrázek zobrazíte okénko s údaji o jeho číslu, FPS,\n"+
058                            " celkovém počtu snímku a počtu posunů");
059    
060                    
061                    BufferedImage bg = ImageSource.square1(Color.red.darker(),Color.red.darker().darker());
062                    
063                    /// PicturePanel
064                    scr = new PicturePanel(bg);
065                    
066                    ///nastaveni okna
067                    Container c = frame.getContentPane();
068                    c.setLayout(new BorderLayout());
069                    c.add(scr,BorderLayout.CENTER);
070                    c.add(napoveda,BorderLayout.SOUTH);
071                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
072                    frame.setSize(400,450);
073            }
074            
075            /**
076             * Vytvoří instance třídy PictureButton, zaregistruje jim posluchače kliknutí
077             * a dá je na PicturePanel.
078             */
079            private static void initPictures() {
080                    /// nastaveni PicturePanelu
081                    for (int i =0; i < pButtons.length; i++) 
082                    {
083                            pButtons[i] = new PictureButton(ImageSource.javaLogo());
084                            pButtons[i].setPaintControl(new PaintControl());
085                            pButtons[i].addActionListener(new PButtonActionListener("F"+(i+1)));
086                            scr.add(pButtons[i],JLayeredPane.DEFAULT_LAYER);
087                            scr.getInputMap(scr.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1 + i,0),"F"+(i+1));
088                            scr.getActionMap().put("F"+(i+1),new PButtonKeyAction(pButtons[i]));
089                    }
090            }
091            
092            /**
093             * AbstractAction (Reakce na stik klávesy) starajicí se o rozběhnutí požadovaného obrázku
094             */
095            public static class PButtonKeyAction extends AbstractAction {
096                    private PictureButton pb = null;
097                    private Driver driver = null;
098    
099                            
100                    /**
101                     * Konstruktor vyžaduje objekt typu PictureButton,
102                     * pro který bude vytvářet vlákno Driver
103                     */
104                    public PButtonKeyAction(PictureButton pb) {
105                            this.pb = pb;
106                    }
107                    
108                    /**
109                     * Po stisku klávesy F(X) se provede test, zda je objekt již v pohybu,
110                     * potom je pozastaven, v opačném případě se inicializuje vlákno Driver
111                     * pro tento objekt a je spuštěno.
112                     */
113                    public void actionPerformed(ActionEvent e) {
114                            if (driver != null && driver.goes()) {
115                                    driver.stopDriving();
116                            }
117                            else {
118                                    PicturePanel c = (PicturePanel) e.getSource();
119                                    driver = new Driver(pb,0,0,c.getWidth() - pb.getWidth(),c.getHeight()-pb.getHeight());
120                                    driver.setPaintControl(pb.getPaintControl());
121                                    driver.start();
122                            }
123                    }
124            }
125            
126            /**
127             * PButtonActionListener způsobí, že po kliknuti na PictureButton 
128             * bude otevřeno okno s některými informacemi o objektu.
129             */
130            public static class PButtonActionListener implements ActionListener {
131                    private JFrame infoFrame = null;
132                    private JLabel nameVal;
133                    private JLabel name             = new JLabel(" Tlacitko:",JLabel.LEFT);;
134                    private JLabel fps              = new JLabel(" FPS:",JLabel.LEFT);
135                    private JLabel frames           = new JLabel(" Snimku:",JLabel.LEFT);
136                    private JLabel movesCount       = new JLabel(" Posun o:",JLabel.LEFT);
137                    private JLabel movesCountNum    = new JLabel("",JLabel.LEFT);
138                    private JLabel fpsNum           = new JLabel("",JLabel.LEFT);
139                    private JLabel framesNum        = new JLabel("",JLabel.LEFT);
140                            
141                                    
142                    /**
143                     * Konstruktor vyžaduje jméno objektu, tento parametr se potom zobrazí 
144                     * mezi informacemi.
145                     */     
146                    public PButtonActionListener(String name) {
147                            this.nameVal = new JLabel(" " + name, JLabel.LEFT);
148                            initInfoFrame();
149                    }
150                    
151                    /// Nastavi podobu okna
152                    private void initInfoFrame() {
153                            infoFrame = new JFrame();
154                            Container c = infoFrame.getContentPane();
155                            c.setLayout(new GridLayout(0,2));
156                            c.add(name);
157                            c.add(nameVal);
158                            c.add(fps);
159                            c.add(fpsNum);
160                            c.add(frames);
161                            c.add(framesNum);
162                            c.add(movesCount);
163                            c.add(movesCountNum);
164                            
165                            c.setBackground(Color.gray.brighter());
166                    }
167    
168                    /**
169                     * Když uživatel klikne na PictureButton, provede se tato obsluha, která
170                     * otevře okno s některými informacemi o objektu. Jméno, FPS, Počet snímků a počet
171                     * vykonaných posunů.
172                     */
173                    public void actionPerformed(ActionEvent e) {
174                            
175                            PictureButton pb = (PictureButton) e.getSource();
176                            
177                            fpsNum.setText(" " + Math.round(pb.getPaintControl().getAverageFps()));
178                            framesNum.setText(" " + pb.getPaintControl().framesCount);
179                            movesCountNum.setText(" " + pb.getPaintControl().movesCount);
180                            infoFrame.pack();
181                            if (infoFrame.isVisible()) {
182                                    infoFrame.validate();  
183                            }
184                            else {
185                                    infoFrame.setVisible(true);
186                            }
187                    }
188            }
189    }