From b7a9b4af036708755a251309dcf591d9bf9db9ea Mon Sep 17 00:00:00 2001 From: Fernando Nasser Date: Mon, 5 Jan 2004 21:18:06 +0000 Subject: [PATCH] Choice.java (add): Leave posting of ItemEvents to peer. 2004-01-05 Fernando Nasser * 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. From-SVN: r75443 --- libjava/ChangeLog | 27 +++++++ .../gnu/java/awt/peer/gtk/GtkChoicePeer.java | 67 ++++++++++++---- libjava/java/awt/Choice.java | 58 +++----------- .../gnu_java_awt_peer_gtk_GtkChoicePeer.c | 80 ++++++++++++++++--- 4 files changed, 157 insertions(+), 75 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 25d611abf38..c5556a9626d 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,30 @@ +2004-01-05 Fernando Nasser + + * 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. + 2004-01-05 Thomas Fitzsimmons * gnu/java/awt/peer/gtk/GtkComponentPeer.java, diff --git a/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java b/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java index 7e5579b3bc7..a03a410508c 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java @@ -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; @@ -45,8 +46,6 @@ import java.awt.peer.ChoicePeer; public class GtkChoicePeer extends GtkComponentPeer implements ChoicePeer { - native void create (); - public GtkChoicePeer (Choice c) { super (c); @@ -59,35 +58,71 @@ public class GtkChoicePeer extends GtkComponentPeer 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 void create (); + + native void append (String items[]); + native int getHistory (); + native void nativeAdd (String item, int index); + native void nativeRemove (int index); - native public void add (String item, int index); - native public void remove (int index); native public void select (int position); - public void removeAll () { } + public void add (String item, int index) + { + 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 addItem (String item, int position) { add (item, position); } - - /* - public void handleEvent (AWTEvent event) - { - if (event instanceof ItemEvent) - ((Choice) awtComponent).select ((String) ((ItemEvent)event).getItem ()); - super.handleEvent (event); - } - */ 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); } } diff --git a/libjava/java/awt/Choice.java b/libjava/java/awt/Choice.java index 863888c5b37..d1f601f777d 100644 --- a/libjava/java/awt/Choice.java +++ b/libjava/java/awt/Choice.java @@ -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) + if (peer != null) { - cp.select (0); - selectedIndex = 0; // Just to keep consistent - } - - for (int i = (count - 1); i >= 0; i--) - { - // 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; diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c index 068cf1e4254..cc586a022d2 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c @@ -85,9 +85,11 @@ Java_gnu_java_awt_peer_gtk_GtkChoicePeer_append 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_append (*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_append } 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_add 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_add } 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_remove 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_select 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); }