将侦听器添加到ArrayList

时间:2011-07-05 05:37:08

标签: java arraylist listener

我有一个ArrayList,我动态地添加了一些对象,我有一个JButton。运行我的程序时,ArrayList为空,JButton设置为setEnabled(false)。我想在ArrayList中有2个元素时启用我的按钮,如果ArrayList有一个项目或为空,则再次禁用它。我怎样才能做到这一点?

8 个答案:

答案 0 :(得分:14)

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 -> {
   ...
   });
}

答案 1 :(得分:13)

ArrayList没有任何通知机制。

我建议您编写自己的List实现,该实现委托私有ArrayList进行存储,但增加了监听通知的能力......或者在Java本身内找到类似的东西。 DefaultListModel 可能为您工作,但它本身并未实现List

答案 2 :(得分:10)

正如@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 :(得分:3)

你不能用ArrayList做这件事,因为@Jon Skeet说ArrayList没有任何通知机制。您应该尝试JGoodies绑定ObservableList,这可能有所帮助。

或者您可以设置一个计时器来检查ArrayList的大小并相应地更改JButton。您将需要一个线程在某个时间间隔执行监视列表的工作。

或者,如果您知道从列表中添加/删除元素的所有位置,请在所有位置写下此登录信息。

答案 4 :(得分:3)

如果你编写自己的List实现,正如@Jon Skeet建议的那样,你可以给它一个EventListenerList。 API概述了相关方法。

答案 5 :(得分:3)

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

答案 6 :(得分:0)

遵循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);
    }
}

在这种情况下,observable是数组的大小,然后,在声明你的arraylist时,你可以添加一个监听器并在大小为2时动作。

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

此实现还允许您在ChangeListener中添加比较,以便您可以知道何时添加了某些内容或删除了某些内容。您还可以存储添加或删除的对象,并将其放在侦听器中。

答案 7 :(得分:0)

如果仅需要使用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;
            }
        };
    }