Добавить слушателя в ArrayList - PullRequest
16 голосов
/ 05 июля 2011

У меня есть ArrayList, в который я динамически добавляю несколько объектов, и у меня есть JButton.ArrayList пуст при запуске моей программы, а JButton установлен в setEnabled (false).Я хочу включить мою кнопку всякий раз, когда в ArrayList есть 2 элемента или более, и отключить ее снова, если ArrayList имеет один элемент или пуст.Как мне этого добиться?

Ответы [ 8 ]

14 голосов
/ 20 августа 2015

Javafx (часть JRE 8) предоставляет наблюдаемую реализацию списка. Этот код работает для меня:

ObservableList<MyAnno> lstAnno1 = FXCollections.observableList(new ArrayList<MyAnno>());

lstAnno1.addListener((ListChangeListener.Change<? extends MyAnno> c) -> {
   c.next();
   updateAnnotation((List<MyAnno>) c.getAddedSubList(), xyPlot);
});

...
lstAnno1.add(new MyAnno(lTs, dValue, strType));
...

public void updateAnnotation(List<MyAnno> lstMyAnno, XYPlot xyPlot) {
   lstMyAnno.forEach(d -> {
   ...
   });
}
13 голосов
/ 05 июля 2011

ArrayList не имеет какого-либо механизма уведомления.

Я предлагаю вам написать собственную реализацию List, которая делегирует приватное ArrayList для своего хранилища, но добавляет возможность прослушивать уведомления ... или находить что-то подобное в самой Java. DefaultListModel может работать на вас, хотя сам по себе List не реализует.

10 голосов
/ 05 июля 2011

Как @Jon Skeet предлагает, вы можете сделать что-то вроде:

public class ListResponseModel<E> extends AbstractListModel {

    private static final long serialVersionUID = 1L;

    private ArrayList<E> delegate = new ArrayList<E>();

    @Override
    public int getSize() {
        return delegate.size();
    }

    @Override
    public Object getElementAt(int index) {
        return delegate.get(index);
    }

    public void add(E e){
        int index = delegate.size();
        delegate.add(e);
        fireIntervalAdded(this, index, index);
    }
}
3 голосов
/ 06 июля 2016
ObservableList<DynamicObjects> ol = FXCollections.ObservableArrayList(new ArrayList<DynamicObjects>());
ListProperty lp = new SimplePropertyList(ol);

lp.addListener(new ChangeListener(){
        @Override public void changed(ObservableValue o, Object oldVal,
                                      Object newVal){
            if (ol.size() > 1 && !JButton.isEnabled()) {
                JButton.setEnable(true);
            } else if (ol.size < 2 && JButton.isEnabled()) {
                JButton.setEnable(false);
            }
    });
3 голосов
/ 05 июля 2011

Если вы напишите свою собственную реализацию List, как предлагает @Jon Skeet, вы можете дать ей EventListenerList.API описывает соответствующие методы.

3 голосов
/ 05 июля 2011

Вы не можете делать такие вещи с ArrayList, потому что, как говорит @Jon Skeet, ArrayList не имеет какого-либо механизма уведомления.Вам следует попробовать привязку JGoodies ObservableList, которая может помочь.

Или вы можете установить таймер, который будет проверять размер ArrayList и соответственно изменять JButton.Вам потребуется поток, чтобы выполнить эту работу по мониторингу списка через некоторый промежуток времени.

Или, если вы знаете все места, где вы добавляете / удаляете элементы из списка, напишите этот логин во всех местах.

0 голосов
/ 07 сентября 2018

Если вам нужно решить эту проблему, используя только java.util.ArrayList, вы можете использовать приведенное ниже решение.Я не знаю, какое именно решение вы хотите.Но вы можете достичь своей потребности, как показано ниже.

Реализация того, что должно произойти после добавления и удаления.Настройте этот интерфейс так, как вам нужно.

public interface ListBehaviorHandler {

    void afterAdded();
    void afterDeleted();
}

И используйте метод ниже, чтобы получить пользовательский список поведения.

public <E> List<E> getCustomList(ListBehaviorHandler listBehaviorHandler) {
        return new ArrayList<E>() {
            @Override
            public boolean add(E e) {
                boolean added = super.add(e);
                listBehaviorHandler.afterAdded();
                return added;
            }

            @Override
            public void add(int index, E element) {
                super.add(index, element);
                listBehaviorHandler.afterAdded();
            }

            @Override
            public E remove(int index) {
                E removed = super.remove(index);
                listBehaviorHandler.afterDeleted();
                return removed;
            }

            @Override
            public boolean remove(Object o) {
                boolean removed = super.remove(o);
                listBehaviorHandler.afterDeleted();
                return removed;
            }
        };
    }
0 голосов
/ 28 июля 2017

Следуя синтаксису SimpleIntegerProperty, я создал ArrayList, который срабатывает при изменении размера.В этом случае вам нужен текущий размер ArrayList, поскольку вы хотите реагировать, когда размер равен 2, поэтому простое решение этого заключается в следующем:

ArrayListProperty.java

public class ArrayListProperty<E> extends ArrayList<E> implements ObservableValue<Number> {
    private ExpressionHelper<Number> helper = null;
    private SimpleIntegerProperty sizeProperty;

    public ArrayListProperty(){
        super();
        sizeProperty = new SimpleIntegerProperty(0);
    }

    @Override
    public boolean add(E e) {
        boolean returnValue = super.add(e);
        sizeProperty.set(size());
        fireValueChangedEvent();
        return returnValue;
    }

    @Override
    public void add(int index, E element) {
        super.add(index, element);
        sizeProperty.set(size());
        fireValueChangedEvent();
    }

    @Override
    public E remove(int index) {
        E returnValue = super.remove(index);
        sizeProperty.set(size());
        fireValueChangedEvent();
        return returnValue;
    }

    @Override
    public boolean remove(Object o) {
        boolean returnValue = super.remove(o);
        if(returnValue){
            sizeProperty.set(size());
            fireValueChangedEvent();
        }
        return returnValue;
    }

    protected void fireValueChangedEvent(){
        ExpressionHelper.fireValueChangedEvent(helper);
    }

    @Override
    public void addListener(ChangeListener<? super Number> listener) {
        helper = ExpressionHelper.addListener(helper, sizeProperty, listener);
    }

    @Override
    public void removeListener(ChangeListener<? super Number> listener) {
        helper = ExpressionHelper.removeListener(helper, listener);
    }

    @Override
    public Number getValue() {
        return null;
    }

    @Override
    public void addListener(InvalidationListener listener) {
        helper = ExpressionHelper.addListener(helper, sizeProperty, listener);
    }

    @Override
    public void removeListener(InvalidationListener listener) {
        helper = ExpressionHelper.removeListener(helper, listener);
    }
}

В этом случае наблюдаемым является размер массива, тогда при объявлении вашего массива вы можете добавить слушателя и действовать, когда размер равен 2.

ArrayListProperty<Object> arrayList = new ArrayListProperty<>();
arrayList.addListener((ob, ov, nv) -> { 
    if(nv.intValue() == 2) doSomething();
});

Эта реализация также позволяет вамдобавьте сравнение в ChangeListener, чтобы вы могли знать, когда что-то было добавлено или что-то удалено.Также вы можете сохранить добавленный или удаленный объект и поместить его в прослушиватель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...