1 package edu.psu.geovista.category;
2
3 import javax.swing.*;
4 import javax.swing.table.AbstractTableModel;
5 import javax.swing.table.TableCellRenderer;
6 import javax.swing.table.TableColumn;
7 import javax.swing.table.DefaultTableCellRenderer;
8 import java.awt.*;
9 import java.awt.event.*;
10 import javax.swing.event.*;
11 import javax.swing.border.Border;
12 import java.util.Vector;
13 import edu.psu.geovista.ui.event.*;
14 import edu.psu.geovista.data.geog.DataSetForApps;
15 import edu.psu.geovista.symbolization.ColorInterpolator;
16
17 /***
18 * <p>Title: Studio applications</p>
19 * <p>Description: </p>
20 * <p>Copyright: Copyright (c) 2002</p>
21 * <p>Company: GeoVSITA Center</p>
22 * @author Xiping Dai
23 * @version 1.0
24 */
25
26 public class CategoryRecords extends JPanel implements ChangeListener, SelectionListener, DataSetListener{
27
28 private static String DEFAULT_USERINFO = "new";
29 private static int DEFAULT_VERSION = 0;
30 private static Color DEFAULT_COLOR = new Color(0, 0, 255);
31 private static String DEFAULT_EXAMPLE_TYPE = "ideal";
32
33 private String userInfo = DEFAULT_USERINFO;
34 private Color preferedColor = DEFAULT_COLOR;
35 private int version = DEFAULT_VERSION;
36 private String exampleType = DEFAULT_EXAMPLE_TYPE;
37
38 private String userInfoStr = "UserInfo";
39 private String versionStr = "VersionInfo";
40 private String theoryStr = "Theory";
41 private String exampleTypeStr = "ExampleType";
42
43 private BorderLayout borderLayout1 = new BorderLayout();
44 private JPanel buttonPanel = new JPanel();
45 private JButton jButton1 = new JButton();
46 private JButton jButton2 = new JButton();
47 private JButton jButton3 = new JButton();
48 private JScrollPane jScrollPane1;
49 private JTable infoTable;
50 private TableColumn column = null;
51 private InfoModel tableModel;
52
53 private int[] selection; //one selection record.
54 private Integer selectionLen;
55 private Vector selections = new Vector(); //All selection records.
56 private Vector selectedRecords = new Vector();
57 private Color[] multipleSelectionColors = new Color[4];
58 private int numObvs;
59 private int[] classification;
60 private Vector oneRecord = new Vector(4);//One record for selection, but with display of selection (# of selected obvs) instead of real selection.
61 private Vector categoryRecords = new Vector(); //records for selection or classification events.
62 transient private EventListenerList listenerList = new EventListenerList();
63
64 public CategoryRecords()
65 {
66 try
67 {
68 jbInit();
69 }
70 catch(Exception ex)
71 {
72 ex.printStackTrace();
73 }
74 }
75 void jbInit() throws Exception
76 {
77 this.setLayout(borderLayout1);
78 jButton1.setText("SAVE");
79 jButton2.setText("DELETE");
80 jButton3.setText("DISPLAY");
81
82 jButton1.addActionListener(new java.awt.event.ActionListener() {
83 /***
84 * put your documentation comment here
85 * @param e
86 */
87 public void actionPerformed (ActionEvent e) {
88 saveButton_actionPerformed(e);
89 }
90 });
91 jButton2.addActionListener(new java.awt.event.ActionListener() {
92 /***
93 * put your documentation comment here
94 * @param e
95 */
96 public void actionPerformed (ActionEvent e) {
97 delButton_actionPerformed(e);
98 }
99 });
100 jButton3.addActionListener(new java.awt.event.ActionListener() {
101 /***
102 * put your documentation comment here
103 * @param e
104 */
105 public void actionPerformed (ActionEvent e) {
106 displayButton_actionPerformed(e);
107 }
108 });
109
110 buttonPanel.add(jButton1, null);
111 buttonPanel.add(jButton2, null);
112 buttonPanel.add(jButton3, null);
113
114 //InfoTableModel tableModel = new InfoTableModel();
115 tableModel = new InfoModel();
116 infoTable = new JTable(tableModel);
117
118 infoTable.setRowSelectionAllowed(true);
119 infoTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
120
121 //Set up renderer and editor for the Favorite Color column.
122 setUpColorRenderer(infoTable);
123 setUpColorEditor(infoTable);
124
125 //Set up real input validation for integer data.
126 //setUpIntegerEditor(infoTable);
127
128 //Set up column sizes.
129 //initColumnSizes(infoTable, tableModel);
130
131 this.setUpSelectionColumn(infoTable.getColumnModel().getColumn(2));
132 //Fiddle with the exampleType column's cell editors/renderers.
133 setUpExampleColumn(infoTable.getColumnModel().getColumn(3));
134
135 jScrollPane1 = new JScrollPane(infoTable);
136
137 this.add(jScrollPane1, BorderLayout.CENTER);
138
139 this.add(buttonPanel, BorderLayout.SOUTH);
140 }
141
142 public void setSelection(int[] selection){
143 this.oneRecord.clear();
144 this.selection = selection;
145 this.selectionLen = new Integer(this.selection.length);
146 this.oneRecord.add(System.getProperty("user.name"));
147 this.oneRecord.add(this.preferedColor);
148 this.oneRecord.add(selectionLen);
149 this.oneRecord.add(this.DEFAULT_EXAMPLE_TYPE);
150 this.selections.addElement(this.selection.clone());
151 this.tableModel.updateRecord(oneRecord);
152 }
153
154 public int[] getSelection(){
155 //System.out.println("getSelection... in categoryRecords");
156 return this.selection;
157 }
158
159 public void setSelectedRecords(Vector selectedRecords){
160 this.selectedRecords = selectedRecords;
161 }
162
163 public Vector getSelectedRocords(){
164 return this.selectedRecords;
165 }
166
167 public void setDataObject(Object[] dataObject){
168 DataSetForApps data = new DataSetForApps();
169 data.setDataObject(dataObject);
170 this.numObvs = data.getNumObservations();
171 this.multipleSelectionColors = new Color[this.numObvs];
172 }
173
174 public void setMultipleSelectionColors(Color[] selectionColors){
175 this.multipleSelectionColors = selectionColors;
176 }
177
178 public Color[] getMultipleSelectionColors(){
179 //System.out.println("getDisplaySelection... in categoryRecords");
180 return this.multipleSelectionColors;
181 }
182
183 public void setCategoryRecords(Vector cateRecords){
184 this.categoryRecords = cateRecords;
185 Vector dataRecords = new Vector();
186 //Transfer the selections to the length of each selection for data in table.
187 for (int i = 0; i < categoryRecords.size(); i ++){
188 dataRecords.add(i, ((Vector)(categoryRecords.elementAt(i))).clone());
189 this.selections.add(((Vector)(categoryRecords.elementAt(i))).elementAt(2));
190 ((Vector)(dataRecords.elementAt(i))).setElementAt(new Integer((((int[])this.selections.elementAt(i)).length)), 2);
191 }
192 dataRecords.trimToSize();
193 this.tableModel.data = dataRecords;
194 }
195
196 public Vector getCategoryRecords(){
197 return categoryRecords;
198 }
199
200 private void saveButton_actionPerformed(ActionEvent e){
201 //Transfer the data in table to categoryRecords for save.
202 //The selection records should be saved in categoryRecords.
203 Vector dataRecords = new Vector();
204 dataRecords = this.tableModel.data;
205 //this.categoryRecords = (Vector)dataRecords.clone();
206 for (int i = 0; i < dataRecords.size(); i ++){
207 this.categoryRecords.add(i, ((Vector)(dataRecords.elementAt(i))).clone());
208 ((Vector)(this.categoryRecords.elementAt(i))).setElementAt(this.selections.get(i), 2);
209 System.out.println("selection i: " + ((int[])((Vector)(this.categoryRecords.elementAt(i))).get(2)).length);
210 }
211 this.categoryRecords.trimToSize();
212 fireChangeEvent();
213 }
214
215 private void delButton_actionPerformed(ActionEvent e){
216 int[] selectedRows = this.infoTable.getSelectedRows();
217 this.tableModel.deleteRows(selectedRows);
218 for (int i = 0; i < selectedRows.length; i++){
219 selections.removeElementAt(selectedRows[i]);
220 }
221 }
222
223 private void displayButton_actionPerformed(ActionEvent e){
224 for (int i = 0; i < this.multipleSelectionColors.length; i ++){
225 this.multipleSelectionColors[i] = null;
226 }
227 int[] selectedRows = this.infoTable.getSelectedRows();
228 System.out.println("selected rows: " + selectedRows.toString());
229 for (int i = 0; i < selectedRows.length; i++){
230 this.selectedRecords.add(this.tableModel.data.get(selectedRows[i]));
231 //set up colors for different selections.
232 Color selectionColor = (Color)((Vector)((this.tableModel.data.get(selectedRows[i])))).get(1);
233 int[] currentSelection = (int[])(selections.get(selectedRows[i]));
234 for (int j = 0; j < currentSelection.length; j++){
235 if (this.multipleSelectionColors[currentSelection[j]] == null){
236 this.multipleSelectionColors[currentSelection[j]] = selectionColor;
237 System.out.println("Color null: " + currentSelection[j] + selectionColor.toString());
238 } else {
239 Color formerColor = this.multipleSelectionColors[currentSelection[j]];
240 Color newColor = ColorInterpolator.mixColorsRGB(formerColor,selectionColor);
241 this.multipleSelectionColors[currentSelection[j]] = newColor;
242 System.out.println("Color mix: " + currentSelection[j] + newColor.toString());
243 }
244 }
245 }
246 fireSelectionChanged(getMultipleSelectionColors());
247 fireChangeEvent();
248 }
249
250 class ColorRenderer extends JLabel
251 implements TableCellRenderer {
252 Border unselectedBorder = null;
253 Border selectedBorder = null;
254 boolean isBordered = true;
255
256 public ColorRenderer(boolean isBordered) {
257 super();
258 this.isBordered = isBordered;
259 setOpaque(true); //MUST do this for background to show up.
260 }
261
262 public Component getTableCellRendererComponent(
263 JTable table, Object color,
264 boolean isSelected, boolean hasFocus,
265 int row, int column) {
266 setBackground((Color)color);
267 if (isBordered) {
268 if (isSelected) {
269 if (selectedBorder == null) {
270 selectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
271 table.getSelectionBackground());
272 }
273 setBorder(selectedBorder);
274 } else {
275 if (unselectedBorder == null) {
276 unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
277 table.getBackground());
278 }
279 setBorder(unselectedBorder);
280 }
281 }
282 return this;
283 }
284 }
285
286 private void setUpColorRenderer(JTable table) {
287 table.setDefaultRenderer(Color.class,
288 new ColorRenderer(true));
289 }
290
291 //Set up the editor for the Color cells.
292 private void setUpColorEditor(JTable table) {
293
294 //First, set up the button that brings up the dialog.
295 final JButton button = new JButton("") {
296 public void setText(String s) {
297 //Button never shows text -- only color.
298 }
299 };
300 button.setBackground(Color.white);
301 button.setBorderPainted(false);
302 button.setMargin(new Insets(0,0,0,0));
303
304 //Now create an editor to encapsulate the button, and
305 //set it up as the editor for all Color cells.
306 final ColorEditor colorEditor = new ColorEditor(button);
307 table.setDefaultEditor(Color.class, colorEditor);
308
309 //Set up the dialog that the button brings up.
310 final JColorChooser colorChooser = new JColorChooser();
311 ActionListener okListener = new ActionListener() {
312 public void actionPerformed(ActionEvent e) {
313 colorEditor.currentColor = colorChooser.getColor();
314 }
315 };
316 final JDialog dialog = JColorChooser.createDialog(button,
317 "Pick a Color",
318 true,
319 colorChooser,
320 okListener,
321 null); //XXXDoublecheck this is OK
322
323 //Here's the code that brings up the dialog.
324 button.addActionListener(new ActionListener() {
325 public void actionPerformed(ActionEvent e) {
326 button.setBackground(colorEditor.currentColor);
327 colorChooser.setColor(colorEditor.currentColor);
328 //Without the following line, the dialog comes up
329 //in the middle of the screen.
330 //dialog.setLocationRelativeTo(button);
331 dialog.show();
332 }
333 });
334 }
335
336 /*
337 * The editor button that brings up the dialog.
338 * We extend DefaultCellEditor for convenience,
339 * even though it mean we have to create a dummy
340 * check box. Another approach would be to copy
341 * the implementation of TableCellEditor methods
342 * from the source code for DefaultCellEditor.
343 */
344 class ColorEditor extends DefaultCellEditor {
345 Color currentColor = null;
346
347 public ColorEditor(JButton b) {
348 super(new JCheckBox()); //Unfortunately, the constructor
349 //expects a check box, combo box,
350 //or text field.
351 editorComponent = b;
352 setClickCountToStart(1); //This is usually 1 or 2.
353
354 //Must do this so that editing stops when appropriate.
355 b.addActionListener(new ActionListener() {
356 public void actionPerformed(ActionEvent e) {
357 fireEditingStopped();
358 }
359 });
360 }
361
362 protected void fireEditingStopped() {
363 super.fireEditingStopped();
364 }
365
366 public Object getCellEditorValue() {
367 return currentColor;
368 }
369
370 public Component getTableCellEditorComponent(JTable table,
371 Object value,
372 boolean isSelected,
373 int row,
374 int column) {
375 ((JButton)editorComponent).setText(value.toString());
376 currentColor = (Color)value;
377 return editorComponent;
378 }
379 }
380
381 private void setUpIntegerEditor(JTable table) {
382 //Set up the editor for the integer cells.
383 final WholeNumberField integerField = new WholeNumberField(0, 5);
384 integerField.setHorizontalAlignment(WholeNumberField.RIGHT);
385
386 DefaultCellEditor integerEditor =
387 new DefaultCellEditor(integerField) {
388 //Override DefaultCellEditor's getCellEditorValue method
389 //to return an Integer, not a String:
390 public Object getCellEditorValue() {
391 return new Integer(integerField.getValue());
392 }
393 };
394 table.setDefaultEditor(Integer.class, integerEditor);
395 }
396
397 private void setUpSelectionColumn(TableColumn selectionColumn){
398 final JButton selButton = new JButton("") {
399 public void setText(String s) {
400 s = "selection";
401 }
402 };
403
404 selButton.setBackground(Color.white);
405 selButton.setBorderPainted(false);
406 selButton.setMargin(new Insets(0,0,0,0));
407 //Now create an editor to encapsulate the button, and
408 //set it up as the editor for all selection cells.
409 final SelectionEditor selectionEditor = new SelectionEditor(selButton);
410 selectionColumn.setCellEditor(selectionEditor);
411
412 //Set up tool tips for the selection cells.
413 DefaultTableCellRenderer renderer =
414 new DefaultTableCellRenderer();
415 renderer.setToolTipText("Click for selection display");
416 selectionColumn.setCellRenderer(renderer);
417
418 selButton.addActionListener(new ActionListener() {
419 public void actionPerformed(ActionEvent e) {
420 selection = (int[])selections.get(infoTable.getSelectedRow());
421 fireChangeEvent();
422 fireSelectionChanged(getSelection());
423 }
424 });
425 }
426
427 /*
428 * The editor button that brings up the selection event.
429 * We extend DefaultCellEditor for convenience,
430 * even though it mean we have to create a dummy
431 * check box. Another approach would be to copy
432 * the implementation of TableCellEditor methods
433 * from the source code for DefaultCellEditor.
434 */
435 class SelectionEditor extends DefaultCellEditor {
436 int[] selection = null;
437
438 public SelectionEditor(JButton b) {
439 super(new JCheckBox()); //Unfortunately, the constructor
440 //expects a check box, combo box,
441 //or text field.
442 editorComponent = b;
443 setClickCountToStart(1); //This is usually 1 or 2.
444
445 //Must do this so that editing stops when appropriate.
446 b.addActionListener(new ActionListener() {
447 public void actionPerformed(ActionEvent e) {
448 fireEditingStopped();
449 }
450 });
451 }
452
453 protected void fireEditingStopped() {
454 super.fireEditingStopped();
455 }
456
457 public Object getCellEditorValue() {
458 return selection;
459 }
460
461 public Component getTableCellEditorComponent(JTable table,
462 Object value,
463 boolean isSelected,
464 int row,
465 int column) {
466 ((JButton)editorComponent).setText(value.toString());
467 //selection = (int[])value;
468 selectionLen = (Integer)value;
469 return editorComponent;
470 }
471 }
472
473 private void setUpExampleColumn(TableColumn exampleColumn) {
474 //Set up the editor for the sport cells.
475 JComboBox comboBox = new JComboBox();
476 comboBox.addItem("Central");
477 comboBox.addItem("Boundary");
478 comboBox.addItem("Ideal mean");
479 comboBox.addItem("Not clear");
480 exampleColumn.setCellEditor(new DefaultCellEditor(comboBox));
481
482 //Set up tool tips for the selection cells.
483 DefaultTableCellRenderer renderer =
484 new DefaultTableCellRenderer();
485 renderer.setToolTipText("Click for combo box");
486 exampleColumn.setCellRenderer(renderer);
487
488 //Set up tool tip for the selection column header.
489 TableCellRenderer headerRenderer = exampleColumn.getHeaderRenderer();
490 if (headerRenderer instanceof DefaultTableCellRenderer) {
491 ((DefaultTableCellRenderer)headerRenderer).setToolTipText(
492 "Click the example to see a list of choices");
493 }
494 }
495
496 public void stateChanged (ChangeEvent e) {
497 JButton button = (JButton)e.getSource();
498 }
499 /***
500 * put your documentation comment here
501 * @param l
502 */
503 public void addChangeListener (ChangeListener l) {
504 this.listenerList.add(ChangeListener.class, l);
505 }
506
507 /***
508 * put your documentation comment here
509 * @param l
510 */
511 public void removeChangeListener (ChangeListener l) {
512 this.listenerList.remove(ChangeListener.class, l);
513 }
514
515 /***
516 * put your documentation comment here
517 */
518 private void fireChangeEvent () {
519 Object[] listeners = this.listenerList.getListenerList();
520 // Process the listeners last to first, notifying
521 // those that are interested in this event
522 for (int i = listeners.length - 2; i >= 0; i -= 2) {
523 if (listeners[i] == ChangeListener.class) {
524 ((ChangeListener)listeners[i + 1]).stateChanged(new ChangeEvent(this));
525 }
526 } // end for
527 }
528
529 //Work with coordinator.
530 public void dataSetChanged(DataSetEvent e){
531 this.setDataObject(e.getDataSet());
532 }
533
534 public void selectionChanged(SelectionEvent e){
535 this.setSelection(e.getSelection());
536 }
537
538 /***
539 * adds an SelectionListener
540 */
541 public void addSelectionListener (SelectionListener l) {
542 listenerList.add(SelectionListener.class, l);
543 }
544 /***
545 * removes an SelectionListener from the component
546 */
547 public void removeSelectionListener (SelectionListener l) {
548 listenerList.remove(SelectionListener.class, l);
549
550 }
551 /***
552 * Notify all listeners that have registered interest for
553 * notification on this event type. The event instance
554 * is lazily created using the parameters passed into
555 * the fire method.
556 * @see EventListenerList
557 */
558 private void fireSelectionChanged (int[] newSelection) {
559
560 // Guaranteed to return a non-null array
561 Object[] listeners = listenerList.getListenerList();
562 SelectionEvent e = null;
563 // Process the listeners last to first, notifying
564 // those that are interested in this event
565 for (int i = listeners.length - 2; i >= 0; i -= 2) {
566 if (listeners[i] == SelectionListener.class) {
567 // Lazily create the event:
568 if (e == null) {
569 e = new SelectionEvent(this, newSelection);
570 }
571 ((SelectionListener)listeners[i + 1]).selectionChanged(e);
572 }
573 }//next i
574
575 }
576
577 private void fireSelectionChanged (Color[] newSelection) {
578
579 // Guaranteed to return a non-null array
580 Object[] listeners = listenerList.getListenerList();
581 SelectionEvent e = null;
582 // Process the listeners last to first, notifying
583 // those that are interested in this event
584 for (int i = listeners.length - 2; i >= 0; i -= 2) {
585 if (listeners[i] == SelectionListener.class) {
586 // Lazily create the event:
587 if (e == null) {
588 e = new SelectionEvent(this, newSelection);
589 }
590 ((SelectionListener)listeners[i + 1]).selectionChanged(e);
591 }
592 }//next i
593
594 }
595 }
This page was automatically generated by Maven