Как легко получить ссылку на данные из выпадающего списка SWT Combo - PullRequest
2 голосов
/ 19 июня 2020

Как получить ссылку на данные из выпадающего списка SWT Combo? В настоящее время мне нужно получить текст из поля со списком, а затем пройтись по моим объектам данных, пока я не найду тот, который имеет тот же текст, что и в поле со списком.

    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() );

Хотя это работает, оно склонно к различным ошибкам, а также интенсивной загрузке процессора, особенно для больших списков. Я действительно знал sh, что у Combo были бы методы setData () и getData () для каждого элемента Combo.

Ответы [ 2 ]

2 голосов
/ 19 июня 2020

Один простой способ связать данные с элементами поля со списком - использовать оболочку JFace модель-представление ComboViewer.

Затем установите три параметра в следующем порядке:

  1. Поставщик содержимого, который указывает, как получить элементы из вводимых вами далее данных. (Часто это просто ArrayContentProvider для моделей, которые являются либо массивом или коллекцией.)
  2. Модель для использования в качестве входных данных. Каждый элемент в вашей модели может иметь ссылку на произвольные пользовательские данные.
  3. Поставщик меток, который предоставляет метки для элементов.

Например:

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

Как только вы это сделаете, есть механизмы для получения выбранного элемента - или вы можете получить завернутый Combo, запросить его выбранный индекс и использовать этот индекс для доступа к элементу вашей модели.

2 голосов
/ 19 июня 2020

Я создал класс, который позволяет связать объект с полем Combo "add ()". Этот класс вернет объект напрямую, без его преобразования. Моя первая попытка создать общий c класс: -)

Базовый c синтаксис для его использования (Комбо ДОЛЖЕН быть установлен на 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();

Это:

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();
        }
    }
}

Создайте класс под названием ComboData в вашем пакете инструментов, затем скопируйте и вставьте в него код сразу под оператором пакета.

...