Source code: jmmv/ui/Form.java
1 /*
2 * DiskCat - Disk Cataloguer
3 * Copyright (C) 2002 Julio Merino <slink@unixbsd.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21 package jmmv.ui;
22
23 import jmmv.Global;
24 import jmmv.db.InvalidDataException;
25 import jmmv.db.Register;
26
27 import java.awt.Font;
28 import java.awt.event.ItemEvent;
29 import java.awt.event.ItemListener;
30 import java.awt.event.KeyEvent;
31 import java.awt.event.KeyListener;
32 import java.awt.GridBagConstraints;
33 import java.awt.GridBagLayout;
34 import java.util.LinkedList;
35 import java.util.ListIterator;
36 import java.sql.SQLException;
37 import javax.swing.JComboBox;
38 import javax.swing.JComponent;
39 import javax.swing.JLabel;
40 import javax.swing.JPanel;
41 import javax.swing.JTextField;
42 import javax.swing.event.ChangeEvent;
43 import javax.swing.event.ChangeListener;
44 import javax.swing.event.EventListenerList;
45
46 /**
47 * Form provides a base abstarct class to create forms in a GUI, using
48 * Swing components. The form is based on a JPanel which can be
49 * 'included' in any container.
50 *
51 * A form emits a ChangeEvent whenever the state of any form entry
52 * changes (i.e. a letter is added, an option is changed, etc). This
53 * allows parent frames to know when the state of the panel changes.
54 *
55 * The form data is based on jmmv.db.Register and derived
56 * classes, that provide a common and abstract way to access a
57 * database.
58 */
59 public abstract class Form extends JPanel implements ItemListener, KeyListener, ChangeListener {
60 protected GridBagLayout gbl;
61 private EventListenerList listenerList = new EventListenerList();
62 private ChangeEvent changeEvent = null;
63 protected boolean ignoreEvents;
64
65 public Form() {
66 GridBagConstraints gbc = new GridBagConstraints();
67
68 gbl = new GridBagLayout();
69 setLayout(gbl);
70
71 ignoreEvents = false;
72 }
73
74 /**
75 * Adds a new entry to the form. An entry is formed by a caption, that
76 * is converted into a JLabel, and a component, that can be any kind of
77 * Swing object. This function is private because it doesn't provide
78 * enough functionality to manage components.
79 *
80 * @param caption The text to add.
81 * @param comp The Swing component.
82 * @param required Specifies if the entry must be filled in.
83 * @see #addEntry(String,JTextLabel,boolean)
84 * @see #addEntry(String,JComboBox,boolean)
85 * @see #addEntry(String,DateEntry,boolean)
86 */
87 private final void internalAddEntry(String caption, JComponent comp, boolean required) {
88 GridBagConstraints gbc = new GridBagConstraints();
89 JLabel label = new JLabel (caption);
90
91 if (required)
92 label.setFont(label.getFont().deriveFont(Font.ITALIC | Font.BOLD));
93
94 gbc.fill = GridBagConstraints.BOTH;
95 gbc.gridwidth = GridBagConstraints.RELATIVE;
96 gbc.ipadx = 5;
97 gbc.ipady = 5;
98 gbc.weighty = 0.1;
99
100 gbc.weightx = 10;
101 gbl.setConstraints(label, gbc);
102 add(label);
103
104 gbc.weightx = 90;
105 gbc.fill = GridBagConstraints.HORIZONTAL;
106 gbc.gridwidth = GridBagConstraints.REMAINDER;
107 gbl.setConstraints(comp, gbc);
108 add(comp);
109 }
110
111 /**
112 * Adds a new entry to the form, based on a caption and a text field.
113 * The text field will be connected to a KeyListener so that the dialog
114 * can enter 'update' mode when a text is modified.
115 *
116 * @param caption The text to add.
117 * @param comp The JTextField.
118 * @param required Specifies if the entry must be filled in.
119 */
120 protected final void addEntry(String caption, JTextField comp, boolean required) {
121 internalAddEntry(caption, comp, required);
122 comp.addKeyListener(this);
123 }
124
125 /**
126 * Adds a new entry to the form, based on a caption and a combobox field.
127 * The combobox will be connected to an EntryListener so that the dialog
128 * can enter 'update' mode when the option is changed.
129 *
130 * @param caption The text to add.
131 * @param comp The JComboBox.
132 * @param required Specifies if the entry must be filled in.
133 */
134 protected final void addEntry(String caption, JComboBox comp, boolean required) {
135 internalAddEntry(caption, comp, required);
136 comp.addItemListener(this);
137 }
138
139 /**
140 * Adds a new entry to the form, based on a caption and a combobox field.
141 * The combobox will be connected to an EntryListener so that the dialog
142 * can enter 'update' mode when the option is changed.
143 *
144 * @param caption The text to add.
145 * @param comp The DateEntry.
146 * @param required Specifies if the entry must be filled in.
147 */
148 protected final void addEntry(String caption, DateEntry comp, boolean required) {
149 internalAddEntry(caption, comp, required);
150 comp.addChangeListener(this);
151 }
152
153 /**
154 * Shows the current register on the form. It must use the 'currentReg'
155 * variable, provided by the derived class.
156 */
157 protected abstract void showRegister();
158
159 /**
160 * Clears form data, and sets default values for fields that can't be
161 * 'emptied', like comboboxes.
162 */
163 public abstract void emptyFields();
164
165 public abstract Register getRegister() throws InvalidDataException, SQLException;
166 public abstract void setRegister(Register r);
167
168 /**
169 * This action manager is used to enter updating mode when a field
170 * in the dialog, that allows item selection, is changed.
171 */
172 public void itemStateChanged(ItemEvent evt) {
173 if (ignoreEvents) return;
174 fireStateChanged();
175 }
176
177 /**
178 * This action manager is used to enter updating mode when a field
179 * in the dialog, that allows text change, is edited.
180 */
181 public void keyTyped(KeyEvent evt) {
182 if (ignoreEvents) return;
183 fireStateChanged();
184 }
185
186 /** Unused */
187 public void keyPressed(KeyEvent evt) {}
188
189 /** Unused */
190 public void keyReleased(KeyEvent evt) {}
191
192 public void stateChanged(ChangeEvent evt) {
193 if (ignoreEvents) return;
194 fireStateChanged();
195 }
196
197 public void addChangeListener(ChangeListener l) {
198 listenerList.add(ChangeListener.class, l);
199 }
200
201 public void removeChangeListener(ChangeListener l) {
202 listenerList.remove(ChangeListener.class, l);
203 }
204
205 protected void fireStateChanged() {
206 Object[] listeners = listenerList.getListenerList();
207
208 for (int i = listeners.length-2; i>=0; i-=2) {
209 if (listeners[i] == ChangeListener.class) {
210 if (changeEvent == null)
211 changeEvent = new ChangeEvent(this);
212 ((ChangeListener) listeners[i+1]).stateChanged(changeEvent);
213 }
214 }
215 }
216 }