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 groupMap = new WeakHashMap();
  61: 
  62:   public native void createCheckButton ();
  63:   public native void createRadioButton (long groupPointer);
  64: 
  65:   public native void addToGroup (long groupPointer);
  66:   public native void removeFromGroup ();
  67:   public native void switchToGroup (long groupPointer);
  68:   
  69:   public native void connectSignals ();
  70: 
  71:   /**
  72:    * Overridden to set Font of label inside button.
  73:    */
  74:   protected native void gtkWidgetModifyFont(String name, int style, int size);
  75:   native void gtkButtonSetLabel (String label);
  76:   native void gtkToggleButtonSetActive (boolean is_active);
  77: 
  78:   public GtkCheckboxPeer (Checkbox c)
  79:   {
  80:     super (c);
  81:   }
  82: 
  83:   public void create ()
  84:   {
  85:     Checkbox checkbox = (Checkbox) awtComponent;
  86:     current_group = checkbox.getCheckboxGroup ();
  87:     if (current_group == null)
  88:       {
  89:         // Initially we're not part of a group so we're backed by a
  90:         // GtkCheckButton.
  91:         createCheckButton();
  92:       }
  93:     else
  94:       {
  95:         // Initially we're part of a group.
  96: 
  97:         // See if this group is already stored in our map.
  98:         Long groupPointer = null;
  99:         synchronized (groupMap)
 100:         {
 101:           groupPointer = (Long) groupMap.get(current_group);
 102:         }
 103:         
 104:         if (groupPointer == null)
 105:           {
 106:             // We don't know about this group.  Create a new native
 107:             // group pointer for this group and store it in our map.
 108:            createRadioButton(0);
 109:           }
 110:         else
 111:           {
 112:             // We already know about this group.  Pass the
 113:             // corresponding native group pointer value to the native
 114:             // create method.
 115:             createRadioButton(groupPointer.longValue());
 116:           }
 117:       }
 118:     currentState = checkbox.getState();
 119:     gtkToggleButtonSetActive(currentState);
 120:     
 121:     String label = checkbox.getLabel();
 122:     if (label != null)
 123:       gtkButtonSetLabel(label);
 124:   }
 125: 
 126:   /**
 127:    * Sets native GtkCheckButton is state is different from current
 128:    * state.  Will set currentState to state to prevent posting an
 129:    * event since events should only be posted for user initiated
 130:    * clicks on the GtkCheckButton.
 131:    */
 132:   public synchronized void setState (boolean state)
 133:   {
 134:     if (currentState != state)
 135:       {
 136:     currentState = state;
 137:     gtkToggleButtonSetActive(state);
 138:       }
 139:   }
 140: 
 141:   public void setLabel (String label)
 142:   {
 143:     gtkButtonSetLabel (label);
 144:   }
 145: 
 146:   public void setCheckboxGroup (CheckboxGroup group)
 147:   {
 148:     if (current_group == null && group != null)
 149:       {
 150:         // This peer's owner is currently not in a group, and now
 151:         // we're adding it to a group.  This means that the backing
 152:         // GtkWidget will change from a GtkCheckButton to a
 153:         // GtkRadioButton.
 154: 
 155:         current_group = group;
 156: 
 157:         // See if the new group is already stored in our map.
 158:         Long groupPointer = null;
 159:         synchronized (groupMap)
 160:         {
 161:           groupPointer = (Long) groupMap.get(current_group);
 162:         }
 163:         
 164:         if (groupPointer == null)
 165:           {
 166:             // We don't know about this group.  Create a new native
 167:             // group pointer for this group and store it in our map.
 168:             addToGroup(0);
 169:           }
 170:         else
 171:           {
 172:             // We already know about this group.  Pass the
 173:             // corresponding native group pointer value to the native
 174:             // create method.
 175:             addToGroup(groupPointer.longValue());
 176:           }
 177:       }
 178:     else if (current_group != null && group == null)
 179:       {
 180:         // This peer's owner is currently in a group, and now we're
 181:         // removing it from a group.  This means that the backing
 182:         // GtkWidget will change from a GtkRadioButton to a
 183:         // GtkCheckButton.
 184:         removeFromGroup();
 185:         current_group = null;
 186:       }
 187:     else if (current_group == null && group == null)
 188:       {
 189:         // This peer's owner is currently not in a group, and we're
 190:         // not adding it to a group, so simply return.
 191:         return;
 192:       }
 193:     else if (current_group != group)
 194:       {
 195:         // This peer's owner is currently in a group, and now we're
 196:         // putting it in another group.  This means that we must
 197:         // remove the backing GtkRadioButton from one group and add it
 198:         // to the other group.
 199: 
 200:         current_group = group;
 201:         
 202:         // See if the new group is already stored in our map.
 203:         Long groupPointer = null;
 204:         synchronized (groupMap)
 205:         {
 206:           groupPointer = (Long) groupMap.get(current_group);
 207:         }
 208:         
 209:         if (groupPointer == null)
 210:           {
 211:             // We don't know about this group.  Create a new native
 212:             // group pointer for this group and store it in our map.
 213:             switchToGroup(0);
 214:           }
 215:         else
 216:           {
 217:             // We already know about this group.  Pass the
 218:             // corresponding native group pointer value to the native
 219:             // create method.
 220:             switchToGroup(groupPointer.longValue());
 221:           }
 222:       }
 223:   }
 224: 
 225:   // Override the superclass postItemEvent so that the peer doesn't
 226:   // need information that we have.
 227:   // called back by native side: item_toggled_cb
 228:   public synchronized void postItemEvent(Object item, boolean state)
 229:   {
 230:     // Only fire event is state actually changed.
 231:     if (currentState != state)
 232:       {
 233:     currentState = state;
 234:     super.postItemEvent(awtComponent,
 235:                 state ? ItemEvent.SELECTED : ItemEvent.DESELECTED);
 236:       }
 237:   }
 238:   
 239:   public void addToGroupMap(long groupPointer)
 240:   {
 241:     synchronized (groupMap)
 242:     {
 243:       groupMap.put(current_group, new Long (groupPointer));
 244:     }
 245:   }
 246: 
 247:   public void dispose ()
 248:   {
 249:     groupMap.clear();
 250:     current_group = null;
 251:     currentState = false;
 252:     super.dispose ();
 253:   }
 254: }