This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Refactoring of Choice


This patch fixes nothing, my previous patch fixed what was broken
already. Why the patch them? It moves tasks to where they belong in
the AWT peer architecture. It is just refactoring but nevertheless
important as it gives people a more accurate reference to base future implementation upon.


2003-12-24 Fernando Nasser <fnasser@redhat.com>

* java/awt/Choice.java (add): Leave posting of ItemEvents to peer.
(insert): Ditto.
(remove): Ditto. Also, Check for valid argument.
(removeAll): Use peer interface method.
* gnu/java/awt/peer/gtk/GtkChoicePeer.java (nativeAdd): New name for
native add function.
(nativeRemove): New name for native remove function.
(getHistory): New native function.
(constructor): Generate ItemEvent.
(add): Ditto, if selection is changed.
(remove): Ditto, ditto.
(removeAll): Add implementation.
(handleEvent): Remove. Dead code.
(choicePostItemEvent): Add comment.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
(Java_gnu_java_awt_peer_gtk_GtkChoicePeer_append): Add comments.
(Java_gnu_java_awt_peer_gtk_GtkChoicePeer_add): Rename to...
(Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeAdd): New name. Add
comments and fix condition to change selection.
(Java_gnu_java_awt_peer_gtk_GtkChoicePeer_remove): Rename to...
(Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeRemove): New name. Add
remove all capability.
(Java_gnu_java_awt_peer_gtk_GtkChoicePeer_getHistory): New function.
(item_activate): Add cast to remove compiler warning.



-- Fernando Nasser Red Hat Canada Ltd. E-Mail: fnasser@redhat.com 2323 Yonge Street, Suite #300 Toronto, Ontario M4P 2C9
Index: gnu/java/awt/peer/gtk/GtkChoicePeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java,v
retrieving revision 1.4
diff -c -p -u -r1.4 GtkChoicePeer.java
--- gnu/java/awt/peer/gtk/GtkChoicePeer.java	23 Dec 2003 19:23:59 -0000	1.4
+++ gnu/java/awt/peer/gtk/GtkChoicePeer.java	24 Dec 2003 20:44:49 -0000
@@ -38,6 +38,7 @@ exception statement from your version. *
 
 package gnu.java.awt.peer.gtk;
 
+import java.awt.AWTEvent;
 import java.awt.Choice;
 import java.awt.event.ItemEvent;
 import java.awt.peer.ChoicePeer;
@@ -59,35 +60,69 @@ public class GtkChoicePeer extends GtkCo
 	  items[i] = c.getItem (i);
 	  
 	append (items);
+
+        // Must set our state before notifying listeners
+	((Choice) awtComponent).select (c.getItem (0));
+	postItemEvent (c.getItem (0), ItemEvent.SELECTED);
       }
   }
 
   native void append (String items[]);
+  native int getHistory ();
 
-  native public void add (String item, int index);
-  native public void remove (int index);
+  native public void nativeAdd (String item, int index);
+  native public void nativeRemove (int index);
   native public void select (int position);
  
-  public void removeAll () { }
-  
-  public void addItem (String item, int position)
+  public void add (String item, int index)
   {
-    add (item, position);
+    int before = getHistory();
+    
+    nativeAdd (item, index);
+    
+    /* Generate an ItemEvent if we added the first one or
+       if we inserted at or before the currently selected item. */
+    if ((before < 0) || (before >= index))
+      {
+        // Must set our state before notifying listeners
+	((Choice) awtComponent).select (((Choice) awtComponent).getItem (0));
+        postItemEvent (((Choice) awtComponent).getItem (0), ItemEvent.SELECTED);
+      }
+  }
+
+  public void remove (int index)
+  {
+    int before = getHistory();
+    int after;
+    
+    nativeRemove (index);
+    after = getHistory();
+    
+    /* Generate an ItemEvent if we are removing the currently selected item
+       and there are at least one item left. */
+    if ((before == index) && (after >= 0))
+      {
+        // Must set our state before notifying listeners
+	((Choice) awtComponent).select (((Choice) awtComponent).getItem (0));
+        postItemEvent (((Choice) awtComponent).getItem (0), ItemEvent.SELECTED);
+      }
+  }
+
+  public void removeAll ()
+  {
+    nativeRemove (-1);
   }
   
-  /*
-  public void handleEvent (AWTEvent event)
+  public void addItem (String item, int position)
   {
-    if (event instanceof ItemEvent)
-      ((Choice) awtComponent).select ((String) ((ItemEvent)event).getItem ());
-    super.handleEvent (event);
+    add (item, position);
   }
-  */
 
   protected void choicePostItemEvent (String label, int stateChange)
   {
+    // Must set our state before notifying listeners
     if (stateChange == ItemEvent.SELECTED)
       ((Choice) awtComponent).select (label);
-    super.postItemEvent (label, stateChange);
+    postItemEvent (label, stateChange);
   }
 }
Index: java/awt/Choice.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Choice.java,v
retrieving revision 1.12
diff -c -p -u -r1.12 Choice.java
--- java/awt/Choice.java	23 Dec 2003 19:23:59 -0000	1.12
+++ java/awt/Choice.java	24 Dec 2003 20:44:49 -0000
@@ -169,17 +169,6 @@ add(String item)
       ChoicePeer cp = (ChoicePeer) peer;
       cp.add (item, i);
     }
-
-  if (i == 0)
-  {
-    selectedIndex = 0;
-    // We must generate an ItemEvent here
-    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent (
-      new ItemEvent ((ItemSelectable)this, 
-                     ItemEvent.ITEM_STATE_CHANGED,
-                     getItem(0),
-                     ItemEvent.SELECTED));
-  }
 }
 
 /*************************************************************************/
@@ -229,17 +218,6 @@ insert(String item, int index)
       ChoicePeer cp = (ChoicePeer) peer;
       cp.add (item, index);
     }
-
-  if (getItemCount () == 1 || selectedIndex >= index)
-  {
-    select (0);
-    // We must generate an ItemEvent here
-    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent (
-      new ItemEvent ((ItemSelectable)this, 
-                     ItemEvent.ITEM_STATE_CHANGED,
-                     getItem(0),
-                     ItemEvent.SELECTED));
-  }
 }
 
 /*************************************************************************/
@@ -273,6 +251,9 @@ remove(String item)
 public synchronized void
 remove(int index)
 {
+  if ((index < 0) || (index > getItemCount()))
+    throw new IllegalArgumentException("Bad index: " + index);
+
   pItems.removeElementAt(index);
 
   if (peer != null)
@@ -281,17 +262,7 @@ remove(int index)
       cp.remove (index);
     }
 
-  if ((index == selectedIndex) && (getItemCount() > 0))
-  {
-    select (0);
-    // We must generate an ItemEvent here
-    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent (
-      new ItemEvent ((ItemSelectable)this, 
-                     ItemEvent.ITEM_STATE_CHANGED,
-                     getItem(0),
-                     ItemEvent.SELECTED));
-  }
-  else if (selectedIndex > index)
+  if (selectedIndex > index)
     --selectedIndex;
 }
 
@@ -303,26 +274,15 @@ remove(int index)
 public synchronized void
 removeAll()
 {
-  int count = getItemCount();
-
-  if (count <= 0)
+  if (getItemCount() <= 0)
     return;
   
-  ChoicePeer cp = (ChoicePeer) peer;
+  pItems.removeAllElements ();
 
-  // Select the first item to prevent an spurious ItemEvent to be generated
-  if (cp != null)
-    {
-      cp.select (0);
-      selectedIndex = 0; // Just to keep consistent
-    }
-
-  for (int i = (count - 1); i >= 0; i--)
+  if (peer != null)
     {
-      // Always remove the last to avoid generation of ItemEvents.
-      pItems.removeElementAt(i);
-      if (cp != null)
-        cp.remove (i);
+      ChoicePeer cp = (ChoicePeer) peer;
+      cp.removeAll ();
     }
 
   selectedIndex = -1;
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c,v
retrieving revision 1.5
diff -c -p -u -r1.5 gnu_java_awt_peer_gtk_GtkChoicePeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c	23 Dec 2003 19:24:00 -0000	1.5
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c	24 Dec 2003 20:44:49 -0000
@@ -85,9 +85,11 @@ Java_gnu_java_awt_peer_gtk_GtkChoicePeer
   ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
+
   menu = GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (ptr)));
 
-  if (!gtk_container_children (GTK_CONTAINER (menu)))
+  /* Are we adding the first element? */
+  if (gtk_option_menu_get_history (GTK_OPTION_MENU (ptr)) < 0)
       need_set_history = 1;
 
   count = (*env)->GetArrayLength (env, items);
@@ -110,7 +112,8 @@ Java_gnu_java_awt_peer_gtk_GtkChoicePeer
 
       (*env)->ReleaseStringUTFChars (env, item, label);
     }
-  
+
+  /* If we just added the first element select it. */  
   if (need_set_history)
     gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), 0);
 
@@ -118,12 +121,13 @@ Java_gnu_java_awt_peer_gtk_GtkChoicePeer
 }
 
 JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkChoicePeer_add 
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeAdd 
   (JNIEnv *env, jobject obj, jstring item, jint index)
 {
   void *ptr;
   const char *label;
   GtkWidget *menu, *menuitem;
+  int current;
   int need_set_history = 0;
 
   ptr = NSA_GET_PTR (env, obj);
@@ -131,17 +135,24 @@ Java_gnu_java_awt_peer_gtk_GtkChoicePeer
   label = (*env)->GetStringUTFChars (env, item, 0);      
 
   gdk_threads_enter ();
-  menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (ptr));
+  
+  current = gtk_option_menu_get_history (GTK_OPTION_MENU (ptr));
 
-  if (!gtk_container_children (GTK_CONTAINER (menu)))
+  /* Are we adding the first element or below or at the currently
+     selected one? */
+  if ((current < 0) || (current >= index))
       need_set_history = 1;
 
+  menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (ptr));
   menuitem = gtk_menu_item_new_with_label (label);
   gtk_menu_insert (GTK_MENU (menu), menuitem, index);
   gtk_widget_show (menuitem);
 
   connect_choice_item_selectable_hook (env, obj, GTK_ITEM (menuitem), label);
 
+  /* If we just added the first element select it.
+     If we added at of below the currently selected position make
+     the first item the selected one. */  
   if (need_set_history)
     gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), 0);
 
@@ -151,13 +162,15 @@ Java_gnu_java_awt_peer_gtk_GtkChoicePeer
 }
 
 JNIEXPORT void JNICALL 
-Java_gnu_java_awt_peer_gtk_GtkChoicePeer_remove 
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeRemove 
   (JNIEnv *env, jobject obj, jint index)
 {
   void *ptr;
   GtkContainer *menu;
   GtkWidget *menuitem;
   GList *children;
+  int need_set_history = 0;
+  int i, from, to;
 
   ptr = NSA_GET_PTR (env, obj);
 
@@ -165,9 +178,38 @@ Java_gnu_java_awt_peer_gtk_GtkChoicePeer
 
   menu = GTK_CONTAINER (gtk_option_menu_get_menu (GTK_OPTION_MENU (ptr)));
   children = gtk_container_children (menu);
-  menuitem = GTK_WIDGET (g_list_nth (children, index)->data);
-  gtk_container_remove (menu, menuitem);
-  gtk_widget_destroy (menuitem);
+
+  if (index == -1)
+    {
+      /* Remove all elements (removeAll) */
+      from = g_list_length (children) - 1;
+      to = 0;
+
+      /* Select the first item to prevent spurious activate signals */
+      gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), 0);
+    }
+  else
+    {
+      /* Remove the specific index element */
+      from = index;
+      to = index;
+
+      /* Are we removing the currently selected element? */
+      if (gtk_option_menu_get_history (GTK_OPTION_MENU (ptr)) == index)
+        need_set_history = 1;
+    }
+
+  for (i = from; i >= to; i--)
+    {
+      menuitem = GTK_WIDGET (g_list_nth (children, i)->data);
+      gtk_container_remove (menu, menuitem);
+      gtk_widget_destroy (menuitem);
+    }
+
+  /* If we just removed the currently selected element and there are
+     still elements left in the list, make the first item the selected one. */  
+  if (need_set_history && gtk_container_children (menu))
+    gtk_option_menu_set_history (GTK_OPTION_MENU (ptr), 0);
 
   gdk_threads_leave ();
 }
@@ -185,6 +227,24 @@ Java_gnu_java_awt_peer_gtk_GtkChoicePeer
   gdk_threads_leave ();
 }
 
+JNIEXPORT jint JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkChoicePeer_getHistory 
+  (JNIEnv *env, jobject obj)
+{
+  void *ptr;
+  int index;
+
+  ptr = NSA_GET_PTR (env, obj);
+
+  gdk_threads_enter ();
+
+  index = gtk_option_menu_get_history (GTK_OPTION_MENU (ptr));
+
+  gdk_threads_leave ();
+
+  return index;
+}
+
 static void
 item_activate (GtkItem *item __attribute__((unused)),
 	       struct item_event_hook_info *ie)
@@ -205,7 +265,7 @@ item_removed (gpointer data, 
 {
   struct item_event_hook_info *ie = data;
 
-  free (ie->label);
+  free ((void *) ie->label);
   free (ie);
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]