JavaFX Property for a BitSet - java

I need a JavaFX Property for a BitSet in order to create a TableColumn with a toggle button for each bit in the BitSet. I have implemented Property<BitSet> but even with the oracle documentation the meaning and usage of some of the interface methods still eludes me, as for me this all looks like superfluous boilerplate. Please tell me if I am on the right track with the implementation and what I can improve. I didn't implement bindings yet because I don't expect to need them for my use case.
import java.util.*;
import javafx.beans.InvalidationListener;
import javafx.beans.property.Property;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
public class BitSetProperty implements Property<BitSet>
{
private BitSet value;
private final Set<ChangeListener<? super BitSet>> changeListeners = new HashSet<>();
private final Set<InvalidationListener> invalidationListeners = new HashSet<>();
#Override public Object getBean() {return value;}
#Override public String getName() {return "what shall I return here?";}
#Override public void addListener(ChangeListener<? super BitSet> listener) {changeListeners.add(listener);}
#Override public void removeListener(ChangeListener<? super BitSet> listener) {changeListeners.remove(listener);}
#Override public BitSet getValue()
{
return (BitSet)value.clone();
}
#Override public void addListener(InvalidationListener listener) {invalidationListeners.add(listener);}
#Override public void removeListener(InvalidationListener listener) {invalidationListeners.remove(listener);}
#Override public void setValue(BitSet value)
{
if(!value.equals(this.value))
{
changeListeners.stream().forEach(cl->cl.changed(this, this.value, (BitSet)value.clone()));
invalidationListeners.stream().forEach(il->il.invalidated(this));
}
this.value=value;
}
#Override public void bind(ObservableValue<? extends BitSet> observable)
{
throw new UnsupportedOperationException();
}
#Override public void unbind()
{
throw new UnsupportedOperationException();
}
#Override public boolean isBound()
{
// TODO Auto-generated method stub
return false;
}
#Override public void bindBidirectional(Property<BitSet> other)
{
throw new UnsupportedOperationException();
}
#Override public void unbindBidirectional(Property<BitSet> other)
{
throw new UnsupportedOperationException();
}
}

Answering my own question as it turns out I misunderstood how properties work.
I thought they trigger change events when the internal state changes but I know now that they treat the content as a black box (I guess assuming the content is immutable) and just trigger when the content is replaced, which is a much easier problem. My question can then be solved using:
ObjectProperty<BitSet> property = new SimpleObjectProperty<>();

Related

How to make a complex object an Observable

I have multiple JavaFX panes and canvases that reference a complex object with data they need, and I want them to redraw when the object changes.
This would call for the object to be Observable, but which class do I use? JavaFX seems to mostly have ObservableValue subclasses, which wrap a value and allow swapping it out. I don't want to swap out the complex object, just notify the listeners when changes occur. I could do that by implementing addListener, but I'm sure there's a subclass that does it for me already.
class ComplexObject /* extends SomeObservableClass */ {
public int getValue1 { complex calculations... };
public int getValue2 { ... };
public void setNewValue1(int newValue) { ... }
}
class ComplexRenderer extends Canvas implements InvalidationListener {
private ComplexObject complexObject;
public void setComplexObject(ComplexObject complexObject) {
this.complexObject = complexObject;
complexObject.addListener(this);
}
public void draw() { ... }
}
Which class should ComplexObject extend? Is there something that maintains the list of listeners and has something like fireValueChangedEvent() so I can make it notify all listeners?
Everything I see in JavaFX seems to be geared towards properties, which don't seem the right choice here.
Not really sure what you meant by swapping, and not really sure if I understood you right.
class ComplexObject {
private IntegerProperty value1 = new SimpleIntegerProperty();
private IntegerProperty value2 = new SimpleIntegerProperty();
private BooleanProperty internalChanged = new SimpleBooleanProperty(false);
public ComplexObject() {
this.internalChanged.bind(Bindings.createBooleanBinding(() ->
this.internalChanged.set(!this.internalChanged.get()), this.value1, this.value2));
}
public IntegerProperty value1Property() { return this.value1; }
public int getValue1() { return this.value1.get(); }
public void setValue1(int value) { return this.value1.set(value); }
public IntegerProperty value2Property() { return this.value2; }
public int getValue2() { return this.value2.get(); }
public void setValue2(int value) { return this.value2.set(value); }
public void setNewValue1(int newValue) { /* What value is this??? */ }
public BooleanProperty internalChangedProperty() { return this.internalChanged; }
}
class ComplexRenderer extends Canvas implements InvalidationListener {
private ComplexObject complexObject;
public void setComplexObject(ComplexObject complexObject) {
this.complexObject = complexObject;
complexObject.internalChangedProperty().addListener(this);
}
#Override public void invalidated(Observable observable) {
// Something inside complex object changed
}
public void draw() { ... }
}
Maybe you can have a look at the Interface ObjectPropertyBase<T> and the classes ObjectPropertyBase<T> and SimpleObjectProperty<T> which implements Observable.
However you have to define when your object changes and listening logic.
I'm sorry it's just a trace of work, but I hope it may be useful.

Can I generify the following code?

I have some methods in a class like this:
#Override
public void sendRemoteRecord(String token, int channelId, int eventId, final ServiceCallback<RemoteRecordResponse> callback) {
epgServicesApiManager.sendRemoteRecord(token, channelId, eventId)
.observeOn(scheduler)
.subscribe(new Action1<RemoteRecordResponse>() {
#Override
public void call(RemoteRecordResponse model) {
if (callback != null)
callback.onSuccess(model);
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
if (callback != null)
callback.onError();
}
});
}
#Override
public void activateRemoteRecord(String token, String cardNumber, final ServiceCallback<RemoteRecordActivateResponse> callback) {
epgServicesApiManager.activateRemoteRecord(token, cardNumber)
.observeOn(scheduler)
.subscribe(new Action1<RemoteRecordActivateResponse>() {
#Override
public void call(RemoteRecordActivateResponse remoteRecordActivateResponse) {
if (callback != null)
callback.onSuccess(remoteRecordActivateResponse);
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
if (callback != null)
callback.onError();
}
});
}
Is it possible to remove the duplication around the code after the observeOn() line?
The annoying part is making sure I do the null check on the callback before using it.
At present, I know of seven distinct methods I need in this class and possibly more.
Unfortunately, in Java 1.7 there is no way to fix this without increasing the amount of code. You can reduce the amount of code needed locally, by introducing some helper classes.
One solution is to move your anonymous inner classes to top-level classes. From there you can introduce a dummy callback and some null-checking work an an abstract class.
It may end up looking something like this (horizontal rules are used to highlight that these classes are in separate files).
This is a dummy callback class, it does exactly nothing, but is safe to call against. This will replace the null values.
public class NullServiceCallBack<T> implements ServiceCallBack<T> {
#Override
public void onSuccess(T target) {}
#Override
public void onError() {}
}
This is an abstract class that handles the validation, converting null values to instances of NullServiceCallback:
public abstract class CallBackAction<T> implements Action1<T> {
private final ServiceCallBack<T> Callback;
public CallBackAction(ServiceCallBack<T> callback) {
this.Callback = (null != callback) ? callback : new NullServiceCallBack<>();
}
protected ServiceCallBack<T> getCallback() {
return Callback;
}
}
This is the concrete class you'll use for success.
public class SuccessCallbackAction<T> extends CallBackAction<T> {
public SuccessCallbackAction(ServiceCallBack<T> callback) {
super(callback);
}
#Override
public void call(T target) {
getCallback().onSuccess(target);
}
}
This is the concrete class for errors. This doesn't do anything with the arguments to call, so we can make this implement for Object once and be done with it.
public class ErrorCallbackAction extends CallBackAction<Object> {
public ErrorCallbackAction(ServiceCallBack<Object> callback) {
super(callback);
}
#Override
public void call(Throwable target) {
getCallback().onError();
}
}
So in the end, your example above should look something like this:
#Override
public void sendRemoteRecord(String token, int channelId, int eventId, final ServiceCallback<RemoteRecordResponse> callback) {
epgServicesApiManager.sendRemoteRecord(token, channelId, eventId)
.observeOn(scheduler)
.subscribe(new SuccessCallbackAction<RemoteRecordResponse>(callback),
new ErrorCallbackAction(callback));
}
#Override
public void activateRemoteRecord(String token, String cardNumber, final ServiceCallback<RemoteRecordActivateResponse> callback) {
epgServicesApiManager.activateRemoteRecord(token, cardNumber)
.observeOn(scheduler)
.subscribe(new SuccessCallbackAction<RemoteRecordActivateResponse>(callback),
new ErrorCallbackAction(callback));
}
Locally, we've reduced the amount of code, and made the intent a little more clear. Globally, we've increased the complexity with the addition of 4 new classes. Whether this is worth it depends on the context your code lives in, and is your call.
Introduce a dummy callback that does nothing, then do safeCallback().onSuccess() or safeCallback().onError()
Also, you can do this:
class SuccessCallback<T> extends Action1<T>() {
#Override
public void call(T value) {
safeCallback().onSuccess(value);
}
}
class ErrorCallback extends Action1<Throwable>() {
#Override
public void call(T value) {
safeCallback().onError();
}
}
then...
subscribe(new SuccessCallback<RemoteRecordActivateResponse>(), new ErrorCallback());
Does this work?

Java Event Listener to detect a variable change

I cannot seem to find an answer anywhere to my question. Is there any event listener which can detect the changing of a boolean or other variable and then act on it. Or is it possible to create a custom event listener to detect this?
Please I cannot seem to find a solution to this anywhere and I found this website explaining how to create custom events
Use PropertyChangeSupport. You wont have to implement as much and it is thread safe.
public class MyClassWithText {
protected PropertyChangeSupport propertyChangeSupport;
private String text;
public MyClassWithText () {
propertyChangeSupport = new PropertyChangeSupport(this);
}
public void setText(String text) {
String oldText = this.text;
this.text = text;
propertyChangeSupport.firePropertyChange("MyTextProperty",oldText, text);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
}
public class MyTextListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals("MyTextProperty")) {
System.out.println(event.getNewValue().toString());
}
}
}
public class MyTextTest {
public static void main(String[] args) {
MyClassWithText interestingText = new MyClassWithText();
MyTextListener listener = new MyTextListener();
interestingText.addPropertyChangeListener(listener);
interestingText.setText("FRIST!");
interestingText.setText("it's more like when you take a car, and you...");
}
}
Just like you need to create an event listener, you will also need to create the event firer -- since there is nothing automatic that will do this for you. I've provided sample code that shows you how to implement such a firer.
This test implementation isn't perfect. It only includes a way to add listeners. You may wish to include a way to remove listeners who are no longer interested in receiving events. Also note that this class is not thread-safe.
import java.util.List;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
import java.awt.EventQueue;
/**
* This class uses the EventQueue to process its events, but you should only
* really do this if the changes you make have an impact on part of a GUI
* eg. adding a button to a JFrame.
*
* Otherwise, you should create your own event dispatch thread that can handle
* change events
*/
public class BooleanChangeTest implements BooleanChangeDispatcher {
public static void main(String[] args) {
BooleanChangeListener listener = new BooleanChangeListener() {
#Override
public void stateChanged(BooleanChangeEvent event) {
System.out.println("Detected change to: "
+ event.getDispatcher().getFlag()
+ " -- event: " + event);
}
};
BooleanChangeTest test = new BooleanChangeTest(false);
test.addBooleanChangeListener(listener);
test.setFlag(false); // no change, no event dispatch
test.setFlag(true); // changed to true -- event dispatched
}
private boolean flag;
private List<BooleanChangeListener> listeners;
public BooleanChangeTest(boolean initialFlagState) {
flag = initialFlagState;
listeners = new ArrayList<BooleanChangeListener>();
}
#Override
public void addBooleanChangeListener(BooleanChangeListener listener) {
listeners.add(listener);
}
#Override
public void setFlag(boolean flag) {
if (this.flag != flag) {
this.flag = flag;
dispatchEvent();
}
}
#Override
public boolean getFlag() {
return flag;
}
private void dispatchEvent() {
final BooleanChangeEvent event = new BooleanChangeEvent(this);
for (BooleanChangeListener l : listeners) {
dispatchRunnableOnEventQueue(l, event);
}
}
private void dispatchRunnableOnEventQueue(
final BooleanChangeListener listener,
final BooleanChangeEvent event) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
listener.stateChanged(event);
}
});
}
}
interface BooleanChangeDispatcher {
public void addBooleanChangeListener(BooleanChangeListener listener);
public boolean getFlag();
public void setFlag(boolean flag);
}
/**
* Listener interface for classes interested in knowing about a boolean
* flag change.
*/
interface BooleanChangeListener extends EventListener {
public void stateChanged(BooleanChangeEvent event);
}
/**
* This class lets the listener know when the change occured and what
* object was changed.
*/
class BooleanChangeEvent extends EventObject {
private final BooleanChangeDispatcher dispatcher;
public BooleanChangeEvent(BooleanChangeDispatcher dispatcher) {
super(dispatcher);
this.dispatcher = dispatcher;
}
// type safe way to get source (as opposed to getSource of EventObject
public BooleanChangeDispatcher getDispatcher() {
return dispatcher;
}
}
you can also try to implement an Observer.
First create the observable object:
import java.util.Observable;
public class StringObservable extends Observable {
private String name;
public StringObservable(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
setChanged();
notifyObservers(name);
}
}
Then the observer:
import java.util.Observable;
import java.util.Observer;
public class NameObserver implements Observer {
private String name;
public NameObserver() {
name = null;
}
public void update(Observable obj, Object arg) {
if (arg instanceof String) {
name = (String) arg;
System.out.println("NameObserver: Name changed to " + name);
} else {
System.out.println("NameObserver: Some other change to subject!");
}
}
}
And in your main (or wherever else):
public class TestObservers {
public static void main(String args[]) {
// Create the Subject and Observers.
StringObservable s = new StringObservable("Test");
NameObserver nameObs = new NameObserver();
// Add the Observer
s.addObserver(nameObs);
// Make changes to the Subject.
s.setName("Test1");
s.setName("Test2");
}
}
Mostly found here
Very late to answer, but this is a problem that can be solved with Observer/Observable. Example
The boolean you are setting should be allowed to do only through a setter method like:
public void setFlag(boolean flag){
//Method code goes here
}
Now in now set method, you can decide based on what value comes in, what event needs to be fired. I am explaining in simple terms without introducing complex terms so you can understand better, so code snippet would look like:
public void setFlag(boolean flag){
//if flag is TRUE do something
//If flag is FALSE then do something
//And finally do what you needed to do with flag
}
Ask questions if you need more info
you create a listener when you want to listen for I/O changes. mostly on graphics.
the answer to your question is to keep state of the running program, then check if variables change from the state inside the infinite loop of your program.
You can use AOP for that, perhaps AspectJ? Check a few examples here (if you use Eclipse, then using AspectJ is really simple with their plugin).
For you, you would have a pointcut similar to the one used in the SampleAspect, but one that will only be used when someone makes a new SET to a boolean variable (this doesn't mean that the value has changed, just that someone loaded a value to the variable).

Detecting a change in an integer

Is there any way to detect change in an integer? Such as creating a listener to listen to the integer to detect and change in value it has. I know this is possible with booleans with a few tricks but I cannot seem to adapt this to an int value. Does anyone have any idea how this could be done? I need to know how to do this in the Java language. Below is code that I found online that allows for a boolean listener. How can I convert this to an integer listener?
import java.util.List;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.EventObject;
import java.awt.EventQueue;
//can u see this austin? can u see this i typed this at 9:33 my time
/**
* This class uses the EventQueue to process its events, but you should only
* really do this if the changes you make have an impact on part of a GUI
* eg. adding a button to a JFrame.
*
* Otherwise, you should create your own event dispatch thread that can handle
* change events
*/
public class test1 implements BooleanChangeDispatcher {
public static void main(String[] args) {
BooleanChangeListener listener = new BooleanChangeListener() { // add this to the class
#Override
public void stateChanged(BooleanChangeEvent event) {
System.out.println("Detected change to: "
+ event.getDispatcher().getFlag()
+ " -- event: " + event);
}
};
test1 test = new test1(false);
test.addBooleanChangeListener(listener);
// test.setFlag(false); // no change, no event dispatch
// test.setFlag(true); // changed to true -- event dispatched
}
private boolean flag;
private List<BooleanChangeListener> listeners;
public test1(boolean initialFlagState) {
flag = initialFlagState;
listeners = new ArrayList<BooleanChangeListener>();
}
#Override
public void addBooleanChangeListener(BooleanChangeListener listener) {
listeners.add(listener);
}
#Override
public void setFlag(boolean flag) {
if (this.flag != flag) {
this.flag = flag;
dispatchEvent();
}
}
#Override
public boolean getFlag() {
return flag;
}
private void dispatchEvent() {
final BooleanChangeEvent event = new BooleanChangeEvent(this);
for (BooleanChangeListener l : listeners) {
dispatchRunnableOnEventQueue(l, event);
}
}
private void dispatchRunnableOnEventQueue(
final BooleanChangeListener listener,
final BooleanChangeEvent event) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
listener.stateChanged(event);
}
});
}
}
interface BooleanChangeDispatcher {
public void addBooleanChangeListener(BooleanChangeListener listener);
public boolean getFlag();
public void setFlag(boolean flag);
}
/**
* Listener interface for classes interested in knowing about a boolean
* flag change.
*/
interface BooleanChangeListener extends EventListener {
public void stateChanged(BooleanChangeEvent event);
}
/**
* This class lets the listener know when the change occured and what
* object was changed.
*/
class BooleanChangeEvent extends EventObject {
private final BooleanChangeDispatcher dispatcher;
public BooleanChangeEvent(BooleanChangeDispatcher dispatcher) {
super(dispatcher);
this.dispatcher = dispatcher;
}
// type safe way to get source (as opposed to getSource of EventObject
public BooleanChangeDispatcher getDispatcher() {
return dispatcher;
}
}
I would create a class capable of registering listeners. Below is a mocked up example. It might even compile as is (assuming you write the corresponding VocalIntegerListener interface exists and is implemented somehow... it's pretty simple).
class VocalInteger {
private int value;
private final Object lock = new Object();
Set<VocalIntegerListener> listeners; // assume interface exists - it's easy
public VocalInteger() {
this(0);
}
public VocalInteger(int value) {
this.value = value;
listeners = new HashSet<VocalIntegerListener>();
}
public int getValue() {
return value;
}
public void setValue(int value) {
synchronized(lock) {
int oldValue = this.value;
this.value = value;
for(VocalIntegerListener listener : listeners) {
listener.fireChangedEvent(oldvalue, value); // assume exists
}
}
}
public void registerListener(VocalIntegerListener listener) {
synchronized(lock) {
listeners.add(listener);
}
}
}
Have a look at "Java Beans" and "bound properties" for the standard approach how to listen for property changed events:
http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html
http://docs.oracle.com/javase/tutorial/javabeans/

Equivalent of C# ObservableCollection in Java

I was wondering if there is a data structure that acts like an OberservableCollection almost like in C# that is able to take a certain type.
ex:
In C# i am able to say..
ObservableCollection<Beer> Beer = new ObservableCollection<Beer>();
Beer.add("Bud"); <br>
Beer.add("Coors");
Assuming that the class Beer is made and we can change the alcohol content so that
Beer[1].content = 5;
I was wondering if anyone knows if there is such a data structure/s that work as well with Java.
I am a C# programmer, not much of a Java programmer so just wondering. Also, it has to be able to take in a custom type, not generic.
org.apache.commons.events.observable
Class ObservableCollection
Observable data structures (ObservableList, ObservableMap, etc) are included in Oracle Java 7u6+ as part of the JavaFX project. A corresponding library for OpenJDK is provided by the OpenJFX project.
Here is a tutorial on using JavaFX collections.
And some sample code for using a JavaFX observable list from the linked tutorial:
import java.util.List;
import java.util.ArrayList;
import javafx.collections.*;
public class CollectionsDemo {
public static void main(String[] args) {
// Use Java Collections to create the List.
List<String> list = new ArrayList<String>();
// Now add observability by wrapping it with ObservableList.
ObservableList<String> observableList = FXCollections.observableList(list);
observableList.addListener(new ListChangeListener() {
#Override public void onChanged(ListChangeListener.Change change) {
System.out.println("Detected a change! ");
}
});
// Changes to the observableList WILL be reported.
// This line will print out "Detected a change!"
observableList.add("item one");
// Changes to the underlying list will NOT be reported
// Nothing will be printed as a result of the next line.
list.add("item two");
System.out.println("Size: "+observableList.size());
}
}
If you want to Observe your lists, i.e. be notified when list changes, you can use Glazed Lists.
If you just want to modify objects stored in your lists, you can get your objects by using List.get(int index), or by iterating the list.
If you want to automatically create Beer objects when storing Strings into the list, you'll probably need to write your own simple list wrapper.
JavaFX now has ObservableList that match your needs, in the case that you don't want to depend on JavaFX - here is a class that I wrote a while ago that can be used instead.
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
*
* #author bennyl
*/
public class ObservableList<T> implements List<T> {
private List<T> wrapped;
private LinkedList<Listener<T>> listeners = new LinkedList<>();
public ObservableList(List wrapped) {
this.wrapped = wrapped;
}
public void addListener(Listener l) {
listeners.add(l);
}
public void removeListener(Listener l) {
listeners.remove(l);
}
#Override
public int size() {
return wrapped.size();
}
#Override
public boolean isEmpty() {
return wrapped.isEmpty();
}
#Override
public boolean contains(Object o) {
return wrapped.contains(o);
}
#Override
public Iterator<T> iterator() {
final Iterator<T> iterator = wrapped.iterator();
return new Iterator<T>() {
T current = null;
#Override
public boolean hasNext() {
return iterator.hasNext();
}
#Override
public T next() {
return current = iterator.next();
}
#Override
public void remove() {
iterator.remove();
fireRemoved(current);
}
};
}
private void fireRemoved(T... items) {
fireRemoved(Arrays.asList(items));
}
#Override
public Object[] toArray() {
return wrapped.toArray();
}
#Override
public <T> T[] toArray(T[] a) {
return wrapped.toArray(a);
}
#Override
public boolean add(T e) {
if (wrapped.add(e)) {
fireAdded(e);
return true;
} else {
return false;
}
}
#Override
public boolean remove(Object o) {
if (wrapped.remove(o)) {
fireRemoved((T) o);
return true;
}
return false;
}
#Override
public boolean containsAll(Collection<?> c) {
return wrapped.containsAll(c);
}
#Override
public boolean addAll(Collection<? extends T> c) {
if (wrapped.addAll(c)) {
fireAdded(c);
return true;
}
return false;
}
#Override
public boolean addAll(int index, Collection<? extends T> c) {
if (wrapped.addAll(index, c)) {
fireAdded(c);
}
return false;
}
#Override
public boolean removeAll(Collection<?> c) {
if (wrapped.removeAll(c)) {
fireRemoved((Collection<? extends T>) c);
return true;
}
return false;
}
#Override
public boolean retainAll(Collection<?> c) {
if (wrapped.retainAll(c)) {
fireStracturalChange();
}
return false;
}
#Override
public void clear() {
wrapped.clear();
fireStracturalChange();
}
#Override
public boolean equals(Object o) {
return wrapped.equals(o);
}
#Override
public int hashCode() {
return wrapped.hashCode();
}
#Override
public T get(int index) {
return wrapped.get(index);
}
#Override
public T set(int index, T element) {
T old = wrapped.set(index, element);
fireRemoved(old);
fireAdded(element);
return old;
}
#Override
public void add(int index, T element) {
wrapped.add(index, element);
fireAdded(element);
}
#Override
public T remove(int index) {
T old = wrapped.remove(index);
fireRemoved(old);
return old;
}
#Override
public int indexOf(Object o) {
return wrapped.indexOf(o);
}
#Override
public int lastIndexOf(Object o) {
return wrapped.lastIndexOf(o);
}
#Override
public ListIterator<T> listIterator() {
return wrapped.listIterator();
}
#Override
public ListIterator<T> listIterator(int index) {
return wrapped.listIterator(index);
}
#Override
public List<T> subList(int fromIndex, int toIndex) {
return wrapped.subList(fromIndex, toIndex);
}
private void fireRemoved(Collection<? extends T> asList) {
for (Listener<T> l : listeners) {
l.onItemsRemoved(this, asList);
}
}
private void fireAdded(T... e) {
fireAdded(Arrays.asList(e));
}
private void fireAdded(Collection<? extends T> asList) {
for (Listener<T> l : listeners) {
l.onItemsAdded(this, asList);
}
}
private void fireStracturalChange() {
for (Listener<T> l : listeners) {
l.onStracturalChange(this);
}
}
public static interface Listener<T> {
void onItemsAdded(ObservableList<T> source, Collection<? extends T> items);
void onItemsRemoved(ObservableList<T> source, Collection<? extends T> items);
void onStracturalChange(ObservableList<T> source);
}
}
There isn't at least in Java Collections api
http://download-llnw.oracle.com/javase/1.5.0/docs/guide/collections/designfaq.html#27
You can create an wrapper or proxy
You can consider using the java.util.Observable class, here is an example :
public class Try extends Observable{
private static List<String> list = new ArrayList<String>();
private static Try observableObj = new Try();
public static List<String> getList(){
observableObj.setChanged();
observableObj.notifyObservers();
return list;
}
public static void main(String[] args) throws RemoteException {
Try2 observer1 = new Try2();
Try2 observer2 = new Try2();
observableObj.addObserver(observer1);
observableObj.addObserver(observer2);
System.out.println(getList().isEmpty());
}
}
class Try2 implements Observer{
#Override
public void update(Observable arg0, Object arg1) {
System.out.println(this.toString()+" has been notified");
}
}
In this way every time the ArrayList gets accessed the two observers get notified.
Sure, you can do this. If you had a class called Soda, you could do:
List<Soda> sodas = new ArrayList<Soda>();
sodas.add(new Soda("Coke"));
sodas.add(new Soda("Sprite"));
Then you could do
sodas.get(1).setSugar(255);

Categories