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 }