Java 将侦听器添加到 ArrayList

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6578308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:54:17  来源:igfitidea点击:

Add listener to ArrayList

javaarraylistlistener

提问by Eng.Fouad

I have an ArrayList which I add some Objects to it dynamically, and I have a JButton. The ArrayList is empty when running my program and the JButton is set to setEnabled(false). I want to enable my button whenever there are 2 elements in the ArrayList or more and disable it again if the ArrayList has one item or empty. How can I achieve this?

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

采纳答案by Jon Skeet

ArrayListdoesn't have any sort of notification mechanism.

ArrayList没有任何通知机制。

I suggest you write your own Listimplementation which delegates to a private ArrayListfor its storage, but adds the ability to listen for notifications... or find something similar within Java itself. DefaultListModelmaywork for you, although it doesn't implement Listitself.

我建议您编写自己的List实现,将其委托给私有ArrayList存储,但增加了侦听通知的能力……或者在 Java 本身中找到类似的东西。可能对你有用,虽然它没有实现自己。DefaultListModelList

回答by Harry Joy

You can't do such thing with ArrayList because as @Jon Skeet says ArrayList doesn't have any sort of notification mechanism. You should try JGoodies binding ObservableListthat could help.

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

Or you could set up a timer that will check for the size of ArrayList and change JButton accordingly. You will require a thread to do this job of monitoring list at some time interval.

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

Or if you know all the place where you add/remove elements from list then write this login at all that place.

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

回答by trashgod

If you write your own Listimplementation, as @Jon Skeet suggests, you can give it an EventListenerList. The API outlines the relevant methods.

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

回答by Tapas Bose

As @Jon Skeet suggests you can also do something like :

正如@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);
    }
}

回答by Michael Baldauf

Javafx (part of JRE 8) provides an observable list implementation. This code works for me:

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

回答by jdz

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

回答by RodMendez

Following SimpleIntegerProperty syntax I made an ArrayList which fire when the size change. In this case you need to now the current size of the ArrayList since you want to react when the size is 2, so a simple solution to this is doing the following:

遵循 SimpleIntegerProperty 语法,我创建了一个 ArrayList,它在大小改变时触发。在这种情况下,您现在需要 ArrayList 的当前大小,因为您希望在大小为 2 时做出反应,因此一个简单的解决方案是执行以下操作:

ArrayListProperty.java

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

In this case the observable is the size of the array, then, when declaring your arraylist, you can add a listener and act when the size is 2.

在这种情况下,observable 是数组的大小,然后,在声明数组列表时,您可以添加一个侦听器并在大小为 2 时进行操作。

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

This implementation also allows you to add a comparison in the ChangeListener so you can know when there was something added or something removed. Also you can store the object added or removed and have it in the listener.

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

回答by Chamly Idunil

If you need to fix this issue using only java.util.ArrayList you can use below solution. I don't know this is the exact solution you want. But you can achieve your need as below.

如果您需要仅使用 java.util.ArrayList 解决此问题,您可以使用以下解决方案。我不知道这是您想要的确切解决方案。但是您可以按如下方式实现您的需求。

Implement what should happen after added and removed. Customize this interface as you needed.

实现添加和删除后应该发生的事情。根据需要自定义此界面。

public interface ListBehaviorHandler {

    void afterAdded();
    void afterDeleted();
}

And use below method to get custom behave list.

并使用以下方法获取自定义行为列表。

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