J'ai un ArrayList auquel j'y ajoute dynamiquement des objets, et un JButton. ArrayList est vide lors de l'exécution de mon programme et le JButton est défini sur setEnabled (false). Je veux activer mon bouton chaque fois qu'il y a 2 éléments dans la liste de tableaux ou plus, et le désactiver à nouveau si la liste de tableaux contient un élément ou est vide. Comment puis-je atteindre cet objectif?
ArrayList
ne dispose d'aucun mécanisme de notification.
Je vous suggère d'écrire votre propre implémentation List
qui délègue à une ArrayList
privée pour son stockage, mais ajoute la possibilité d'écouter les notifications ... ou de trouver quelque chose de similaire dans Java même. DefaultListModel
peut fonctionne pour vous, bien qu'il n'implémente pas List
lui-même.
Javafx (composant de JRE 8) fournit une implémentation de liste observable. Ce code fonctionne pour moi:
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 -> {
...
});
}
Comme @Jon Skeet suggère que vous pouvez également faire quelque chose comme:
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);
}
}
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);
}
});
Vous ne pouvez pas faire une telle chose avec ArrayList car, comme le dit @ Jon Skeet, ArrayList ne dispose d'aucun mécanisme de notification. Vous devriez essayer JGoodies qui lie ObservableList
qui pourrait vous aider.
Vous pouvez également configurer un minuteur qui vérifiera la taille de ArrayList et modifiera JButton en conséquence. Vous aurez besoin d'un thread pour faire ce travail de liste de suivi à un certain intervalle de temps.
Ou si vous connaissez tout le lieu où vous ajoutez/supprimez des éléments de la liste, écrivez ce login à tout ce lieu.
Si vous écrivez votre propre implémentation List
, comme le suggère @Jon Skeet, vous pouvez lui donner un EventListenerList
. L'API décrit les méthodes pertinentes.
En suivant la syntaxe SimpleIntegerProperty, j'ai créé un ArrayList qui se déclenche lorsque la taille change. Dans ce cas, vous devez maintenant définir la taille actuelle de ArrayList, car vous souhaitez réagir lorsque la taille est égale à 2, une solution simple consiste à procéder comme suit:
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);
}
}
Dans ce cas, l’observable est la taille du tableau, puis, lors de la déclaration de votre liste, vous pouvez ajouter un écouteur et agir lorsque la taille est 2.
ArrayListProperty<Object> arrayList = new ArrayListProperty<>();
arrayList.addListener((ob, ov, nv) -> {
if(nv.intValue() == 2) doSomething();
});
Cette implémentation vous permet également d'ajouter une comparaison dans ChangeListener afin de savoir quand quelque chose a été ajouté ou supprimé. Aussi, vous pouvez stocker l'objet ajouté ou supprimé et l'avoir dans l'écouteur.
Si vous devez résoudre ce problème en utilisant uniquement Java.util.ArrayList, vous pouvez utiliser la solution ci-dessous. Je ne sais pas si c'est la solution exacte que vous voulez. Mais vous pouvez réaliser votre besoin comme ci-dessous.
Implémenter ce qui devrait arriver après ajouté et supprimé. Personnalisez cette interface selon vos besoins.
public interface ListBehaviorHandler {
void afterAdded();
void afterDeleted();
}
Et utilisez la méthode ci-dessous pour obtenir une liste de comportements personnalisée.
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;
}
};
}