Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to easily get a data reference from an SWT Combo drop list

Tags:

java

combobox

swt

How do you get a data reference from an SWT Combo drop list? Currently I need to get the text from the Combo box, then run through my data objects until I reach one that has the same text as what the Combo box reports.

    Combo combo = new Combo( new Shell(), SWT.READ_ONLY );

    for (Person person : People.getPeople())
        combo.add( person.getName() );

    for (Person person : People.getPeople())
        if (combo.getText().equals( person.getName() ))
            System.out.println( "Person: " + person.getFullName() );

While this works, it is prone to various errors, and also CPU intensive especially for large lists. I really wish that a Combo would had "setData()" and "getData()" methods for each Combo item.

like image 334
Big Guy Avatar asked Jan 18 '26 08:01

Big Guy


1 Answers

I have created a class which allows an object to be associated with a Combo box "add()". This class will return the object directly without casting it. My first crack at creating a generic class :-)

Basic syntax to use it is (the Combo MUST be set to SWT.READ_ONLY):

Combo peopleBaseCombo = new Combo(shell, SWT.READ_ONLY);
ComboData<Person> peopleCombo = new ComboData<Person>(peopleBaseCombo);

for ( Person person : People.getPeople())
   peopleCombo.addItem(person, person.getLastName);

...

Person person = peopleCombo.getCurrentItem();

The class is:

import java.util.ArrayList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Combo;

/**
 * A generic wrapper around a standard SWT {@link Combo} control.
 * Allows for using arbitrary data objects associated with the displayed text.
 * Assumes a {@link SWT#READ_ONLY} combo drop list<br><br>
 * <blockquote>Combo peopleBaseCombo = new Combo(shell, SWT.READ_ONLY);<br>
 * ComboData&lt;Person&gt; peopleCombo = new ComboData&lt;Person&gt;(peopleBaseCombo);<br><br>
 * for ( Person person : People.getPeople())<br>
 * &nbsp;&nbsp;&nbsp;peopleCombo.addItem(person, person.getLastName);<br>
 * <br>
 * ...<br>
 * <br>
 * Person person = peopleCombo.getCurrentItem();</blockquote>
  */
public class ComboData<T>
{
    private ArrayList<ComboItem<T>> ivItemList;
    private Combo                   ivCombo;

    /**
     * Create a ComboControl for the passed Combo control
     * @param combo - SWT {@link Combo} control
     */
    public ComboData( Combo combo )
    {
        super();

        ivCombo = combo;
        ivItemList = new ArrayList<>();

        removeAll();
     }

    /**
     * Adds an item to the controller along with the text you want shown in the Combo
     * @param itemData - the data item of the defined type
     * @param text - the text which will be shown in the Combo control
     */
    public void addItem( T itemData, String text )
    {
        // these are added at the same time, and therefore have the same index location
        ivItemList.add( new ComboItem<T>( itemData, text ) );
        ivCombo.add( text );
    }

    /**
     * Removes all the items in the list and Combo
     */
    public void removeAll()
    {
        ivItemList.clear();
        ivCombo.removeAll();
    }

    /**
     * Returns the combo held by this control
     */
    public Combo getCombo()
    {
        return ivCombo;
    }

    /**
     * Set the current displayed item in the Combo using the associated data object
     * @param setItemData - Sets the Combo display to the text associated with the setItemData
     */
    public void setCurrentItem( T setItemData )
    {
        for (ComboItem<T> item : ivItemList)
            if (item.getItemData().equals( setItemData ))
            {
                ivCombo.setText( item.getText() );
                return;
            }

        if (ivItemList.size() > 0)
            ivCombo.setText( ivItemList.get( 0 ).getText() );
    }

    /**
     * Gets the currently chosen ComboItem associated with the Combo control displayed text
     * @return the data item associated with the displayed text
     */
    public T getCurrentItem()
    {
        ComboItem<T> currentItem;

        try
        {
            currentItem = ivItemList.get( ivCombo.getSelectionIndex() );
        }
        catch (IndexOutOfBoundsException e)
        {
            try
            {
                currentItem = ivItemList.get( 0 );
            }
            catch (IndexOutOfBoundsException e1)
            {
                // will only happen if this method is called before there are any items in the list
                return null;
            }
        }

        return currentItem.getItemData();
    }

    @Override
    public String toString()
    {
        StringBuilder info = new StringBuilder();
        String className;

        try
        {
            className = getCurrentItem().getClass().getName();
        }
        catch (NullPointerException e)
        {
            className = "";
        }

        info.append( "ComboControl (" );
        info.append( className );
        info.append( "):" );

        for (ComboItem<T> item : ivItemList)
        {
            info.append( "\n  " );
            info.append( item.getInformation() );
        }

        return info.toString();
    }

    /**
     * The item holding both the Combo control text, and its associated data
     */
    private class ComboItem<I>
    {
        private String ivText;
        private I      ivItemData;

        /**
         * Create the Combo item using the arbitrary data and the text to be displayed
         */
        private ComboItem( I itemData, String text )
        {
            super();

            ivItemData = itemData;
            ivText = text;
        }

        /**
         * Get the text to be displayed in the Combo control
         */
        private String getText()
        {
            return ivText;
        }

        /**
         * Get the object associated with the text shown in the Combo control
         */
        private I getItemData()
        {
            return ivItemData;
        }

        /**
         * Gets information about the item and its data item
         */
        private String getInformation()
        {
            return ivText + ": " + ivItemData.toString();
        }
    }
}

Create a class called ComboData in your tools package, then copy paste the code into it, just below the package statement.

like image 133
Big Guy Avatar answered Jan 19 '26 21:01

Big Guy