001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.editor;
025:
026: import jacareto.starter.AppletStarter;
027: import jacareto.starter.Starter;
028: import jacareto.system.Environment;
029: import jacareto.system.Language;
030: import jacareto.toolkit.io.FileUtilities;
031:
032: import java.awt.BorderLayout;
033: import java.awt.Container;
034: import java.awt.Dialog;
035: import java.awt.Dimension;
036: import java.awt.FlowLayout;
037: import java.awt.Frame;
038: import java.awt.GridBagConstraints;
039: import java.awt.GridBagLayout;
040: import java.awt.Insets;
041: import java.awt.Point;
042: import java.awt.Window;
043: import java.awt.event.ActionEvent;
044: import java.awt.event.ActionListener;
045:
046: import java.io.File;
047:
048: import java.util.Enumeration;
049: import java.util.Hashtable;
050:
051: import javax.swing.JButton;
052: import javax.swing.JDialog;
053: import javax.swing.JFileChooser;
054: import javax.swing.JLabel;
055: import javax.swing.JPanel;
056: import javax.swing.JScrollPane;
057: import javax.swing.JTable;
058: import javax.swing.JTextField;
059: import javax.swing.ListSelectionModel;
060: import javax.swing.SwingUtilities;
061: import javax.swing.event.ListSelectionEvent;
062: import javax.swing.event.ListSelectionListener;
063: import javax.swing.table.DefaultTableModel;
064:
065: /**
066: * The panel for the cursor images in the starters..
067: *
068: * @author <a href="mailto:cspannagel@web.de">Christian Spannagel</a>
069: * @version 1.03
070: */
071: public class CursorImagesPanel extends JPanel implements
072: ActionListener, ListSelectionListener {
073: /** The language. */
074: private Language language;
075:
076: /** The table. */
077: private JTable table;
078:
079: /** The table model. */
080: private DefaultTableModel tableModel;
081:
082: /** The associated editor. */
083: private Editor editor;
084:
085: /** The button for a new image entry. */
086: private JButton newButton;
087:
088: /** The button for editing an image entry. */
089: private JButton editButton;
090:
091: /** The delete button. */
092: private JButton deleteButton;
093:
094: /** Whether or not the starter should be updated. */
095: private boolean isUpdateOnChange;
096:
097: /**
098: * Creates a new instance.
099: *
100: * @param env the environemt
101: * @param editor the associated starter editor
102: * @param isUpdateOnChange whether or not the starter should be updated
103: */
104: public CursorImagesPanel(Environment env, Editor editor,
105: boolean isUpdateOnChange) {
106: this .editor = editor;
107: this .isUpdateOnChange = isUpdateOnChange;
108: language = env.getLanguage();
109:
110: setLayout(new BorderLayout());
111:
112: table = new JTable(0, 2) {
113: public boolean isCellEditable(int row, int column) {
114: return false;
115: }
116: };
117:
118: ListSelectionModel selectionModel = table.getSelectionModel();
119: selectionModel
120: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
121: selectionModel.addListSelectionListener(this );
122:
123: JScrollPane tablePane = new JScrollPane(table) {
124: public Insets getInsets() {
125: return new Insets(10, 10, 10, 10);
126: }
127: };
128:
129: tablePane.setPreferredSize(new Dimension(400, 300));
130: tableModel = (DefaultTableModel) table.getModel();
131:
132: Object[] columnNames = new Object[2];
133: columnNames[0] = language
134: .getString("Starters.Starter.Cursor.Name");
135: columnNames[1] = language
136: .getString("Starters.Starter.Cursor.Image");
137: tableModel.setColumnIdentifiers(columnNames);
138:
139: if (editor.getElement() != null) {
140: Hashtable params = ((AppletStarter) editor.getElement())
141: .getCursorImages();
142: Enumeration enumeration = params.keys();
143:
144: while (enumeration.hasMoreElements()) {
145: String[] rowData = new String[2];
146: rowData[0] = (String) enumeration.nextElement();
147: rowData[1] = (String) params.get(rowData[0]);
148: tableModel.addRow(rowData);
149: }
150: }
151:
152: JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT));
153: newButton = new JButton(language.getString("General.New"));
154: newButton.addActionListener(this );
155: buttonPane.add(newButton);
156: editButton = new JButton(language.getString("General.Edit"));
157: editButton.addActionListener(this );
158: editButton.setEnabled(false);
159: buttonPane.add(editButton);
160: deleteButton = new JButton(language.getString("General.Delete"));
161: deleteButton.addActionListener(this );
162: deleteButton.setEnabled(false);
163: buttonPane.add(deleteButton);
164:
165: add(tablePane, BorderLayout.CENTER);
166: add(buttonPane, BorderLayout.SOUTH);
167: }
168:
169: /**
170: * Called when a button has been pressed.
171: *
172: * @param event the action event representing the button action
173: */
174: public void actionPerformed(ActionEvent event) {
175: Window window = SwingUtilities.getWindowAncestor(editor
176: .getComponent());
177:
178: if (event.getSource() == newButton) {
179: CursorEditorDialog dialog = null;
180:
181: if (window instanceof Frame) {
182: dialog = new CursorEditorDialog((Frame) window);
183: } else if (window instanceof Dialog) {
184: dialog = new CursorEditorDialog((Dialog) window);
185: }
186:
187: String key = dialog.getKey();
188: String value = dialog.getValue();
189:
190: if ((key != null) && (!key.equals(""))) {
191: Object[] rowData = new Object[2];
192: rowData[0] = key;
193: rowData[1] = value;
194: tableModel.addRow(rowData);
195:
196: if (isUpdateOnChange && (editor.getElement() != null)) {
197: ((Starter) editor.getElement()).setCursorImage(key,
198: value);
199: }
200: }
201: } else if (event.getSource() == editButton) {
202: int selectedRow = table.getSelectedRow();
203:
204: if (selectedRow >= 0) {
205: String key = (String) tableModel.getValueAt(
206: selectedRow, 0);
207: String value = (String) tableModel.getValueAt(
208: selectedRow, 1);
209: CursorEditorDialog dialog = null;
210:
211: if (window instanceof Frame) {
212: dialog = new CursorEditorDialog((Frame) window,
213: key, value);
214: } else if (window instanceof Dialog) {
215: dialog = new CursorEditorDialog((Dialog) window,
216: key, value);
217: }
218:
219: key = dialog.getKey();
220: value = dialog.getValue();
221:
222: if ((key != null) && (!key.equals(""))) {
223: tableModel.setValueAt(key, selectedRow, 0);
224: tableModel.setValueAt(value, selectedRow, 1);
225:
226: if (isUpdateOnChange
227: && (editor.getElement() != null)) {
228: ((Starter) editor.getElement()).setCursorImage(
229: key, value);
230: }
231: }
232: }
233: } else if (event.getSource() == deleteButton) {
234: int selectedRow = table.getSelectedRow();
235:
236: if (selectedRow >= 0) {
237: String key = (String) tableModel.getValueAt(
238: selectedRow, 0);
239: tableModel.removeRow(selectedRow);
240:
241: if (isUpdateOnChange && (editor.getElement() != null)) {
242: ((Starter) editor.getElement())
243: .removeCursorImage(key);
244: }
245:
246: deleteButton.setEnabled(false);
247: editButton.setEnabled(false);
248: }
249: }
250: }
251:
252: public void addRow(String[] data) {
253: tableModel.addRow(data);
254: }
255:
256: /**
257: * Called when the list selection has changed.
258: *
259: * @param event DOCUMENT ME!
260: */
261: public void valueChanged(ListSelectionEvent event) {
262: editButton.setEnabled(true);
263: deleteButton.setEnabled(true);
264: }
265:
266: /**
267: * Clears the table.
268: */
269: private void clearTable() {
270: for (int i = tableModel.getRowCount() - 1; i >= 0; i--) {
271: tableModel.removeRow(i);
272: }
273: }
274:
275: /**
276: * Sets the data of the table
277: *
278: * @param data DOCUMENT ME!
279: */
280: public void setTableData(Hashtable data) {
281: clearTable();
282:
283: Enumeration enum2 = data.keys();
284:
285: while (enum2.hasMoreElements()) {
286: String[] rowData = new String[2];
287: rowData[0] = (String) enum2.nextElement();
288: rowData[1] = (String) data.get(rowData[0]);
289: addRow(rowData);
290: }
291: }
292:
293: //
294: // The cursor entry editor
295: //
296:
297: /**
298: * The editor dialog for cursor entries.
299: */
300: class CursorEditorDialog extends JDialog implements ActionListener {
301: //~ Instance fields ------------------------------------------------------------------------
302:
303: private String key;
304: private String value;
305: private JButton okButton;
306: private JButton cancelButton;
307: private JButton chooseButton;
308: private JTextField valueField;
309: private JTextField nameField;
310:
311: //~ Constructors ---------------------------------------------------------------------------
312:
313: CursorEditorDialog(Frame frame) {
314: this (frame, "", "");
315: }
316:
317: CursorEditorDialog(Frame frame, String key, String value) {
318: super (frame, true);
319:
320: Point frameLocation = frame.getLocationOnScreen();
321: create(key, value, frameLocation.x, frameLocation.y, frame
322: .getWidth(), frame.getHeight());
323: }
324:
325: CursorEditorDialog(Dialog dialog) {
326: this (dialog, "", "");
327: }
328:
329: CursorEditorDialog(Dialog dialog, String key, String value) {
330: super (dialog, true);
331:
332: Point dialogLocation = dialog.getLocationOnScreen();
333: create(key, value, dialogLocation.x, dialogLocation.y,
334: dialog.getWidth(), dialog.getHeight());
335: }
336:
337: //~ Methods --------------------------------------------------------------------------------
338:
339: private void create(String key, String value, int frameX,
340: int frameY, int frameWidth, int frameHeight) {
341: this .key = key;
342: this .value = value;
343:
344: Container content = getContentPane();
345: content.setLayout(new GridBagLayout());
346:
347: GridBagConstraints c = new GridBagConstraints();
348: c.fill = GridBagConstraints.NONE;
349: c.anchor = GridBagConstraints.CENTER;
350: c.insets = new Insets(5, 5, 5, 5);
351:
352: // Row for the name
353: c.gridx = 0;
354: c.gridy = 0;
355: c.weightx = 30;
356: c.weighty = 20;
357:
358: JLabel nameLabel = new JLabel(language
359: .getString("Starters.Starter.Cursor.Name"));
360: content.add(nameLabel, c);
361:
362: c.gridx = 1;
363: c.weightx = 60;
364: nameField = new JTextField(key, 20);
365: nameLabel.setLabelFor(nameField);
366: content.add(nameField, c);
367:
368: // Row for the value
369: c.gridx = 0;
370: c.gridy = 1;
371:
372: JLabel valueLabel = new JLabel(language
373: .getString("Starters.Starter.Cursor.Image"));
374: content.add(valueLabel, c);
375:
376: c.gridx = 1;
377: valueField = new JTextField(value, 20);
378: valueLabel.setLabelFor(valueField);
379: content.add(valueField, c);
380:
381: c.gridx = 2;
382: c.weightx = 20;
383: chooseButton = new JButton(language
384: .getString("General.Choose")
385: + "...");
386: chooseButton.addActionListener(this );
387: content.add(chooseButton, c);
388:
389: // Row for the buttons
390: c.gridwidth = 3;
391: c.gridx = 0;
392: c.gridy = 2;
393: c.weighty = 40;
394:
395: JPanel buttonRow = new JPanel(new FlowLayout(
396: FlowLayout.CENTER));
397: okButton = new JButton(language.getString("General.Ok"));
398: okButton.addActionListener(this );
399: cancelButton = new JButton(language
400: .getString("General.Cancel"));
401: cancelButton.addActionListener(this );
402: buttonRow.add(okButton);
403: buttonRow.add(cancelButton);
404: content.add(buttonRow, c);
405:
406: pack();
407:
408: int x = frameX + ((frameWidth - getWidth()) / 2);
409: int y = frameY + ((frameHeight - getHeight()) / 2);
410: setLocation(x, y);
411:
412: setVisible(true);
413: }
414:
415: public void actionPerformed(ActionEvent event) {
416: if (event.getSource() == okButton) {
417: this .key = nameField.getText();
418: this .value = valueField.getText();
419: dispose();
420: } else if (event.getSource() == chooseButton) {
421: JFileChooser chooser = new JFileChooser(".");
422: chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
423: chooser
424: .setFileFilter(new javax.swing.filechooser.FileFilter() {
425: public boolean accept(File file) {
426: try {
427: if (file.isDirectory()) {
428: return true;
429: } else {
430: String extension = FileUtilities
431: .getExtension(file)
432: .toLowerCase();
433:
434: return extension.equals("gif")
435: || extension
436: .equals("jpg")
437: || extension
438: .equals("jpeg");
439: }
440: } catch (Exception e) {
441: // just for mysterious InterruptedExceptions
442: return false;
443: }
444: }
445:
446: public String getDescription() {
447: return "Images (*.GIF, *.JPG)";
448: }
449: });
450: chooser.setDialogTitle(language
451: .getString("General.ChooseFile")
452: + "...");
453:
454: int returnVal = chooser.showDialog(this , language
455: .getString("General.Ok"));
456:
457: if (returnVal == JFileChooser.APPROVE_OPTION) {
458: valueField.setText(chooser.getSelectedFile()
459: .getAbsolutePath());
460: }
461: } else {
462: this .key = null;
463: this .value = null;
464: dispose();
465: }
466: }
467:
468: /**
469: * Returns the key, or <code>null</code> when the user has canceled.
470: *
471: * @return DOCUMENT ME!
472: */
473: public String getKey() {
474: return key;
475: }
476:
477: /**
478: * Returns the value, or <code>null</code> when the user has canceled.
479: *
480: * @return DOCUMENT ME!
481: */
482: public String getValue() {
483: return value;
484: }
485: }
486: }
|