home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Symantec Visual Cafe for Java 2.5
/
symantec-visual-cafe-2.5-database-dev-edition.iso
/
Visual Cafe Pro v1.0
/
SOURCE.BIN
/
ComboBox.java
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
Macintosh to JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Java Source
|
1997-06-19
|
31.6 KB
|
1,115 lines
package symantec.itools.awt;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.TextField;
// 01/29/97 TWB Integrated changes from Macintosh
// 04/15/97 LAB Added 1 line in deselect() to clear
// the textbox if deselect is called.
/**
* ComboBox drop-down listbox component.
* @version 1.0, Nov 26, 1996
* @author Symantec
*/
public class ComboBox
extends Panel
{
/**
* Event ID used when the image part of a drop-down list item is selected.
*/
public static final int EVT_IMAGE_SELECT = ImageListBox.EVT_IMAGE_SELECT;
private boolean bEditable;
private boolean bSearchable;
private boolean bCaseSensitive;
private TextField editBox;
private DirectionButton arrow;
private ImageListBox list;
private boolean bDown = false;
private int ix;
private int iy;
private int iwidth;
private int iheight;
private int lheight;
private boolean bOverList = false;
private boolean showHScroll = false;
private boolean showVScroll = true;
private Font editFont;
private Font dropFont;
private static boolean bOsFlag = false;
private static ComboBox currentlyDown = null;
private Component parent = null;
private String sSearchText;
private String sSearchItem;
private String sLastText;
private String sSearchOrig;
private int searchIndex;
private int searchLen;
private int searchI;
/**
* Constructs a new default ComboBox. The ComboBox is not editable and
* not searchable by default.
*/
public ComboBox()
{
this(false, false);
}
/**
* Constructs a new editable or searchable ComboBox.
* @param editable true = editable, false = non-editable
* @param searchable true = searchable, false = non-searchable
*/
public ComboBox(boolean editable, boolean searchable)
{
bOsFlag = !System.getProperty("os.name").startsWith("Win");
setLayout(null);
editBox = new TextField("");
editBox.setBackground(Color.white);
arrow = new DirectionButton(DirectionButton.DOWN);
list = new ImageListBox("ILB");
list.setComboMode(true);
list.setShowHorizontalScroll(false);
add(list);
add(editBox);
add(arrow);
arrow.setShowFocus(false);
arrow.shrinkTriangle(1, 1, 5, 5);
arrow.disable();
lheight = 0;
list.hide();
setEditable(editable);
setSearchable(searchable);
bCaseSensitive = true;
}
/**
* Conditionally set the ComboBox to be editable.
* @param editable true = editable, false = non-editable
* @see #getEditable
*/
public void setEditable(boolean editable)
{
bEditable = editable;
editBox.setEditable(bEditable || bSearchable);
}
/**
* Return the current ComboBox "editable" status.
* @return boolean - current editable status
* @see #setEditable
*/
public boolean getEditable()
{
return bEditable;
}
/**
* Conditionally set the ComboBox to be searchable.
* @param searchable true = searchable, false = non-searchable
* @see #getSearchable
*/
public void setSearchable(boolean searchable)
{
bSearchable = searchable;
editBox.setEditable(bEditable || bSearchable);
}
/**
* Returns the current ComboBox "searchable" status.
* @see #setSearchable
*/
public boolean getSearchable()
{
return bSearchable;
}
/**
* Conditionally set the ComboBox to be case sensitive during searches.
* @param bCaseSensitive true = case-sensitive, false = case-insensitive
* @see #getCaseSensitive
*/
public void setCaseSensitive(boolean bCaseSensitive)
{
this.bCaseSensitive = bCaseSensitive;
}
/**
* Returns the current ComboBox case-sensitive search status.
* @see #setSearchable
*/
public boolean getCaseSensitive()
{
return bCaseSensitive;
}
/**
* Sets whether or not the horizontal scrollbar should be made visible when
* necessary or should never be made visible.
* @param cond true = show when necessary, false = never show
* @see #getShowHorizontalScroll
*/
public void setShowHorizontalScroll(boolean cond)
{
showHScroll = cond;
list.setShowHorizontalScroll(cond);
}
/**
* Gets the current horizontal scrollbar display option.
* @return true if the horizontal scrollbar should be displayed when necessary,
* false if the scrollbar should never be shown.
* @see #setShowHorizontalScroll
*/
public boolean getShowHorizontalScroll()
{
return showHScroll;
}
/**
* Sets whether or not the vertical scrollbar should be made visible when
* necessary or should never be made visible.
* @param cond true = show when necessary, false = never show
* @see #getShowVerticalScroll
*/
public void setShowVerticalScroll(boolean cond)
{
showVScroll = cond;
list.setShowVerticalScroll(cond);
}
/**
* Gets the current vertical scrollbar display option.
* @return true if the vertical scrollbar should be displayed when necessary,
* false if the scrollbar should never be shown.
* @see #setShowVerticalScroll
*/
public boolean getShowVerticalScroll()
{
return showVScroll;
}
/**
* Set the edit field and drop-down list font.
* @param f new edit field and drop-down list font
* @see #getComboBoxFont
*/
public synchronized void setComboBoxFont(Font f)
{
setFont(f);
}
/**
* Get the edit field and drop-down font.
* @return current edit field and drop-down font
* @see #setComboBoxFont
*/
public synchronized Font getComboBoxFont()
{
return editFont;
}
/**
* Set the edit field font.
* @param f new edit field font
* @see #getEditFieldFont
*/
public synchronized void setEditFieldFont(Font f)
{
if (editBox != null && f != null && iheight > 15)
{
editFont = f;
editBox.setFont(f);
}
}
/**
* Get the edit field font.
* @return current edit field font
* @see #setEditFieldFont
*/
public synchronized Font getEditFieldFont()
{
return editFont;
}
/**
* Set the drop-down list font.
* @param f new drop-down list font
* @see #getDropDownFont
*/
public synchronized void setDropDownFont(Font f)
{
if (list != null && f != null)
{
dropFont = f;
list.setFont(f);
}
}
/**
* Get the drop-down list font.
* @return current drop-down list font
* @see #setDropDownFont
*/
public synchronized Font getDropDownFont()
{
return dropFont;
}
/**
* Processes events for this component.
* This is a standard Java AWT method which gets called by the AWT
* to handle this component's events. The default handler for
* components dispatches to one of the following methods as needed:
* action(), gotFocus(), lostFocus(), keyDown(), keyUp(), mouseEnter(),
* mouseExit(), mouseMove(), mouseDrag(), mouseDown(), or mouseUp().
*
* @param evt the event to handle
* @return true if the event was handled and no further action is needed,
* false to pass the event to this component's parent
* @see java.awt.Component#action
* @see java.awt.Component#gotFocus
* @see java.awt.Component#lostFocus
* @see java.awt.Component#keyDown
* @see java.awt.Component#keyUp
* @see java.awt.Component#mouseEnter
* @see java.awt.Component#mouseExit
* @see java.awt.Component#mouseMove
* @see java.awt.Component#mouseDrag
* @see java.awt.Component#mouseDown
* @see java.awt.Component#mouseUp
*/
public boolean handleEvent(Event evt)
{
switch (evt.id)
{
case Event.KEY_ACTION_RELEASE:
{
if (evt.target != editBox)
{
switch(evt.key)
{
case Event.HOME: list.select(0); break;
case Event.END: list.select(list.countItems() - 1); break;
case Event.PGUP:
case Event.UP: list.select(list.getSelectedIndex() - 1); break;
case Event.PGDN:
case Event.DOWN: list.select(list.getSelectedIndex() + 1); break;
}
editBox.setText(list.getSelectedItem());
editBox.selectAll();
}
break;
}
case Event.KEY_PRESS:
{
sLastText = editBox.getText();
break;
}
case Event.KEY_RELEASE:
{
if (evt.target == editBox)
{
verify();
}
break;
}
case Event.GOT_FOCUS:
{
if (evt.target == this && !bDown)
{
editBox.selectAll();
editBox.requestFocus();
break;
}
if (bOsFlag)
{
if (evt.target == editBox)
{
dropList(false);
}
}
break;
}
case Event.LOST_FOCUS:
{
if ((evt.target == arrow) && !bOverList)
{
dropList(false);
}
break;
}
case Event.MOUSE_ENTER:
{
if (evt.target == list)
{
bOverList = true;
}
break;
}
case Event.MOUSE_EXIT:
{
if (evt.target == list)
{
bOverList = false;
}
break;
}
case Event.ACTION_EVENT:
{
if (evt.target instanceof DirectionButton)
{
dropList(!bDown);
return true;
}
else if (evt.target == list) // ignore double-click
{
return true;
}
break;
}
case EVT_IMAGE_SELECT:
{
if (parent == null)
{
parent = getParent();
}
if (parent != null)
{
evt.target = this;
parent.postEvent(evt);
}
return true;
}
case Event.LIST_SELECT:
{
editBox.setText(list.getSelectedItem());
if (parent == null)
{
parent = getParent();
}
if (parent != null)
{
evt.target = this;
evt.id = Event.ACTION_EVENT;
parent.postEvent(evt);
}
dropList(false);
return true;
}
}
return super.handleEvent(evt);
}
/**
* Return ComboBox top/down addition status.
* @return if true, add the ComboBox physically first, top to bottom, into
* the container which will be its parent.
* @see #addLastBottomUp
*/
public static boolean addFirstTopDown()
{
return !addLastBottomUp();
}
/**
* Return ComboBox bottom/up addition status.
* @return if true, add the ComboBox physically last, bottom to top, into
* the container which will be its parent.
* @see #addFirstTopDown
*/
public static boolean addLastBottomUp()
{
String sOs = System.getProperty("os.name");
if (sOs.startsWith("S") || // SunOS, Solaris
sOs.startsWith("Kona") || // Kona (Mr. Coffee)
sOs.startsWith("AIX") || // AIX
sOs.startsWith("OSF") ) // OSF
{
return true;
}
// Windows Netscape 3.0bx
if (sOs.startsWith("Win") &&
System.getProperty("java.vendor").startsWith("Netscape") &&
System.getProperty("java.version").equals("1.02") )
{
return true;
}
return false;
}
/**
* Use this method to set a flag for use in your handleEvent to determine if
* the ComboBox needs help in "un-dropping". This will improve useability
* under platforms which do not provide proper focus events. (For best
* performance assign a variable in your class once to avoid repeated function
* calls to this method.)
* <pre>
* boolean bNeedsPlatformHelp = ComboBox.needsPlatformHelp();
*
* public boolean handleEvent(Event evt)
* {
* switch (evt.id)
* {
* case Event.MOUSE_UP:
* // do it on mouse up, which indicates a full click somewhere other than
* // the ComboBox that could be currently dropped down.
* if (bNeedsPlatformHelp)
* ComboBox.unDropLastDropped();
* break; // or other MOUSE_UP processing as necessary
*
* ...
*
* }
*
* ...
*
* }
* </pre>
* @see #unDropLastDropped
*/
public static boolean needsPlatformHelp()
{
return bOsFlag;
}
/**
* "un-drop" the last ComboBox that was dropped down.
* @see #needsPlatformHelp
*/
public static void unDropLastDropped()
{
if (currentlyDown != null)
{
currentlyDown.dropList(false);
}
}
/**
* Clear all items from the drop-down list.
*/
public void clear()
{
list.clear();
editBox.setText("");
}
/**
* Adds the specified item to the end of drop-down list and enable the item.
* @param item the item to be added
* @see #addItem(java.lang.String, boolean)
* @see #addItem(java.awt.Image, java.lang.String)
* @see #addItem(java.awt.Image, java.lang.String, boolean)
* @see #setListItems(java.lang.String[])
*/
public synchronized void addItem(String item)
{
addItem((Image)null, item, true);
}
/**
* Adds the specified item to the end of drop-down list and conditionally enable it.
* @param item the item to be added
* @param bEnabled whether or not the item is enabled
* @see #addItem(java.lang.String)
* @see #addItem(java.awt.Image, java.lang.String)
* @see #addItem(java.awt.Image, java.lang.String, boolean)
* @see #setListItems(java.lang.String[])
*/
public synchronized void addItem(String item, boolean bEnabled)
{
addItem((Image)null, item, bEnabled);
}
/**
* Adds the specified item with an image to the end of drop-down list and enables it.
* @param image the image to display on item line
* @param item the item to be added
* @see #addItem(java.lang.String)
* @see #addItem(java.lang.String, boolean)
* @see #addItem(java.awt.Image, java.lang.String, boolean)
* @see #setListItems(java.lang.String[])
*/
public synchronized void addItem(Image image, String item)
{
addItem(image, item, true);
}
/**
* Adds the specified item with an image to the end of drop-down list and
* conditionally enable it.
* @param image the image to display on item line
* @param item the item to be added
* @param bEnabled whether or not the item is enabled
* @see #addItem(java.lang.String)
* @see #addItem(java.lang.String, boolean)
* @see #addItem(java.awt.Image, java.lang.String)
* @see #setListItems(java.lang.String[])
*/
public synchronized void addItem(Image image, String item, boolean bEnabled)
{
list.addItem(image, item, bEnabled);
arrow.enable();
}
/**
* Adds the string array to the list.
* @param items items to add to the list
* @see #getListItems
* @see #addItem(java.lang.String)
* @see #addItem(java.lang.String, boolean)
* @see #addItem(java.awt.Image, java.lang.String)
* @see #addItem(java.awt.Image, java.lang.String, boolean)
*/
public void setListItems(String[] items)
{
clear();
for (int i = 0; i < items.length; ++i)
{
addItem(items[i]);
}
}
/**
* Returns the current list as a array.
* @see #setListItems
*/
public String[] getListItems()
{
int len = countItems();
String[] items = new String[len];
for (int i = 0; i < len; ++i)
{
items[i] = getItem(i);
}
return items;
}
/**
* Returns the number of items in the drop-down list.
*/
public int countItems()
{
return list.countItems();
}
/**
* Returns the drop-down item at the specified zero-relative index.
*/
public String getItem(int index)
{
return list.getItem(index);
}
/**
* Changes the image associated with a drop-down item.
* @param index the zero-relative index of the drop-down item
* @param image the image to associate with the drop-down item
*/
public void changeImage(int index, Image image)
{
list.changeImage(index, image);
}
/**
* Changes the text associated with a drop-down item.
* @param index the zero-relative index of the drop-down item
* @param text the text to associate with the drop-down item
*/
public void changeText(int index, String text)
{
list.changeText(index, text);
}
/**
* Enables a drop-down item at a given zero-relative list index.
* @param index the zero-relative index of the drop-down item
* @see #disable
*/
public void enable(int index)
{
list.enable(index);
}
/**
* Disables a drop-down item at a given zero-relative list index.
* @param index the zero-relative index of the drop-down item
* @see #enable
*/
public void disable(int index)
{
list.disable(index);
}
/**
* Conditionally enables a drop-down item at a given zero-relative list index.
* @param index the zero-relative index of the drop-down item
* @param cond item enable condition (true = enable, false = disable)
* @see #disable
*/
public void enable(int index, boolean cond)
{
if (cond)
{
list.enable(index);
}
else
{
list.disable(index);
}
}
/**
* Deletes an item from the drop-down list.
* @param position the zero-relative index of the item
* @see #addItem(java.lang.String)
* @see #addItem(java.lang.String, boolean)
* @see #addItem(java.awt.Image, java.lang.String)
* @see #addItem(java.awt.Image, java.lang.String, boolean)
* @see #setListItems(java.lang.String[])
*/
public synchronized void delItem(int position)
{
delItems(position, position);
}
/**
* Deletes multiple items from the drop-down list.
* (Note: the end position must be greater than or equal to the start position.)
* @param start the start zero-relative index of the items
* @param end the end zero-relative index of the items
* @see #addItem(java.lang.String)
* @see #addItem(java.lang.String, boolean)
* @see #addItem(java.awt.Image, java.lang.String)
* @see #addItem(java.awt.Image, java.lang.String, boolean)
* @see #setListItems(java.lang.String[])
*/
public synchronized void delItems(int start, int end)
{
list.delItems(start, end);
if (list.countItems() == 0)
{
arrow.disable();
dropList(false);
}
}
/**
* Deletes the selected item from the list.
* @see #addItem(java.lang.String)
* @see #addItem(java.lang.String, boolean)
* @see #addItem(java.awt.Image, java.lang.String)
* @see #addItem(java.awt.Image, java.lang.String, boolean)
* @see #setListItems(java.lang.String[])
*/
public synchronized void delSelectedItem()
{
list.delSelectedItems();
}
/**
* Returns the text in the text field portion of the ComboBox, unless the ComboBox
* is not editable.
* @return edit field text (if editable) or null if ComboBox not editable
* @see #getSelectedItem
*/
public String getText()
{
verify();
return editBox.getText();
}
/**
* Returns the selected item on the drop-down list.
* @return text of selected item, or null if no item is selected
* @see #getText
* @see #getSelectedIndex
*/
public String getSelectedItem()
{
return list.getSelectedItem();
}
/**
* Gets the zero-relative index of the selected item in the drop-down list.
* @return zero-relative index of selection, or -1 if no item is selected
* @see #getSelectedItem
*/
public int getSelectedIndex()
{
return list.getSelectedIndex();
}
/**
* Selects the drop-down item with the specified zero-relative index.
* @param index the zero-relative index of the drop-down item to select
* @see #deselect
*/
public synchronized void select(int index)
{
if (index >= 0 && index <= list.countItems())
{
list.select(index);
editBox.setText(list.getSelectedItem());
if (bOsFlag)
{
repaint();
}
}
}
/**
* Selects the first drop-down item in the list which has exactly matching text.
* @param str the String to match
* @see #deselect
*/
public void select(String str)
{
list.select(str);
editBox.setText(list.getSelectedItem());
if (bOsFlag)
{
repaint();
}
}
/**
* Deselects the drop-down item at the specified zero-relative index.
* @param index the zero-relative index of the drop-down item to deselect
* @see #deselect
*/
public synchronized void deselect(int index)
{
list.deselect(index);
editBox.setText("");
}
/**
* Returns the selection state for the given zero-relative index.
* @param index the zero-relative index of the drop-down item to be checked
* @return true if the drop-down item at the specified index has been
* selected; false otherwise
* @see #select
*/
public synchronized boolean isSelected(int index)
{
return list.isSelected(index);
}
/**
* Sets this component's text font.
* This is a standard Java AWT method which gets called to change
* the font used for drawing text in this component.
* In this case the text is in the edit field and the drop-down list.
* @param f the new font to use for drawing text
* @see java.awt.Component#getFont
*/
public synchronized void setFont(Font f)
{
editFont = dropFont = f;
setEditFieldFont(f);
setDropDownFont(f);
super.setFont(f);
}
/**
* Handles dropping and "un-dropping" the ComboBox list.
* @param bDown true to drop the list, false to "un-drop" the list.
*/
public void dropList(boolean bDown)
{
if (this.bDown == bDown)
{
return;
}
this.bDown = bDown;
if (bDown)
{
if (currentlyDown != null && currentlyDown != this)
{
currentlyDown.dropList(false);
}
currentlyDown = this;
list.show();
list.setDirty();
list.repaint();
if (getParent() != null)
{
lheight = Math.min(getParent().bounds().height - iy - iheight - 10, list.minimumSize().height + 3);
}
else
{
lheight = list.minimumSize().height + 3;
}
arrow.setDirection(DirectionButton.UP);
}
else
{
lheight = 0;
currentlyDown = null;
list.hide();
arrow.setDirection(DirectionButton.DOWN);
invalidate();
}
arrow.repaint();
super.reshape(ix, iy, iwidth, iheight + lheight);
}
/**
* Moves and/or resizes this component.
* This is a standard Java AWT method which gets called to move and/or
* resize this component. Components that are in containers with layout
* managers should not call this method, but rely on the layout manager
* instead.
*
* @param x horizontal position in the parent's coordinate space
* @param y vertical position in the parent's coordinate space
* @param width the new width
* @param height the new height
*/
public synchronized void reshape(int x, int y, int width, int height)
{
ix = x;
iy = y;
iwidth = width;
if (bOsFlag)
{
iheight = Math.max(29, height);
}
else
{
iheight = height;
}
if (height > 22)
{
height -= 22;
if (bOsFlag)
{
x = y = 7;
}
else
{
x = y = 5;
}
while(height > 0)
{
x++;
height--;
if (height > 0)
{
y++;
height--;
}
}
arrow.shrinkTriangle(1, 1, x, y);
}
else
{
arrow.shrinkTriangle(1, 1, 5, 5);
}
super.reshape(ix, iy, iwidth, iheight + lheight);
}
/**
* Paints this component using the given graphics context.
* This is a standard Java AWT method which typically gets called
* by the AWT to handle painting this component. It paints this component
* using the given graphics context. The graphics context clipping region
* is set to the bounding rectangle of this component and its <0,0>
* coordinate is this component's top-left corner.
*
* @param g the graphics context used for painting
* @see java.awt.Component#repaint
* @see java.awt.Component#update
*/
public void paint(Graphics g)
{
super.paint(g);
Dimension s = size();
if (bDown)
{
list.reshape(0, iheight+1, s.width, lheight);
}
if (symantec.itools.lang.OS.isMacintosh())
editBox.reshape(0,(int)(iheight* 0.1), s.width-16,(int)(iheight*0.8));
else
editBox.reshape(0,0, s.width-16, iheight);
editBox.setText(list.getSelectedItem()); // so we can get an item to show
// w/o an event (see constructor) - Andy
if (symantec.itools.lang.OS.isMacintosh())
arrow.reshape(s.width-16,(int)(iheight* 0.1), 15, (int)(iheight*0.8));
else
{
if (bOsFlag)
{
arrow.reshape(s.width-16, 2, 15, iheight-4);
}
else
{
arrow.reshape(s.width-16, 1, 15, iheight-2);
}
}
}
/**
* Returns the recommended dimensions to properly display this component.
* @return the preferred size with the specified number of rows if the
* row size is greater than 0.
*/
/**
* Returns the recommended dimensions to properly display this component.
* This is a standard Java AWT method which gets called to determine
* the recommended size of this component.
*
* @see #minimumSize
*/
public Dimension preferredSize()
{
Dimension s = size();
Dimension d = minimumSize();
return new Dimension(Math.max(s.width, d.width), Math.max(s.height, d.height));
}
/**
* Returns the minimum dimensions to properly display this component.
* This is a standard Java AWT method which gets called to determine
* the minimum size of this component.
* Considerations include the number of rows in the list.
* @see #preferredSize
*/
public Dimension minimumSize()
{
Dimension d = editBox.minimumSize();
d.width += 17;
if (d.height == 0)
{
if (bOsFlag)
{
d.height = 29;
}
else
{
d.height = 21;
}
}
return d;
}
private void verify()
{
if (bSearchable == true)
{
searchIndex = editBox.getSelectionStart();
sSearchOrig = editBox.getText().substring(0, searchIndex);
if (bCaseSensitive)
{
sSearchText = sSearchOrig;
}
else
{
sSearchText = sSearchOrig.toUpperCase();
}
searchLen = list.countItems();
if (sSearchText.length() > 0)
{
for(searchI = 0; searchI < searchLen; ++searchI)
{
if (bCaseSensitive)
{
sSearchItem = list.getItem(searchI);
}
else
{
sSearchItem = list.getItem(searchI).toUpperCase();
}
if (sSearchItem.startsWith(sSearchText))
{
editBox.setText(sSearchOrig);
list.select(searchI);
editBox.select(searchIndex, searchIndex);
break;
}
}
if (!bEditable && (searchI == searchLen)) // !editable && search failed
{
editBox.setText(sLastText);
editBox.select(searchIndex-1, searchIndex-1);
}
}
}
sLastText = editBox.getText();
}
}