Frames | No Frames |
1: /* GtkCheckboxPeer.java -- Implements CheckboxPeer with GTK 2: Copyright (C) 1998, 1999, 2002, 2003, 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package gnu.java.awt.peer.gtk; 40: 41: import java.awt.Checkbox; 42: import java.awt.CheckboxGroup; 43: import java.awt.event.ItemEvent; 44: import java.awt.peer.CheckboxPeer; 45: import java.util.WeakHashMap; 46: 47: /** 48: * This class wraps either a GtkCheckButton or a GtkOptionButton 49: * depending on if this peer's owner belongs to a CheckboxGroup. 50: */ 51: public class GtkCheckboxPeer extends GtkComponentPeer 52: implements CheckboxPeer 53: { 54: // The CheckboxGroup to which this GtkCheckboxPeer's owner belongs. 55: public CheckboxGroup current_group; 56: // The current state of the GTK checkbox. 57: private boolean currentState; 58: 59: // A map from CheckboxGroup to GSList* GTK option group pointer. 60: private static WeakHashMap<CheckboxGroup,Long> groupMap 61: = new WeakHashMap<CheckboxGroup,Long>(); 62: 63: public native void createCheckButton (); 64: public native void createRadioButton (long groupPointer); 65: 66: public native void addToGroup (long groupPointer); 67: public native void removeFromGroup (); 68: public native void switchToGroup (long groupPointer); 69: 70: public native void connectSignals (); 71: 72: /** 73: * Overridden to set Font of label inside button. 74: */ 75: protected native void gtkWidgetModifyFont(String name, int style, int size); 76: native void gtkButtonSetLabel (String label); 77: native void gtkToggleButtonSetActive (boolean is_active); 78: 79: public GtkCheckboxPeer (Checkbox c) 80: { 81: super (c); 82: } 83: 84: public void create () 85: { 86: Checkbox checkbox = (Checkbox) awtComponent; 87: current_group = checkbox.getCheckboxGroup (); 88: if (current_group == null) 89: { 90: // Initially we're not part of a group so we're backed by a 91: // GtkCheckButton. 92: createCheckButton(); 93: } 94: else 95: { 96: // Initially we're part of a group. 97: 98: // See if this group is already stored in our map. 99: Long groupPointer = null; 100: synchronized (groupMap) 101: { 102: groupPointer = groupMap.get(current_group); 103: } 104: 105: if (groupPointer == null) 106: { 107: // We don't know about this group. Create a new native 108: // group pointer for this group and store it in our map. 109: createRadioButton(0); 110: } 111: else 112: { 113: // We already know about this group. Pass the 114: // corresponding native group pointer value to the native 115: // create method. 116: createRadioButton(groupPointer.longValue()); 117: } 118: } 119: currentState = checkbox.getState(); 120: gtkToggleButtonSetActive(currentState); 121: 122: String label = checkbox.getLabel(); 123: if (label != null) 124: gtkButtonSetLabel(label); 125: } 126: 127: /** 128: * Sets native GtkCheckButton is state is different from current 129: * state. Will set currentState to state to prevent posting an 130: * event since events should only be posted for user initiated 131: * clicks on the GtkCheckButton. 132: */ 133: public synchronized void setState (boolean state) 134: { 135: if (currentState != state) 136: { 137: currentState = state; 138: gtkToggleButtonSetActive(state); 139: } 140: } 141: 142: public void setLabel (String label) 143: { 144: gtkButtonSetLabel (label); 145: } 146: 147: public void setCheckboxGroup (CheckboxGroup group) 148: { 149: if (current_group == null && group != null) 150: { 151: // This peer's owner is currently not in a group, and now 152: // we're adding it to a group. This means that the backing 153: // GtkWidget will change from a GtkCheckButton to a 154: // GtkRadioButton. 155: 156: current_group = group; 157: 158: // See if the new group is already stored in our map. 159: Long groupPointer = null; 160: synchronized (groupMap) 161: { 162: groupPointer = groupMap.get(current_group); 163: } 164: 165: if (groupPointer == null) 166: { 167: // We don't know about this group. Create a new native 168: // group pointer for this group and store it in our map. 169: addToGroup(0); 170: } 171: else 172: { 173: // We already know about this group. Pass the 174: // corresponding native group pointer value to the native 175: // create method. 176: addToGroup(groupPointer.longValue()); 177: } 178: } 179: else if (current_group != null && group == null) 180: { 181: // This peer's owner is currently in a group, and now we're 182: // removing it from a group. This means that the backing 183: // GtkWidget will change from a GtkRadioButton to a 184: // GtkCheckButton. 185: removeFromGroup(); 186: current_group = null; 187: } 188: else if (current_group == null && group == null) 189: { 190: // This peer's owner is currently not in a group, and we're 191: // not adding it to a group, so simply return. 192: return; 193: } 194: else if (current_group != group) 195: { 196: // This peer's owner is currently in a group, and now we're 197: // putting it in another group. This means that we must 198: // remove the backing GtkRadioButton from one group and add it 199: // to the other group. 200: 201: current_group = group; 202: 203: // See if the new group is already stored in our map. 204: Long groupPointer = null; 205: synchronized (groupMap) 206: { 207: groupPointer = groupMap.get(current_group); 208: } 209: 210: if (groupPointer == null) 211: { 212: // We don't know about this group. Create a new native 213: // group pointer for this group and store it in our map. 214: switchToGroup(0); 215: } 216: else 217: { 218: // We already know about this group. Pass the 219: // corresponding native group pointer value to the native 220: // create method. 221: switchToGroup(groupPointer.longValue()); 222: } 223: } 224: } 225: 226: // Override the superclass postItemEvent so that the peer doesn't 227: // need information that we have. 228: // called back by native side: item_toggled_cb 229: public synchronized void postItemEvent(Object item, boolean state) 230: { 231: // Only fire event is state actually changed. 232: if (currentState != state) 233: { 234: currentState = state; 235: super.postItemEvent(awtComponent, 236: state ? ItemEvent.SELECTED : ItemEvent.DESELECTED); 237: } 238: } 239: 240: public void addToGroupMap(long groupPointer) 241: { 242: synchronized (groupMap) 243: { 244: groupMap.put(current_group, new Long (groupPointer)); 245: } 246: } 247: 248: public void dispose () 249: { 250: groupMap.clear(); 251: current_group = null; 252: currentState = false; 253: super.dispose (); 254: } 255: }