Revision 21273

View differences:

trunk/extensions/extTopology/src/org/gvsig/gui/JComboBoxWithDisabledItems.java
1
/*
2
 * Created on 10-abr-2006
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
*
46
* $Id: 
47
* $Log: 
48
*/
49
package org.gvsig.gui;
50

  
51
import java.awt.Component;
52
import java.awt.event.ActionEvent;
53
import java.awt.event.ActionListener;
54
import java.util.Vector;
55

  
56
import javax.swing.ComboBoxModel;
57
import javax.swing.JComboBox;
58
import javax.swing.JLabel;
59
import javax.swing.JList;
60
import javax.swing.ListCellRenderer;
61
import javax.swing.UIManager;
62
import javax.swing.border.EmptyBorder;
63

  
64
/**
65
 * Implementation of JComboBox that allows us to enable/disable
66
 * individual items of the JComboBox.
67
 * 
68
 * Based in the work of Nobuo Tamemasa, in 
69
 * http://www.codeguru.com/java/articles/165.shtml
70
 * 
71
 * 
72
 * @author Alvaro Zabala
73
 *
74
 */
75
public class JComboBoxWithDisabledItems extends JComboBox {
76
	
77
	private static final long serialVersionUID = -1375989245835223722L;
78
	
79
	public JComboBoxWithDisabledItems(){
80
		super();
81
//		initialize();
82
	}
83
	
84
	public JComboBoxWithDisabledItems(ComboBoxModel model){
85
		super(model);
86
		initialize();
87
	}
88
	
89
	public JComboBoxWithDisabledItems(Object[] items){
90
		super(items);
91
		initialize();
92
	}
93
	
94
	public JComboBoxWithDisabledItems(Vector<?> items){
95
		super(items);
96
		initialize();
97
	}
98
	
99
	
100
	public void initialize(){
101
		setRenderer(new ComboRenderer());
102
	    addActionListener(new ComboListener(this));
103
	}
104

  
105
	public void addItem(Object item){
106
		if(item instanceof ComboItem){
107
			super.addItem(item);
108
		}else{
109
			ComboItem newItem = new ComboItem(item);
110
			newItem.setEnabled(true);
111
			super.addItem(newItem);
112
		}
113
	}
114
	
115
	public Object getItemAt(int index){
116
		ComboItem item = (ComboItem) super.getItemAt(index);
117
		return item.obj;
118
	}
119
	
120
	public Object getSelectedItem(){
121
		ComboItem item = (ComboItem) super.getSelectedItem();
122
		return item.obj;
123
	}
124
	
125
	public void setItemEnable(int index, boolean enabled){
126
		ComboItem item = (ComboItem) super.getItemAt(index);
127
		item.isEnable = enabled;
128
	}
129
	
130
	public boolean isItemEnabled(int index){
131
		if(index >= 0){
132
			ComboItem item = (ComboItem) super.getItemAt(index);
133
			return item.isEnable;
134
		}else
135
			return false;
136
	}
137
	/**
138
	 * Combo box renderer.
139
	 * 
140
	 * @author Alvaro Zabala
141
	 *
142
	 */
143
	class ComboRenderer extends JLabel implements ListCellRenderer {
144
		private static final long serialVersionUID = 4216706963467674095L;
145

  
146
		public ComboRenderer() {
147
	      setOpaque(true);
148
	      setBorder(new EmptyBorder(1, 1, 1, 1));
149
	    }
150

  
151
	    public Component getListCellRendererComponent( JList list, 
152
	           Object value, int index, boolean isSelected, boolean cellHasFocus) {
153
	      if (isSelected) {
154
	        setBackground(list.getSelectionBackground());
155
	        setForeground(list.getSelectionForeground());
156
	      } else {
157
	        setBackground(list.getBackground());
158
	        setForeground(list.getForeground());
159
	      } 
160
//	      if (! ((ComboItem)value).isEnabled()) {
161
	      if(! isItemEnabled(index)){
162
	        setBackground(list.getBackground());
163
	        setForeground(UIManager.getColor("Label.disabledForeground"));
164
	      }else{
165
	    	  setBackground(list.getBackground());
166
		      setForeground(list.getForeground());
167
	      }
168
	      setFont(list.getFont());
169
	      setText((value == null) ? "" : value.toString());
170
	      return this;
171
	    }
172

  
173
	  }
174
	
175
	  
176
	/**
177
	 * Listens for combo box selection events.
178
	 * 
179
	 * It the new selected items are not enabled, the combo box
180
	 * will remain unchanged.
181
	 * 
182
	 * @author Alvaro Zabala
183
	 *
184
	 */
185
	  class ComboListener implements ActionListener {
186
	    JComboBox combo;
187
	    Object currentItem;
188
	    
189
	    ComboListener(JComboBox combo) {
190
	      this.combo  = combo;
191
	      combo.setSelectedIndex(0);
192
	      currentItem = combo.getSelectedItem();
193
	    }
194
	    
195
	    public void actionPerformed(ActionEvent e) {
196
	      Object tempItem = combo.getSelectedItem();
197
	      int selectedIndex = combo.getSelectedIndex();
198
	      //If the selected item in the combo box is enable,
199
	      //the combo will change. If not, the selected item
200
	      //will be the previous selected item
201
//	      if (! ((ComboItem)tempItem).isEnabled()) {
202
	      if(isItemEnabled(selectedIndex)){
203
	        combo.setSelectedItem(currentItem);
204
	      } else {
205
	        currentItem = tempItem;
206
	      }
207
	    }
208
	  }//ComboListener
209
	  
210
	  /**
211
	   * Combo box item that allows to enabling / disabling combo 
212
	   * box entries.
213
	   * 
214
	   * @author Alvaro Zabala
215
	   *
216
	   */
217
	  class ComboItem  {
218
	    Object  obj;
219
	    boolean isEnable;
220
	    
221
	    ComboItem(Object obj,boolean isEnable) {
222
	      this.obj      = obj;
223
	      this.isEnable = isEnable;
224
	    }
225
	    
226
	    ComboItem(Object obj) {
227
	      this(obj, true);
228
	    }
229
	    
230
	    public boolean isEnabled() {
231
	      return isEnable;
232
	    }
233
	    
234
	    public void setEnabled(boolean isEnable) {
235
	      this.isEnable = isEnable;
236
	    }
237
	    
238
	    public String toString() {
239
	      return obj.toString();
240
	    }
241
	  }
242
}
trunk/extensions/extTopology/src/org/gvsig/gui/ModalDialog.java
1
/*#########################################################################
2
 *
3
 * A component of the Gatherer application, part of the Greenstone digital
4
 * library suite from the New Zealand Digital Library Project at the
5
 * University of Waikato, New Zealand.
6
 *
7
 * Author: John Thompson, Greenstone Digital Library, University of Waikato
8
 *
9
 * Copyright (C) 1999 New Zealand Digital Library Project
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
 *########################################################################
25
 */
26
package org.gvsig.gui;
27

  
28
import java.awt.*;
29
import java.awt.event.*;
30
import javax.swing.*;
31

  
32

  
33

  
34
/** An extension of the JDialog that overrides the JVM's typical modal behaviour. This typical behaviour is that when a modal dialog is opened, all other windows cease to respond to user events until the modal dialog is disposed. However this prevents us opening the help documents property whenever a modal dialog is open. Thus we override the modal behaviour so that only the owner frame or dialog is blocked. 
35
 * Note that because we always call the super constructor with modal set to false, this should be made visible with setVisible(true) rather than show() which will return straight away. */
36
// feedback note: veronika had changed all the super constructor calls to 
37
// use modal instead of false - not sure if this is needed so I have not 
38
// put that in. --kjdon
39
public class ModalDialog
40
    extends JDialog {
41

  
42
    /**
43
	 * 
44
	 */
45
	private static final long serialVersionUID = 6966218812722673601L;
46

  
47
	/** The current modal dialog being shown on screen, if any. */
48
    static public ModalDialog current_modal = null;
49

  
50
    /** true if this dialog should be modal, ie block user actions to its owner window, false otherwise. */
51
    protected boolean modal = false;
52
    /** true if this dialog is currently waiting some thread. */
53
    protected boolean waiting = false;
54

  
55
    /** Constructor.
56
     */
57
    public ModalDialog() {
58
	super((Frame)null, "", false);
59
    }
60

  
61
    /** Constructor.
62
     * @param parent the Dialog which is the owener of this dialog.
63
    */
64
    public ModalDialog(Dialog parent) {
65
	super(parent, "", false);
66
    }
67

  
68
    /** Constructor.
69
     * @param parent the Dialog which is the owener of this dialog.
70
     * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
71
     */
72
    public ModalDialog(Dialog parent, boolean modal) {
73
	super(parent, "", false);
74
	this.modal = modal;
75
    }
76
    
77
    /** Constructor.
78
     * @param parent the Dialog which is the owner of this dialog.
79
     * @param title the String to use as the title for this dialog.
80
     */
81
    public ModalDialog(Dialog parent, String title) {
82
	super (parent, title, false);
83
	this.modal = false;
84
    }
85

  
86
    /** Constructor.
87
     * @param parent the Dialog which is the owener of this dialog.
88
     * @param title the String to use as the title for this dialog.
89
     * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
90
     */
91
    public ModalDialog(Dialog parent, String title, boolean modal) {
92
	super (parent, title, false);
93
	this.modal = modal;
94
    }
95

  
96
   /** Constructor.
97
     * @param parent the Frame which is the owener of this dialog.
98
     */
99
    public ModalDialog(Frame parent) {
100
	super(parent, "", false);
101
    }
102

  
103
    /** Constructor.
104
     * @param parent the Frame which is the owener of this dialog.
105
     * @param modal whether this dialog is modal or not
106
     */
107
    public ModalDialog(Frame parent, boolean modal) {
108
	super(parent, "", false);
109
	this.modal = modal;
110
    }
111
    
112
    /** Constructor.
113
     * @param parent the Frame which is the owner of this dialog.
114
     * @param title the String to use as the title for this dialog.
115
     */
116
    public ModalDialog(Frame parent, String title) {
117
	super (parent, title, false);
118
    }
119

  
120
    /** Constructor.
121
     * @param parent the Frame which is the owener of this dialog.
122
     * @param title the String to use as the title for this dialog.
123
     * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
124
     */
125
    public ModalDialog(Frame parent, String title, boolean modal) {
126
	super (parent, title, false);
127
	this.modal = modal;
128
    }
129

  
130
    public void dispose() {
131
	super.dispose();
132
    }
133

  
134
    /** Ensures the current dialog is visible. */
135
    public void makeVisible() {
136
	super.setVisible(true);
137
    }
138

  
139
    /** The set visible method is overriden to provide modal functionality. It essentially hijacks control of the event dispatch thread while the dialog is open, only allowing non-user events to be passed to the parent dialog. Furthermore it only has this effect within the current AWT component tree by utilitizing the TreeLock.
140
     * @param visible true if this dialog should be painted on-screen, false otherwise.
141
     */
142
    public void setVisible(boolean visible)
143
    {
144
	if (visible) {
145
	    current_modal = this;
146
	}
147
	else {
148
	    current_modal = null;
149
	}
150

  
151
	// If we are in the AWT Dispatch thread then it is all good.
152
 	if (SwingUtilities.isEventDispatchThread()) {
153
 	    super.setVisible(visible);
154
	    if (modal && visible) {
155
		EventQueue theQueue = getToolkit().getSystemEventQueue();
156
		while (isVisible()) {
157
		    try {
158
			AWTEvent event = theQueue.getNextEvent();
159
			Object src = event.getSource();
160

  
161
			// Block all keyboard and mouse events to the parent component
162
			if (src.equals(getParent())) {
163
			    if (event instanceof KeyEvent || event instanceof MouseEvent) {
164
				// System.err.println("Event to parent component blocked.");
165
				continue;
166
			    }
167
			}
168

  
169
			// Re-dispatch other events
170
			if (event instanceof ActiveEvent) {
171
  			    ((ActiveEvent) event).dispatch();
172
  			}			    
173
			else if (src instanceof Component) {
174
			    ((Component) src).dispatchEvent(event);
175
			}
176
		    }
177
		    catch (Exception exception) {
178
		    	exception.printStackTrace();
179
		    }
180
		}
181
	    }
182
 	}
183
 	else {
184
 	    try {
185
 		SwingUtilities.invokeAndWait(new MakeDialogVisibleTask(this, visible));
186
 	    }
187
 	    catch (Exception exception) {
188
 	    	exception.printStackTrace();
189
 	    }
190
 	}
191
    }
192
    
193
    private class MakeDialogVisibleTask
194
	implements Runnable {
195
	private boolean make_visible;
196
	private ModalDialog dialog;
197
	public MakeDialogVisibleTask(ModalDialog dialog, boolean make_visible) {
198
	    this.dialog = dialog;
199
	    this.make_visible = make_visible;
200
	}
201
	public void run() {
202
	    // Blocks until the user dismisses the dialog
203
	    dialog.setVisible(make_visible);
204
	}
205
    }
206

  
207
    /** Overridden method so we can control modality and not rely on the Dialog default.
208
     * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
209
     */
210
    public void setModal (boolean modal) {
211
	this.modal = modal;
212
    }
213
}

Also available in: Unified diff