Rob Seegel > Tk-JComboBox-1.12 > Tk::JComboBox

Download:
Tk-JComboBox-1.12.tar.gz

Dependencies

Annotate this POD (1)

Related Modules

Tcl::Tk
Tk::MatchEntry
Archive::Zip
Tk::Pane
Tk::ComboEntry
Tk::SplitFrame
XML::Generator
HTML::Mason
HTML::Template
HTML::Element
more...
By perlmonks.org

CPAN RT

New  2
Open  1
View/Report Bugs
Module Version: 1.12   Source   Latest Release: Tk-JComboBox-1.14

NAME ^

Tk::JComboBox - Create and manipulate JComboBox widgets

SYNOPSIS ^

$jcb = $parent->JComboBox(?options?);

DESCRIPTION ^

JComboBox is a composite widget that contains a text Label or Entry, a Button, and a popup Listbox. It performs the same sort of tasks that can be accomplished by several other Composite widgets. Some such as BrowseEntry and Optionmenu are part of the standard Tk distribution, and there are many others available in CPAN.

JComboBox borrows features from the Java Swing component bearing the same name, but falls short of being a true clone. Many of the methods and the general look and feel should be familiar to java developers. JComboBox also combines several features offered by many of the other "Combo Box" implementations, and works in two modes: editable and readonly.

In readonly mode, JComboBox offers similar functionality to Optionmenu. It is basically a labeled button that activates a popup list. An item from the list is displayed on the Button when selected.

When editable, JComboBox somewhat resembles BrowseEntry. That is, the widget is composed of an Entry widget with a Button to the right of it. As in the editable mode, the Button activates a popup Listbox from which a single item can be selected.

For more detailed information on using this widget, refer to the JComboBox tutorial.

COMPONENTS ^

You should use caution when configuring JComboBox subwidgets. Extensive configuration changes may result in unexpected or invalid behavior. The subwidgets are advertised to allow for fine tuned configuration of the internal subwidgets, when there no provided options or methods that will do what you need.

Subwidgets used in readonly mode

NAME: Entry, RO_Entry
CLASS: Label

This Label is used to display the selected item from the popup Listbox. This widget and the Button subwidget form the face of the Button that triggers the popup Listbox.

Subwidgets used in editable mode

Name: Entry, ED_Entry
Class: Entry

This Entry is used to display the selected item from the popup Listbox, or can accept input that does not appear within the Listbox.

Subwidgets used in both modes

Name: Button, ED_Button, RO_Button
Class: Label

This Label is used to trigger the Popup Listbox, and by default displays a bitmap of a filled triangle that points downward. This subwidget only supports Label options.

Name: Popup
Class: Toplevel

This widget contains the Listbox subwidget that displays one or more entries that can be selected for the JComboBox. This is mostly used a container (and an additional way of configuring the Listbox dimensions).

Name: Listbox
Class: Listbox

Used to contain one or more entries, one of which can be selected and displayed within the Box subwidget.

OPTIONS ^

JComboBox supports a long list of options, so to try and break them up a bit I've grouped them in sections. The Basic section contains options that implement or override standard Tk options. or deal with simple things such as colors. The Callback section contains all the options that can have configured Callbacks. The Miscellaneous section contains options that are unique to this widget. These options provide complex functionality that can alter look and feel or provide for initialization shortcuts.

Basic options

Name: background
Class: Background
Switch: -background/-bg

Specifies the normal background color to use when displaying the widget. This color will be applied to all internal widgets as well. For fine-tuned configuration of subwidgets, refer to the -subwidgets option.

Switch: -bitmap

Specifies a bitmap to display in the Button subwidget. Defaults to a filled,downward pointing triangle.

Name: borderwidth
Class: BorderWidth
Switch: -borderwidth

Specifies a non-negative value indicated the width of the of the 3-D border to draw around the outside of the widget.

Name: cursor
Class: Cursor
Switch: -cursor

Specifies the mouse cursor to be used for the widget. This cursor will be applied to all internal widgets as well.

Switch: -disabledbackground

Specifies the background color to display when the JComboBox state is set to disabled. This option currently only affects the Entry subwidget, while in editable mode.

Switch: -disabledforeground

Specifies the foreground color to display when the JComboBox state is set to disabled. This option affects both the Entry and Button subwidgets in either mode.

Switch: -entrybackground

Specifies the background color used in one or more subwidgets depending on the mode. In both modes, the color is applied to the Entry and Listbox subwidgets. In readonly mode, the background is also applied to the Button subwidget.

Name: entryWidth
Class: EntryWidth
Switch: -entrywidth

Specifies a value to use for sizing the width of the Entry subwidget. The specified value can fall in one of three categories. If a value greater than 0 is specified, then the Entry will use that width regardless of the contents of the Listbox, or values set to the Listbox. If the value is set to 0, then the Entry will be sized large enough to hold its current text. If set to -1, the Entry will be sized to the longest item currently contained within the Listbox. The value defaults to -1, which works well for when the JComboBox contains a fairly static list. Otherwise, a value greater than 0 is recommended.

Name: font
Class: Font
Switch: -font

Specifies the font to use when drawing text inside the widget. This font will be applied to internal widgets that can display a font.

Name: foreground
Class: Foreground
Switch: -foreground

Specifies the foreground color to use for the Entry and Listbox subwidget in either mode.

Name: gap
Class: Gap
Switch: -gap

Specifies the number of spaces (in characters) between the Entry and the Button subwidgets. Default value is 0.

Switch: -highlightbackground

Specifies the color to display in the traversal highlight region when the widget does not have the input focus.

Switch: -highlightcolor

Specifies the color to use for the traversal highlight rectangle that is drawn around the widget when it has the input focus.

Switch: -highlightthickness

Specifies the size of the rectangle surrounding the JComboBox that changes color when it has the focus. The default value is 0. Note that on Win32 systems, focus is drawn slightly differently than on other systems. JComboBox does not currently account for the difference.

Name: padY
Class: PadY
Switch: -pady

Specifies the width of a rectangular border to insert between the Entry/Button Subwidgets and their container. This can be used to enlarge the height of the JComboBox. It has no default value.

Name: relief
Class: Relief

Specifies the 3-D effect desired for the widget. Acceptable values are raised, sunken, flat, ridge, solid, and groove. The value indicates how the interior of the widget should appear relative to its exterior; for example, raised means the interior of the widget should appear to protrude from the screen, relative to the exterior of the widget. The default value depends on the mode: groove in readonly mode and sunken in editable mode.

Switch: -selectbackground

Specifies the background color to use when displaying selected items. This value will be applied to the Listbox in both modes, and to the Entry subwidget in editable mode.

Switch: -selectborderwidth

Specifies a non-negative value indicating the width of the 3-D border to draw around selected items. The value may have any of the forms acceptable to Tk_GetPixels. This value will be applied to the Listbox subwidget in both modes, and to the Entry subwidget in editable mode.

Switch: -selectforeground

Specifies the foreground color to use when displaying selected items. This value will be applied to the Listbox subwidget in both modes, and to the Entry subwidget in editable mode.

Name: state
Class: State
Switch: -state

Specifies one of two state values for the JComboBox: normal and disabled. When the state is set to disabled, the event handlers will not respond to user events, and the color of the JComboBox will change depending on the mode. In both modes, -disableforeground will be applied to both the Entry and Button subwidgets' foreground. In editable mode, -disablebackground will be applied to the Entry subwidget's background. The disabled state also causes -takefocus to be set to 0. Changing the state back to the default of normal will reverse these changes to the JComboBox.

Name: takeFocus
Class: TakeFocus
Switch: -takefocus

Determines whether or not the JComboBox takes focus or not during keyboard traversal. This setting defaults to 1 and is crucial to the JComboBox accepting keyboard events. Regardless of mode, it is the Entry subwidget within the JComboBox that receives the focus, and so it should be the target of any key binding.

Name: textVariable
Class: Variable
Switch: -textvariable

Used to pass a scalar reference into the JComboBox that will provide a way of setting and accessing the selected value. This option can be used as an alternative to using the various widget methods because scalar references that are passed are tied to widget methods. Every time the variable is accessed, it is roughly equivalent to calling: getSelectedValue(), and every time the variable is set, it is like calling: setSelected($value, -type = 'value')>.

Because each Listbox entry in JComboBox could represent two pieces of information, it's important to understand precisely what the -textvariable provides access to. Given the following setup:

   my $value;
   my $jcb = $mw->JComboBox(
      -textvariable => \$value,
      -choices => [
         {-name => 'one', -value => 1},
         {-name => 'two', -value => 2},
         "three"
      ],
   )->pack;

The following should be expected:

   $jcb->setSelectedIndex(0);
   print $value . "\n";    ## prints 1  
   $jcb->setSelectedIndex(2);
   print $value . "\n";    ## prints three

And the following would also be expected:

   $this = 2;        ## changes the selection to "two"
   $this = "three";  ## changes the selection to "three"

Because no value for "three" was specified, the value defaults to "three" for the purpose of both examples. Note that the mode may limit what can be set as well. For example, in "readonly" mode, the only items that can be selected are those that appear within the Listbox.

Note: Unlike other widgets, -textvariable is tightly controlled within JComboBox and experimentation is recommended if you plan to use it. It can be used as a shortcut for setting/retrieving item values.

Callback options

Some of the options have changed names since the previous version. -menucreate/-menumodify, for example are now, -popupcreate/-popupmodify. After having now looked at the code for a year or so, the old names felt wrong. After all, it is not a menu that is displayed, its a Listbox, and the two are very different. Because I had a subwidget called Popup, it seemed to make more sense to me for these options to use "popup" instead of "menu".

Switch: -matchcommand

Specifies a callback that will be used to determine whether a specified String matches a field within the popup Listbox. This callback will be invoked every time a search for an index is done. This callback will be utilized within the getItemIndex method, and through the Autofind functionality (which uses getItemIndex).

Callbacks are passed at least two parameters: $searchStr and $field. searchStr contains the search string. This will be the search pattern. When the -matchcommand is not set, all special regex patterns are escaped, and the search is generally anchored to the start of any string it will compared to. field is a single item within the list that the searchStr is being checked against. It will either be the name, which is the String that appears in the list, or it's value. The value is non-visible element associated with the visible one. A callback should return 1 if the match succeeds, and 0 otherwise.

Refer to the tutorial for more information on this option.

Switch: -popupcreate/-listcmd

Specifies a callback that will be invoked prior to showing the Popup Listbox. This callback is the first of two callback options that can be invoked prior to displaying the Popup. The most common use case would be for someone wanting to dynamically populate the contents of the widget prior to displaying it. After this callback is invoked JComboBox will go through it's own internal routine of configuring the height/width and positioning characteristics of the Popup. Some of this is driven by various configuration options. The downside of this is that any configuration of this type done within a popupcreate callback may be overridden.

Note for versions prior to 1.12: In prior versions, this callback could be configured to completely replace the internal positioning/configuration of the Popup. This is a good deal of trouble for soneone to go through, and it didn't seem to be a likely need -- espcially given the presence of the -popupmodify option. Developers using this option in older versions, can call $jcb->PopupCreate within their custom -popupcreate callback to get an aproximation of the functionality in 1.12 and beyond. Also in older versions if the JComboBox contained no items or was already being displayed this callback would not be invoked. This is no longer the case.

Switch: -popupmodify

Specifies a callback to call immediately before the Popup is shown. This is the second of two callbacks called prior to displaying the Popup. This callback can be used to override any height/width or positional configuration done prior to this callback. It serves as a mechanism for the developer to have the final word in how the Popup should display before it is shown. The expectation is that use of this option will be rare and most developers will prefer the -popupcreate option over this one.

Switch: -selectcommand/-browsecmd

Specifies a callback to call every time a selection is made within the JComboBox. The specified callback will be passed the following arguments, in this order: $jcbWidget, $selectedIndex, $selectedValue, $selectedName. In cases where a value is not specified for an entry, the value will be the same as for $selectedName. In editable mode, when an entry is displayed that does not appear within the Listbox, the $selectedIndex will be set to -1, and both the selectedName and selectedValue will be the value displayed within the Entry subwidget. The selectcommand CALLBACK will only be called once after each change to the selection. This option is roughly equivalent to the -browsecmd and -browse2cmd found in BrowseEntry.

Switch: -validatecommand

Specifies a callback to evaluate when you want to validate the input into the entry widget. Setting it to undef disables this feature (the default). This command must return a valid boolean value. If it returns 0 (or the valid boolean equivalent) then it means you reject the new edition and it will not occur and the invalidCommand will be evaluated if it is set. If it returns 1, then the new edition occurs. More details of this option can be found in the documentation for the Entry widget. Also take a look at the -validate option listed later in this document.

Miscellaneous options

Switch: -autofind

Specifies the configuration parameters for a set of functionality that uses key strokes to quickly locate and/or select entries within the Popup Listbox. This option takes a reference to a hash containing one or more options that each take a boolean value. Some options have no effect depending on the mode.

The options currently include:

-enable - Specifies whether or not to enable autofind or not. The value defaults to 1.

-casesensitive - Specifies whether or not the autofind capability should ignore the case of each keystroke when finding a match in the List. Defaults to 0.

-complete - Specifies whether or not to use auto completion when the JComboBox is in editable mode. Auto completion causes the remainder of an entry to be filled in when a matching entry is found, though the entry is not yet selected. Defaults to 0. Note, this option is ignored regardless of value when the -select option is enabled.

-select - Selects the first item in the list that matches the keystroke (in editable mode), and entry (in readonly mode). Repeated keys/entries will cause the next matching entry to be selected. Defaults to 0. This option takes priority over the -complete option.

-showpopup - Specifies whether or not to display the Popup Listbox when a matching entry is found within the list. Defaults to 1.

More information on this option can be found in the tutorial under Using Autofind.

Name: listHighlight
Class: ListHighlight
Switch: -listhighlight

Specifies whether or not list highlighting should be set. List highlighting is typical on Win32 Combo Box implementations. When the mouse is over a Listbox item, the item appears as though it were selected in the Listbox. A value of 1 enabled the feature, and 0 deactivates it. The default setting is 1.

Name: listWidth
Class: ListWidth
Switch: -listwidth

By default, the width of the Popup is sized to fit the width of the JComboBox. This option allows that behavior to be modified. If defined, the listwidth will be applied to the width of the Listbox, and the width of the Listbox will be the primary factor in sizing the Popup (borderwidth of the Popup, and presence of a scrollbar also will figure into sizing). The default value is -1.

Name: maxRows
Class: MaxRows
Switch: -maxrows

Specifies a maximum number of rows that will be displayed in the Listbox subwidget. If the Listbox contains fewer elements than the specified size, then it will shrink to fit only that number. If there are more elements than the specified maxrows size, then the Listbox will adjust the height to the specified number and use a scrollbar for accessing the other elements. Defaults to 10. Note: if a specified maxrows value causes the Popup to expand beyond the top and bottom of the screen, then the maxrow setting will be overridden automatically so that the popup can be contained within the screen.

Name: mode
Class: Mode
Switch: -mode

Specifies the operating mode of the JComboBox, and can either by readonly, the default, or editable. The mode can currently only be set at Creation time, and cannot be reconfigured. Some options can have subtly different affects depending on the mode. These cases will be noted under the documentation for each option.

Name: updownSelect
Class: UpDownSelect
Switch: -updownselect

When the JComboBox has focus, and the popup is visible, the arrow keys can be used to move the Listbox selection up or down. The Listbox selection is not necessarily equivalent to the JComboBox selection. In Win32 Combo Box implementations, it is common for the up/down keys to also affect the JComboBox selection along with the Listbox selection. This option toggles that behavior. If set to 1 then the arrow keys will treat the previous or next item in the Listbox as the selected item in the JComboBox, and if set to 0, it won't. The default setting is 1.

Name: validate
Class: Validate
Switch: -validate

This option is only used when in editable mode, and generally is exactly the same as the same option for the Entry Widget. It specifies the mode in which validation should operate: none, focus, focusin, focusout, key, or all. It defaults to none. When you want validation, you must explicitly state which mode you wish to use.

In addition, there are two other values: match and cs-match that restrict values to entries that are contained within the internal List. cs-match treats case as significant, and match does not. When used, these options effectively negate the editable mode. When these values are configured, the JComboBox automatically configures its own CALLBACK for the -validatecommand option.

The Choices option

Switch: -choices/-options

Specifies a reference to an array to use to populate the JComboBox with entries. This option is meant to be used when creating the Widget, and reconfiguring this option will first delete any preexisting entries before adding the new ones. The value is expected to be an array reference. Setting the value to an empty string will remove the tie along with any existing entries.

As of version 1.07, setting the -choices option will do more than simply populate the JComboBox Listbox -- it will tie the internal List to the array. This means that as an alternative to using the various public methods, you can use the array as an interface. Changes made to the array will be reflected in the JComboBox, and vice versa.

As of version 1.08, a single array can be associated with multiple JComboBox instances. However, the precise behavior merits further explanation. Not all associated instances have the same relationship with the array. The first instance to be configured with the array becomes the master instance, and all other instances retain roles as observers. When changes are made to the array, both master and observers will be modified to reflect the change. Changes made to the master through its methods will reflected in the array, and those made to observers will not. If the master is reconfigured to use a different choices array, then all of the other observers will automatically be reconfigured as well. If an observer is reconfigured, then it will be the only one to be changed. If the new array is not already associated with other JComboBox instances, then the observer will become the master instance for the new array,

For more details on using this option, refer to the section in the tutorial, Access Through the Choices Array.

METHODS ^

$jcb->addItem(string, ?option => value)

Appends a new Listitem to be used in the Popup Listbox. string is a scalar variable that will be displayed in the Listbox. This method takes two options -selected and -value:

-selected => selected

Where selected is a boolean value (true/yes/1) and determines whether or not the list item is the select item within the JComboBox. The default value for this is false. Any subsequent call that uses this option overrides previous ones.

-value => value

Where value is an alternate scalar associated with the List item for times when it's desirable to have a value other than the one displayed (can be useful for database applications).

Example:

   $jcb->addItem('Alaska', -value => 'AK', -selected => 1);
$jcb->clearSelection()

Clears the current selected item in the JComboBox, if one is selected.

$jcb->getItemIndex(string, ?option => value, ...)

Searches the JComboBox for the first item that matches the given string and returns that item's index. If no match is found, returns -1. This methods supports the options -mode and -type.

-type => type

Where type is either name, which is the displayed text, or value, which is the alternate value associated with the item. If an item in the JComboBox does not have a value defined, then that item's name will be used. Defaults to name.

-mode => mode

Where mode affects how the given string is compared to a list item. Values include: exact, usecase, and ignorecase. exact means that the string must completely match the list item, including case. usecase means that the string must match the beginning of the list item, including its case. ignorecase means that the string must match the beginning of the list item, regardless of the case. Defaults to exact.

Example:

 ## Finds first matching list item that has a value complete matching AK
 my $index = $jcb->getItemIndex('AK', -type => 'value');
 ## Finds the first matching list item that starts with the letter 'a'
 my $index = $jcb->getItemIndex('a', -mode => 'usecase');
 ## Finds the first matching list item that starts with 'a' or 'A'
 my $index = $jcb->getItemIndex('a', -mode => 'ignorecase');
$jcb->getItemCount()

Returns the number of list items stored in the JComboBox.

$jcb->getSelectedIndex()

Returns the index of the current selected item or -1, if none of the items is selected.

$jcb->getSelectedValue()

Returns the value of the current selected value or an undef if there isn't one selected. In editable mode, if there is no item selected, it will return the contents of the Entry widget, if there are any characters there, and an undef.

$jcb->getItemNameAt(index)

Returns the string displayed in the Listbox at the specified index, or undef if there is no name at the specified index (index out of range).

$jcb->getItemValueAt(index)

Returns the alternate value associated with the list item at the specified index if it is set. Otherwise, the displayed name will be returned (The same as if getItemNameAt had been called).

$jcb->hidePopup()

Causes the popup Listbox to the withdrawn from the screen, unmapping it.

$jcb->index(index)

Returns the integer value that corresponds to index. If index is end then return value is a count of the number of elements in the Listbox (not the index of the last element).

$jcb->insertItemAt(index, string, ?option => value, ...)

Inserts a new list item into the JComboBox at the specified index. Refer to the section on indices in the Listbox documentation. string is a scalar variable that will be displayed in the Listbox (also referred to in this document as the List item name). This method takes two options: -selected and -value.

-selected => selected

Where selected is a boolean value (true/yes/1) and determines whether or not the list item is the select item within the JComboBox. The default value for this is false. Any subsequent call that uses this option overrides previous ones.

-value => value

Where value is an alternate scalar associated with the List item for times when it's desirable to have a value other than the one displayed (can be useful for database applications).

Example:

The following example produces the same result as the example given for addItem:

   $jcb->insertItemAt('end', 'ALASKA', -value => 'AK', -selected => 1);
$jcb->popupIsVisible()

Returns 1 if the popup is visible (mapped) and 0 otherwise.

$jcb->removeAllItems()

Completely removes all list items from the JComboBox, and clears any selected item if present. In editable mode, this will also clear the Entry widget.

$jcb->removeItemAt(index)

Deletes a single list item from the JComboBox at the specified index.

$jcb->see(index)

Adjusts the JComboBox so that the list item indicated by the specified index is visible. If the Listbox is hidden, it will be made visible, and the list will shift so that the item is viewable.

$jcb->setSelected(string, ?option => value, ...)

Sets the index of the first element that matches the specified string as selected, and has no effect if there are no matches. Generally, this method is a lot like getItemIndex, and takes the same options: -type and -mode.

-type => type

Where type is either name, which is the displayed text, or value, which is the alternate value associated with the item. If an item in the JComboBox does not have a value defined, then that item's name will be used. Defaults to name.

-mode => mode

Where mode affects how the given string is compared to a list item. Values include: exact, usecase, and ignorecase. exact means that the string must completely match the list item, including case. usecase means that the string must match the beginning of the list item, including its case. ignorecase means that the string must match the beginning of the list item, regardless of the case. Defaults to exact.

$jcb->setSelectedIndex(index)

Selects the list item at the specified index, and has no effect if the specified index does not exist.

$jcb->showPopup()

Displays the popup Listbox if hidden (normally triggered by JComboBox button, or one of the key bindings. This method invokes CALLBACK registered to -menu create, which defaults to the ShowPopup method. When this method is called, it will make a global Grab, and will temporarily steal grab from any other window that made a grab. Call "hidePopup" to release the grab and return it to whatever widget had it before this method was called. This is useful when using JComboBox within DialogBox widgets.

BINDINGS ^

Default Keyboard Bindings

Like other Combo Box implementations, JComboBox now has a set of Keyboard bindings that provide access to the entries within the popup Listbox. The precise behavior of some of these bindings will depend on JComboBox options such as -autofind, -list highlighting, and -updownselect.

Alt-Down

Toggles the visibility of the Popup. The event handler is AltDown.

Alt-Up

Hides the popup. The event handler is hidePopup.

Down

Moves the Listbox selection down by one entry as long as there is an entry for the selection to move to. Refer to documentation on -autofind and -updownselect. The Event Handler is UpDown.

Escape

Hides the popup. The event handler is hidePopup.

FocusOut

Sets the displayed entry as selected. Uses the Enter event handler.

KeyPress

The precise behavior of a Key press depends on the -mode and the -autofind option. The default behavior for readonly mode is similar to what you might encounter in a Windows environment. The List items will be searched and the first entry that begins with the pressed letter will be selected, regardless of case. If the same key is pressed again, then the search will begin from the previous match. The Listbox will be shown, and the matching entry will be selected and visible.

For the editable mode, the default behavior is identical, except that instead of just the first letter, the entire String within the Entry will be used for the search. Refer to the Tutorial documentation on Customizing Interface Behavior for more information. Uses the KeyPress event handler.

Up

Moves the Listbox selection up by one entry as long as there is an entry for the selection to move to. Refer to documentation on -updownselect. The Event Handler is UpDown.

Creating your own bindings

Currently, binding to JComboBox events can be a tricky task because of design choices I made with JComboBox, and with the fact that it is a Composite with multiple subwidgets that can each process events. For example, what if you wanted to bind a keyboard event to the JComboBox? If you tried the following:

   $jcb->bind('<KeyPress>', sub { print "Key: " . shift->XEvent->A . "\n"; });

It would not work as expected. This is because by default, if the JComboBox widget receives focus, it immediately redirects that focus to the Box subwidget, which is the only subwidget configured to take the focus.

This is done for a few reasons:

1. More so than any other widget inside JComboBox, the Box (a Label in readonly mode, and an Entry in editable mode) is the focal point. The Listbox isn't always visible, and the Button is intended for mouse interaction. The Box is what displays the value, and in the right mode, allows the user to edit it directly.

2. I wanted only one widget within JComboBox to accept focus, this way when a user was tabbing between widgets, it would only stop once for JComboBox, as it does for most other widgets, otherwise I find that a user might get confused on why the focus didn't move immediately to the next widget in the application as they tabbed through.

3. Laziness. In the case of editable mode, I wanted to take advantage of existing bindings for the Entry widget, and the idea of both generating internal events and delegating external key presses seemed like it was more trouble than it was worth.

So, why not override the bind method so that it always bound directly to the Box subwidget? I considered it, but rejected it because I thought it would be confusing, because it would make the bind method appear to be broken since it would not contain a reference to the JComboBox, but a reference to the Box subwidget. The real problem with this is that if I ever wanted to bind any non keyboard events to the JComboBox, then it wouldn't be easy with the overridden bind.

There are similar problems with other events, so where does this leave you? I advocate two different possibilities. The first is to use or override one of the existing callback options. JComboBox uses several Callbacks that can be overridden to allow for custom behavior. Read the documentation on each Callback, and in the options where there is a default Callback, the name will be listed so that you can call it from within your custom code if you wish. The second would be to get a reference to one or more subwidgets, and bind to them directly. The option you choose will depend largely on what you need to do. Generally, the option callbacks are easier to use, but unfortunately, they do not address all cases.

In the earlier example of the key press, here are some alternatives. Note that each of the approaches are different, and provide varying levels of access.

   ## This code would be called in editable mode only
   $jcb->configure(-validate => 'key',
                   -validatecommand => sub {
      my $newStr = shift;
      my $newChar = shift;
      print "new String: $newStr new Character: $newChar\n";
      return 1; ## Allow character
   }
   ## This code would be called in both modes, and after validation
   $jcb->configure(-keycommand => sub {
      my ($cw, $key, $keySym, $keySymNum) = @_;
      print "Key: $key KeySym: $keySym KeySymNum: $keySymNum\n";
      $cw->AutoFind; ## If you need AutoFind functionality
   });
   $jcb->Subwidget('Box')->bind('<KeyRelease>', [\&doSomething, $jcb]);
   ...
   sub doSomething {
      my ($entry, $jcb) = @_; 
      my $key = $entry->XEvent->A;
      print "Key: $key\n";
   }

ALTERNATIVES ^

Standard distribution

If JComboBox doesn't fit your needs, you're free to modify the code as you see fit, but before you do, you might consider some of the alternatives that are available on CPAN. Even if none of the others is a perfect fit, it may be closer to what you were looking for, and be easier to modify.

The standard distribution contains two Composites that do some of what JComboBox does: Tk::BrowseEntry and Tk::Optionmenu. BrowseEntry visually resembles JComboBox in editable mode to a certain extent, and Optionmenu is a bit like JComboBox in readonly mode. The main difference is that JComboBox more closely resembles a Win32 Combo Box.

Available on CPAN

On CPAN, there are a few more choices available:

JBrowseEntry

JBrowseEntry is maintained by Jim Turner, and began as an enhanced version of BrowseEntry in the main distribution. JBrowseEntry initially tweaked the appearance of the composite, and added key bindings including one to search for List entries corresponding to a key press. JBrowseEntry has since been modified to have a Win32 appearance when used on Windows versions. One of its nice touches is that it has the option of specifying a different bitmap for arrow button for when the widget has focus. It's a nice idea, and one way of working around focus and highlighting issues -- I might keep that in the mind for the future.

I'm not precisely sure how JBrowseEntry currently compares to BrowseEntry, but at one time JBrowseEntry provided key bindings where JComboBox did not, and since it was an enhanced BrowseEntry, someone could replace any instances of BrowseEntry without breaking their existing code, and then take advantage of the enhancements, which is a real advantage for someone looking for a nice upgrade with little to no integration work. The same can <i>not</i> be said for JComboBox.It was never intended as a clone or enhanced BrowseEntry.

JBrowseEntry's document isn't that current unfortunately. It leads one to believe that JComboBox does not provide key bindings. At one time, this was true, but as of release 1.0, JComboBox also has key bindings and is generally more configurable than JBrowseEntry, and provides more out-of-the-box functionality. To be fair, this does come at price: JComboBox has a larger number of options and methods, and can be more difficult to learn. The hopeful payoff is that less time should be required to implement common Combo Box behavior leaving more time to implement core business requirements.

ComboEntry

ComboEntry is part of distribution (Tk-DKW) created by Damion Wilson. This was one of the first Combo Box-type widgets available on CPAN, outside of the main distribution. Damion's distribution served as a good source of examples when I was first learning Tk, and I have a soft spot for them, but I've found many of the widgets in the distribution to be buggy, and not documented very well. Also, the distribution has not been updated since 1999, so it appears to be unsupported. Having said that, ComboEntry may still serve as a useful starting point for your own customized version.

MenuEntry

MenuEntry is part of Graham Barr's, Tk-GBARR distribution, which is currently maintained by Slaven Rezic. MenuEntry was one of the "unfinished" widgets included in that distribution, and was the widget I used as the initial starting point for this widget (Thanks, Graham!). It is as bare bones an implementation as you're likely to find, plus I liked it's look. I initially made only a few minor modifications, then a few more, and finally it got to the point where it no longer resembled Graham's widget. Like ComboEntry, I think this is a great widget for use as a starting point, when creating your own, if you should decide to go that route.

HistEntry

HistEntry is a specialized BrowseEntry widget maintained by Slaven Rezic. It's purpose is to maintain an internal list of items that are added by adding text and then hitting <Return>.

MatchEntry

MatchEntry is an Entry/Listbox combination maintained by Wolfgang Hommel that is used to provide a user friendly auto-completion functionality. The Listbox and auto-completion capabilities are key-driven, and provides a large number of options for configuring the widget. Unlike the other widgets mentioned above the Listbox popup is not triggered by a Button, because MatchEntry doesn't have one. Like HistEntry, MatchEntry is intended for a specialized function. JComboBox also provides some limited auto-completion capabilities, but they are not as sophisticated as what MatchEntry provides.

VERSION ^

This document covers the 1.12 release of JComboBox.

AUTHOR ^

Rob Seegel (RobSeegel@comcast.net)

syntax highlighting: