Getting a object reference in interface that was not passed - java

Currently, the below code gives compile erorr, because the listener don't know whats smsTask. I would need a instance of the smsTask in the listener. Is it possible to do this without passing it in the contruntor? It seems redunant if I do:
.createTask(smsTask,new TaskCompleteListener(smsTask){...}
current code:
public void doStuff(){
SmartPhoneTask smsTask=createSmsTask();
super.getSystem().createTask(smsTask,new TaskCompleteListener(){
#Override
public void onTaskComplete() {
releaseResources(smsTask);//error.
}});
}
private SmartPhoneTask createSmsTask() {
return new SmartPhoneTask();
}
createTask:
void createTask(SmartPhoneTask task, TaskCompleteListener listener);

You can declare the variable final :
final SmartPhoneTask smsTask=createSmsTask();

If TaskCompleteListener is under your control you can add a Task parameter to the onTaskComplete() method:
public void onTaskComplete(Task task) {
releaseResources(task);
}
Now the System has to pass the corresponding task to the listener when the onTaskComplete() method is called.
With this way you can also add the same TaskListener to multiple tasks.

Related

How to define more generic classes and interface when using realm?

I am trying to write a function that gets a list of games and use a callback to load the results. This is what i have right now:
public void getAllGames(OrderedRealmCollectionChangeListener<RealmResults<Game>> callback) {
realm.where(Game.class).findAllSortedAsync("startTime").addChangeListener(callback);
}
I want to make decouple Realm(OrderedRealmCollectionChangeListener and RealmResults) from this function, but I don't know how. I tried creating a listener that extends the OrderedRealmCollectionChangeListener but I am still stuck with the RealmResults, and when I try to extend that it said BaseRealm is private so it is impossible for me to create a constructor for that. How can I make it look like this:
public void getAllGames(SomeListener<SomeList<Game>> callback) {
realm.where(Game.class).findAllSortedAsync("startTime").addChangeListener(callback);
}
Derp, all I should have done is write the callback behaviour inside the getAllGames function:
public void getAllGames(SomeListener<List<Game>> callback) {
realm.where(Game.class).findAllSortedAsync("startTime").addChangeListener(new OrderedRealmCollectionChangeListener<RealmResults<Game>>() {
#Override
public void onChange(RealmResults<Game> collection, OrderedCollectionChangeSet changeSet) {
callback.callback(collection);
}
});
}

How to Access a Property of the Outer Class Instance from an Inner Class

In a method of a custom class View:
public class View {
private Timer timer;
...
private double[][] allLevels;
...
I have a method with an abstract call that needs to point to the variable allLevels. The variable is produced by another class GameLogic, but in the Main of the application. In the Main, the return argument from a public method is then passed to the View:
public class Game extends ApplicationAdapter {
View view;
GameLogic gameLogic;
#Override
public void create () {
System.out.println("Creating");
this.gameLogic = new GameLogic();
this.gameLogic.prepareStimulus();
}
#Override
public void render () {
Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
this.view = new View();
this.view.presentStimulus(this.gameLogic.allLevels);
}
}
Because of a very complex game/business logic I thought I would try to separate and encapsulate as much as possible in a MVC-ish pattern. The Main uses libgdx, which requires create and render to be separate.
My main problem is that I am unable to reach the variable in the class View from the abstract call to the class scope.
public void presentStimulus(double[][] allLevels){
...
timer = new Timer();
...
timer.scheduleTask(new Task(){
#Override
public void run(){
DO SOMETHING WITH that.allLevels[0][0]
}
}, .....);
I have looked at a similar issue, but I guess my question is more basic.
The IDE is unable to autocomplete the reference to the properties using the keyword "this". How can I make the Run() method access the property of the instance of the outer class?
The problem ( I rather doubt it) is here -
public void presentStimulus(double[][] allLevels){
...
timer = new Timer();
...
timer.scheduleTask(new Task(){
#Override
public void run(){
DO SOMETHING WITH that.allLevels[0][0]
}
}, .....);
You see, in this code time.scheduleTask, you are just only creating a new Task and not executing it. It is executed after a while with another thread I supposed, thus it is run in a different context, which does not have allLevels value at the time of execution. So there is no way you can access that allLevels in that run method unless you use closure. I am not sure whether java supports closure or not, but here is a similar answer that might help you - Closure in Java 7
You can use some other solutions, like save the hash and allLevels in a separate static dictionary that is accessible globally and then pick the value from there.

Generically changing variables with listeners

I have a set of instances of a class named Marker that has a Marker#setDelay(double) method. This method is called based on mouse drags (you can drag around the markers). Every marker has a corresponding double variable in a config class.
I want to synchronize the config class with the marker instances. So whenever the Marker#setDelay(double) method is called, the corresponding variable in the config class should change too. How can I do that?
I tried using Runnables that I can apply to the markers, so the runnable would be called from within the Marker#setDelay(double) method, but this Runnable does not have access to the delay value. Is there some sort of method pointer workarround?
My last resort would be a interface and anonymous instances for every marker. But that seems kind of ugly...
The general off-the-shelf pattern here is straightforward: Introduce an interface like MarkerListener. Then you can create a (possibly anonymous) MarkerListener implementation that updates your config, and add it to the respective `MarkerĀ“.
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
interface MarkerListener
{
void delayChanged(double oldDelay, double newDelay);
}
class Marker
{
private double delay;
private final List<MarkerListener> markerListeners =
new CopyOnWriteArrayList<MarkerListener>();
void addMarkerListener(MarkerListener markerListener)
{
markerListeners.add(markerListener);
}
void removeMarkerListener(MarkerListener markerListener)
{
markerListeners.add(markerListener);
}
void setDelay(double newDelay)
{
if (newDelay != this.delay)
{
double oldDelay = this.delay;
this.delay = newDelay;
fireDelayChanged(oldDelay, newDelay);
}
}
private void fireDelayChanged(double oldDelay, double newDelay)
{
for (MarkerListener markerListener : markerListeners)
{
markerListener.delayChanged(oldDelay, newDelay);
}
}
}
Of course, this involves some code bloat. It is basically a minimalistic implementation of something that could also be achieved when using the DoubleProperty from JavaFX that Joop Eggen referred to in his answer. So you might want to consider using the DoubleProperty. (One could also solve this with PropertyChangeListeners, but these are probably not so appropriate here)
Since you referred to "function pointers": You could also use DoubleConsumer instances instead of introducing an own interface. But it's impossible to tell from the question whether this is the best solution here.
JavaFX has ...Property classes, which you can bind to receive change notifications. That is a much underestimated/overseen UI functionality.
So use a DoubleProperty. (A warning: the javadoc does not easily suffice for usage.)
See for a usage here.
Have a DoubleProperty
addListener new ChangeListener with as ObservableValue the DoubleProperty
I didn't fully understand the problem.
Here is my solution anyway
Create a Listener
public interface MarkerChangeListener{
void markerChanged(double value);
}
Implement the Config Class with listener
public class Config implements MarkerChangeListener{
private double delay;
#override
public void markerChanged(double value){
this.delay = value;
}
....
}
Add a method to your Marker class to add listener and fire the listener when the value updated
public class Marker{
private MarkerChangeListener listener;
public void addListener(MarkerChangerListener listener){
this.listener = listener;
}
public void setDelay(double delay){
this.delay = delay;
listener.markerChanged(delay)
}
}
Add the listener to the Marker class from where you create markers.
marker.addListener(config);

Android: Cannot access public static function or public variables from another class

Here is the declaration in 'MainActivity.java'
private static String competition = null;
I've created a setter function which adds value to it.
public static void setCompetition(String competition1) {
competition = competition1;
}
I've created a getter function to get the value in another class from the same package:
public static String getCompetition() {
return competition;
}
However it returns null.
Here is how I tried to use it in a function
public void onReceive(Context context, Intent intent) {
with in the class AlarmNotify which extends BroadcastReceiver:
final String competition = MainActivity.getCompetition();
I think you are not invoking setCompetition anywhere. To validate that, try with this piece of code -
public static void setCompetition(String competition1) {
System.out.println("Set competition to "+competition1);
competition = competition1;
}
If you do not see any printed message, then setCompetition is not being invoked. Ensure that this is being invoked.
Here is the mistake I did:
I was calling a network based async task, which takes few seconds to retrieve the data. It works in the background.
I was calling another function which was trying to access these values. It was being fired instantaneously, even before the async task could run. That is why it was returning null.
Async task hadn't returned those values.
Ultimately I put the call to the other function in the postExecute method of the Async.
Hope that helps anyone who makes the same mistake as I did.

Testing Presenters in MVP GWT application

I have a simple application and want to make it testable. I m new in this area.
Here is a simple Presenter, taking in mind this code ,could you advice or give me some example how to test it.
public class SomePresenter extends Presenter<MainPanelPresenter.Display>
{
public interface Display extends WidgetDisplay
{
HasClickHandlers getAddButton();
HasClickHandlers getDeleteButton();
void setData(ArrayList<Person> data);
ArrayList<String> getSelectedRows();
Widget asWidget();
}
private final DispatchAsync dispatcher;
public static final Place PLACE = new Place("main");
#Inject
public SomePresenter(DispatchAsync dispatcher, EventBus eventBus, Display display)
{
super(display, eventBus);
this.dispatcher = dispatcher;
bind();
}
protected void onBind()
{
display.getAddButton().addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
eventBus.fireEvent(new AddButtonEvent());
}
});
display.getDeleteButton().addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
ArrayList<String> list = display.getSelectedRows();
deletePerson(list);
}
});
}
....
private void loadDbData()
{
..........
}
private void deletePerson(ArrayList<String> ids)
{
..........
}
}
Edit:
What does the Presenter is, load initial data from db, have 2 buttons add and delete.
When add is press then a new form is load and user is able to input data and save to the db,
delete button just delete person from db.
Thanks
The general idea of unit testing such a class would be, like for any other class :
create Mock version of the dependencies (Display, EventBus, etc...)
set expectations on what the depdencies should do when the Presenter works
exercice the Presenter and check the expectations
However there are a couple of issues with your version of the Presenter :
The loadDbData() method is not showed, but I assumed it means the Presenter also has access to some other component that does the fetching. Can this component be abtracted in a dependency, and mocked liked the rest ?
Then there is the testing of bind(). The only responsibility of your Presenter in this method is to set up callbacks on some buttons provided by the Display. What you want to test is both :
That the callbacks are set
That the set callbacks do the expected things
A few ideas to help with the later :
You can reduce the coupling between Presenter and Button. If possible, change the Display interface from :
Button getAddButton();
to
addAddButtonClickedHandler(ClickHandler);
This means your Presenter does not have to use a Display object that returns actual BUtton
You can reduce the callbacks content to calling a single method, that you can then test in isolation
protected void bind() {
display.addAddButtonClickHandler(new ClickHandler() {
public void onClick(ClickEvent) {
fireAdded();
}
});
}
// The fireAdded function can be tested independenty of the Display, potentially with
// a mock EventBus
protected void fireAdded() {
event.fireEvent(....)
}
If you really want to check that the callbacks are properly set, than you can use a 'Dummy' implementation of the Display class, that provides you a list of all the callbacks, and let you call them
private class DummyDisplay implements Display {
private List<ClickHandler> addButtonClickHandlers;
public void addAddButtonClickHandler(ClickHandler handler) {
addButtonClickHandlers.add(handler);
}
public void fireAddButtonClick() {
for (ClickHandler h in addButtonClickHandlers) {
h.onClick(new ClickEvent());
}
}
// ....
}
Then your test would :
create a presenter with such a dummy display
use bind to set the callbacks
use display.fireAddButtonClick() to simulate a user clicking
check that has the result of the click, the effects of fireAdded are seen
This type of class (that mostly glue other classes together) can tend to be hard to test ; at some point, it the other classes are thoroughly tested it can become slightly counter productive to concentrate on the gluers, rather than the glued.
Hoping this helps.

Categories