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

佐手、 提交于 2020-06-28 12:32:17

问题


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.


回答1:


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.




回答2:


One easy way to associate data with combo box items is to use the JFace model-view wrapper ComboViewer.

Then, set three things, in this order:

  1. A content provider, which specifies how to get elements out of the input you provide next. (Frequently, this is just an ArrayContentProvider, for models that are either an array or collection.)
  2. The model to use as input. Each element in your model can have a reference to arbitrary user data.
  3. A label provider that provides labels for elements.

For example:

    myCombo.setContentProvider(new ArrayContentProvider());
    myCombo.setInput( myModel );
    myCombo.setLabelProvider(new LabelProvider() {
      @Override
      public String getText(Object element) { ... }
    });

Once you've done that, there are mechanisms to get the selected element -- or you can get the wrapped Combo, ask it for its selected index, and use that index to access an element of your model.



来源:https://stackoverflow.com/questions/62477570/how-to-easily-get-a-data-reference-from-an-swt-combo-drop-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!