Source for gnu.java.awt.peer.gtk.GtkCheckboxPeer

   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: }