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 }