1   /**
2    * 
3    */
4   package kerhoswing;
5   
6   import java.awt.BorderLayout;
7   import java.awt.Color;
8   import java.awt.Dimension;
9   import java.awt.FlowLayout;
10  import java.awt.Font;
11  import java.awt.event.ActionEvent;
12  import java.awt.event.ActionListener;
13  import java.awt.event.KeyAdapter;
14  import java.awt.event.KeyEvent;
15  
16  import javax.swing.BoxLayout;
17  import javax.swing.JButton;
18  import javax.swing.JDialog;
19  import javax.swing.JLabel;
20  import javax.swing.JOptionPane;
21  import javax.swing.JPanel;
22  import javax.swing.JScrollPane;
23  import javax.swing.JTextField;
24  import javax.swing.UIManager;
25  import javax.swing.border.EmptyBorder;
26  
27  import kanta.IntKentta;
28  import kanta.JonoKentta;
29  import kanta.Kentta;
30  import kanta.PohjaTietue;
31  import kanta.RegExpTarkistaja;
32  import kanta.Tietue;
33  import kerho.Harrastus;
34  import kerho.Jasen;
35  import fi.jyu.mit.gui.EditPanel;
36  
37  
38  /**
39   * Dialogi, jolla voidaan muokata Tietue-rajapinnan edustajaa
40   * @author vesal
41   * @version 25.03.2012
42   * TODO muuta paneeliksi jota voi käyttää toisissa formeissa.
43   */
44  public class TietueDialog extends JDialog {
45      private static final long serialVersionUID = 1L;
46  
47      private static Color virheVari = new Color(255, 0, 0);
48      private static Color normaaliVari = new Color(255, 255, 255);
49  
50      private boolean result = false;
51      private Tietue muokattavaTietue;
52      private int editLeveys = 150;
53      private int maxLabelLeveys = 20;
54      private EditPanel[] editTietueKentta = null;
55  
56      private final JPanel contentPanel = new JPanel();
57      private JPanel buttonPane = new JPanel();
58      private JButton okButton = new JButton("OK");
59      private JButton cancelButton = new JButton("Cancel");
60      
61      private final JLabel labelVirhe = new JLabel("");
62      private final JScrollPane scrollTietue = new JScrollPane();
63      private final JPanel panelTietueenPaikka = new JPanel();
64  
65  
66      /**
67       * Testiohjelman tietueen kysymisdialogille
68       * @param args ei käytössä
69       */
70      public static void main(String[] args) {
71          try {
72              UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
73          } catch (Throwable e) {
74              e.printStackTrace();
75          }
76          try {
77              boolean result;
78              Jasen jasen = new Jasen();
79              Harrastus har = new Harrastus();
80              result = kysyTietue(jasen,"Anna jäsenen tiedot",200);
81              if ( !result ) return;
82              result = kysyTietue(har,"Anna harrastuksen tiedot",50);
83              if ( !result ) JOptionPane.showMessageDialog(null, "Et tykännyt");
84              Kentta[] kentat = { 
85                      new IntKentta("id"),
86                      new JonoKentta("Laita merkkejä A-F",new RegExpTarkistaja("[A-F]+")),
87                      new JonoKentta("Laita haluttu määrä a",new RegExpTarkistaja("a+","Vain a kirjaimia"))        
88              };
89              PohjaTietue t = new PohjaTietue(kentat, 1);
90              result = kysyTietue(t,"Anna lisätiedot",40);
91              if ( !result ) return;
92              JOptionPane.showMessageDialog(null, "Ekaan laitoit: " + t.anna(1));
93          } catch (Exception e) {
94              e.printStackTrace();
95          }
96      }
97  
98      
99      /**
100      * Käynnistä dialogi ja kysy tietueeseen tiedot
101      * @param tietue tietue jota muoskataan 
102      * @param otsikko lomakkeessa näytettävä otsikko
103      * @param editLeveys kuinka leveäski edit-lenttä tehdään
104      * @return true jos kuitattu OK, muuten false
105      */
106     public static boolean kysyTietue(Tietue tietue,String otsikko, int editLeveys) {
107         boolean ret = false;
108         TietueDialog dialog = new TietueDialog();
109         dialog.setTitle(otsikko);
110         dialog.setEditLeveys(editLeveys);
111         dialog.setMuokattavaTietue(tietue);
112         dialog.setVisible(true);
113         ret = dialog.getResult();
114         dialog.dispose();
115         return ret;
116     }
117 
118 
119 
120     /**
121      * Create the dialog.
122      */
123     public TietueDialog() {
124         setModalityType(ModalityType.APPLICATION_MODAL);
125         setModal(true);
126         setBounds(100, 100, 367, 411);
127         getContentPane().setLayout(new BorderLayout());
128         contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
129         getContentPane().add(contentPanel, BorderLayout.CENTER);
130         contentPanel.setLayout(new BorderLayout(0, 0));
131         labelVirhe.setOpaque(true);
132         labelVirhe.setPreferredSize(new Dimension(20, 20));
133         
134         contentPanel.add(labelVirhe, BorderLayout.SOUTH);
135         
136         contentPanel.add(scrollTietue, BorderLayout.CENTER);
137         
138         scrollTietue.setViewportView(panelTietueenPaikka);
139         panelTietueenPaikka.setLayout(new BorderLayout(0, 0));
140         
141         panelTietueenPaikka.add(panelTietue, BorderLayout.NORTH);
142         panelTietue.setLayout(new BoxLayout(panelTietue, BoxLayout.Y_AXIS));
143         
144         panelTietue.add(editPanelNimi);
145         editPanelHetu.setCaption("hetu");
146         
147         panelTietue.add(editPanelHetu);
148         buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
149         getContentPane().add(buttonPane, BorderLayout.SOUTH);
150 
151         okButton.addActionListener(new ActionListener() {
152             @Override
153             public void actionPerformed(ActionEvent e) {
154                 if (!tarkista() ) return;
155                 setResult(true);
156                 setVisible(false);
157             }
158         });
159         okButton.setActionCommand("OK");
160         buttonPane.add(okButton);
161 
162         getRootPane().setDefaultButton(okButton);
163         cancelButton.addActionListener(new ActionListener() {
164             @Override
165             public void actionPerformed(ActionEvent e) {
166                 setVisible(false);
167             }
168         });
169         cancelButton.setActionCommand("Cancel");
170         buttonPane.add(cancelButton);
171     }
172     
173     
174     /**
175      * Palautetaan dialogista saatu tulos. 
176      * @return true jos painettiuin ok, muuten false
177      */
178     public boolean getResult() {
179         return result;
180     }
181 
182 
183     /**
184      * Apumetodi tuloksen asettamiseksi sisäistä luokista 
185      * @param value palautettava arvo
186      */
187     protected void setResult(Boolean value) {
188         result = value;
189     }
190 
191 
192     /**
193      * @return mitä tietuetta ollaan muokkaamassa
194      */
195     protected Tietue getMuokattavaTietue() {
196         return muokattavaTietue;
197     }
198 
199 
200     /**
201      * Käsittelijäluokka edit kentän näppäimen vapauttamiselle 
202      */
203     protected class EditKeyReleased extends KeyAdapter {
204         @Override public void keyReleased(KeyEvent e) {
205             kasitteleMuutosTietueeseen((JTextField)e.getComponent());
206         }
207     }
208     
209     
210     private EditKeyReleased editKeyReleased = new EditKeyReleased();
211     private final JPanel panelTietue = new JPanel();
212     private final EditPanel editPanelNimi = new EditPanel();
213     private final EditPanel editPanelHetu = new EditPanel();
214     
215     
216     /**
217      * @param tietue tietue jota muokataan 
218      */
219     protected void setMuokattavaTietue(Tietue tietue) {
220         this.muokattavaTietue = tietue;
221         panelTietue.removeAll();
222         int n = tietue.getKenttia() - tietue.ekaKentta();
223         editTietueKentta = new EditPanel[n];
224         maxLabelLeveys = 20;
225 
226         for (int i = 0, k = tietue.ekaKentta(); k < tietue.getKenttia(); k++, i++) {
227             EditPanel edit = new EditPanel(); 
228             edit.setCaption(tietue.getKysymys(k));
229             edit.setText(tietue.anna(k));
230             editTietueKentta[i] = edit;
231             edit.setName("et" + k);
232             edit.getEdit().setName("tt" + k);
233             panelTietue.add(edit);
234             edit.addKeyListener(editKeyReleased); 
235             edit.setLabelWidth(150);
236             Font font = edit.getLabel().getFont();  
237             // int fontHeight = getFontMetrics(font).getHeight();  
238             int w = getFontMetrics(font).stringWidth(edit.getCaption()) + 10;
239             if ( w > maxLabelLeveys ) maxLabelLeveys = w;            
240         }
241         asetaLeveydet();
242     }
243 
244 
245     /**
246      * Asetetaan edit-kenttien leveydet maksimin ja edit-leveyden mukaan 
247      */
248     protected void asetaLeveydet() {
249         if ( editTietueKentta == null ) return;
250         for (EditPanel edit : editTietueKentta) {
251             int h = edit.getPreferredSize().height;
252             edit.setLabelWidth(maxLabelLeveys);
253             edit.setPreferredSize(new Dimension(editLeveys+maxLabelLeveys,h));
254         }
255         pack();  // muokkaa dialogin mahdollisimman pieneksi
256     }
257 
258     
259     /**
260      * Laitetaan virheilmoitus näkyville jos labelVirhe on alustettu.
261      * Miksä virhettä ei ole, niin piilotetaan virheilmoitus.    
262      * @param virhe virheteksti
263      */
264     protected void setVirhe(String virhe) {
265         if ( labelVirhe == null ) return;
266         if ( virhe == null ) {
267             labelVirhe.setText("");
268             labelVirhe.setVisible(false);
269             okButton.setVisible(true);
270             return;
271         }
272         labelVirhe.setVisible(true);
273         labelVirhe.setText(" " +virhe);
274         labelVirhe.setBackground(virheVari);
275         okButton.setVisible(false);
276     }
277 
278     private boolean ekaKerta = false; // laita tähän true jos tulee aluksi turha tapahtuma
279    
280     /**
281      * Käsittelee edit-kenttään tulleen muutoksen tietueeseen.
282      * Jos muutosta ei voida sijoittaa tietueeseen, muutetaan 
283      * taustaväri punaiseksi.
284      * @param edit muuttunut kenttä
285      */
286     protected void kasitteleMuutosTietueeseen(JTextField edit) {
287         if (ekaKerta) { ekaKerta = false; return; } // Jostakin syystä yksi tapahtuma tulee heti aluksi. Tätä ei haluta
288         if (editTietueKentta == null) return;
289         if (edit == null) return;
290         if (muokattavaTietue == null) return;
291         String s = edit.getText();
292         int k = Integer.parseInt(edit.getName().substring(2));
293         String virhe = muokattavaTietue.aseta(k, s);
294         setVirhe(virhe);
295         if (virhe == null) {
296             edit.setToolTipText("");
297             edit.setBackground(normaaliVari);
298         } else {
299             edit.setToolTipText(virhe);
300             edit.setBackground(virheVari);
301         }
302     }
303 
304 
305     /**
306      * Tarkistetaan onko kaikki kentät täytetty oikein
307      * @return true jos kentät oikein 
308      */
309     protected boolean tarkista() {
310         boolean res = true;
311         ekaKerta = false;
312         JTextField ekaVirhe = null;
313         for (EditPanel edit : editTietueKentta) {
314             kasitteleMuutosTietueeseen(edit.getEdit());
315             if ( !okButton.isValid() ) {
316                 if ( ekaVirhe == null ) ekaVirhe = edit.getEdit();
317                 res = false;
318             }
319         }
320         if ( ekaVirhe != null ) {
321             kasitteleMuutosTietueeseen(ekaVirhe);
322             ekaVirhe.requestFocusInWindow(); 
323         }  
324         return res;
325     }
326 
327 
328     /**
329      * @return editointikentän leveys
330      */
331     public int getEditLeveys() {
332         return editLeveys;
333     }
334 
335 
336     /**
337      * @param editLeveys leveys editointikentille
338      */
339     public void setEditLeveys(int editLeveys) {
340         this.editLeveys = editLeveys;
341         // asetaLeveydet();
342         if ( muokattavaTietue != null ) setMuokattavaTietue(muokattavaTietue);
343     }
344     
345     
346 
347 }
348