Can't Access Public Methods of View Object(Android) in Java - java

This seems like an elementary problem so I'm sure it's something small I've overlooked. Maybe I've just been looking at it too long.
I've been trying to create an onClick Listener in a view, and I have a public set method to set the listener. But when I try to call that method outside of the class I get an error saying it can't resolve the method.
I've tried creating other public methods or public member variables but I can't view any of them outside of the class for some reason.
Here is some relative snippets:
PaintView: (The class I can't get public members from)
public class PaintView extends View {
public interface OnPaintClickedListener
{
public void onPaintClicked(int color);
}
private OnPaintClickedListener _onPaintClickedListener;
public void setOnPaintClickedListener(OnPaintClickedListener listener)
{
_onPaintClickedListener = listener;
}
...
}
PaletteView: (The class that uses a PaintView)
public class PaletteView extends ViewGroup {
....
public void addColor(Context context, int color)
{
View newPaintView = new PaintView(context, color);
//setOnPaintClickedListener gives the message "Cannot resolve method setOn...blah blah'
newPaintView.setOnPaintClickedListener(new PaintView.OnPaintClickedListener()
{
#Override
public void onPaintClicked(int color)
{
}
});
this.addView(newPaintView);
}
}
It does ok with the interface code, but it just can find that setOnPaintClickedListener method.
Thanks in advance, I'm 97% sure I'm going to feel like an idiot as soon as somebody points out my mistake.

Change to:
PaintView newPaintView = new PaintView(context, color);
explanation...as the variable you were using was declared with type View, the compiler wasn't able to find the method that was defined in the subclass PaintView, so it complains.
Alternatively, you could leave the same declaration and when calling the specific method, you would have to do cast to the subclass like this:
((PaintView)newPaintView).setOnPaintClickedListener

Related

How to use overridden Methods in an Activity as own Methods

I created an App, where I get answers from my Server to my HelperClass. The HelperClass has several #override Methods. This I override this Methods in every activity different.
So now my Problem is, I get lots of Problems, casue of multi threading. For example with a simple Toast. I have to use runOnUiThread() every time. Or "Only the original thread that created a view hierarchy can touch its views." when a overridden Helperclass method should use a (for example) MainActivity-Method to set a new layout.
Is there any solution, how I can solve those problems?
Code example:
public abstract class HelperClass extends AppCompatActivity{
#Override
public void methodOne() { }
#Override
public void methodTwo() { }
}
Here are my Methods defined. An another Class gets the answer from the Server and call them. (everything works).
I override them in every Activity (here for example MainActivity)
public class MainActivity extends HelperClass {
#Override
protected void onCreate(Bundle savedInstanceState){
setContentView(R.layout.first_layout);
}
#Override
public void methodOne() {
Toast.makeText(this,"text",Toast.LENGTH_SHORT).show();
}
#Override
public void methodTwo() {
setContentView(R.layout.second_layout);
}
}
So I will get Error, when I use them without runUIThread(). I need a solution for everywhere, cause I think this is not clean. There should be a better way then using runUIthread() in every single method, when I want to use a View or something else (till now I only had this two Problems, there are still 20-30 Funktions to declare).

Why can I not call the interface method?

Disclaimer: I'm coming from Swift so my idea on how delegation works is biased.
I have an interface defined:
public interface IChatButtonResponse {
void chat(ListingEntry listingEntry, String initialUserText);
}
My class has a local reference to it that is saved when instantiated:
public class ListingAdapter extends BaseAdapter {
private IChatButtonResponse delegate;
public ListingAdapter(Context context, ArrayList<ListingEntry> listingEntries, IChatButtonResponse delegate) {
this.delegate = delegate;
When I try to call the delegate in response to a button tap, I get a compilation error:
chatButton.setOnClickListener(new View.OnClickListener() {
delegate.chat(listingEntry, null); // Cannot resolve symbol 'chat'
});
Why can it not be resolved? I tried to make the method declaration in the interface public but that didn't change anything. (I would have been surprised if it did)
EDIT:
My usage of the interface in the same package:
public class MainActivity extends AppCompatActivity implements IChatButtonResponse {
.
.
.
#Override
void chat(ListingEntry listingEntry, String initialUserText) {
}
I am getting a compilation error here: 'chat(ListingEntry, String)' in ...sample.app.MainActivity' clashes with 'chat(ListingEntry, String) in ...sample.app.IChatButtonResponse'; attempting to assign weaker access privileges ('package-private'); was 'public'
Tried making the implementation method public with no change.
For the original error in question, the clue was found on another error I hadn't noticed earlier on the chatButton.setOnClickListener.
The OnClickListener method onClick must be overridden like this:
chatButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String referenceID = listingEntry.referenceID;
delegate.chat(listingEntry,null);
}
});
This fixes the resolution error at the call site.

Is it possible to overwrite an object's tick method in it's constructor?

I'm making a game UI from scratch and rather than create a class for many similar objects, such as the FPS and score counters.
Is it possible for me to create a single class that allows me to overwrite their basic tick methods in a similar way to how I'm overwriting the onClick() methods on my buttons?
hudUIManager.addObject(new UIImageButton(handler, handler.getWidth()/2-128, handler.getHeight()/2-32, 64, 64, Assets.button_menu, new ClickListener(){
#Override
public void onClick() {
State.setState(handler.getGame().getMenuState());
}}));
Feel free to tell me I'm going about this completely the wrong way as long as you can point me in the right direction. Any and all help is appreciated!
A way to do that would be to create a class which takes an interface in its constructor. Then when you instantiate the class, you would pass in an implementation of the interface as an anonymous class as you do when you pass in the ClickListener in your example.
For instance, the interface may be something like
public interface Ticker() {
public void doTick();
}
Then the base class may be something like
public class TickObject() {
private Ticker ticker;
public TickObject(Ticker ticker) {
this.ticker = ticker;
}
public void doTick() {
ticker.doTick();
}
}
Then when you want to create an instance of TickerObject it would be as follows
TickObject tickerObject = new TickObject(new Ticker(){
#Overide
public void doTick() {
// implement
}
});

Observer pattern issues Java

I am trying to implement a simple observer pattern in java and I am running into an issue that I cannot seem to figure out. I have the following:
public interface Observable {
public void addView(Observer view);
public void removeView(Observer view);
public void notifyView();
public Object getUpdate(Observer view);
}
public class Data implements Observable {
//List to hold all of the views observing data changes.
private ArrayList<Observer> views = new ArrayList<Observer>();
private ArrayList<Integer> data = new ArrayList<Integer>();
...
#Override
public void notifyView() {
for (Observer view: views){
//issue here
view.update(data);
}
}
...
}
I am getting an error in my notifyView() method when I try to call the view.update() method. The error I get is:
The method update(Observable, Object) in the type Observer is not applicable for the arguments (ArrayList<Integer>)
I do not understand this because I have my Observer interface, and class set up as follows:
public interface Observer {
public void update(ArrayList<Integer> data);
}
public class View implements Observer{
#Override
public void update(ArrayList<Integer> data) {
// TODO Auto-generated method stub
}
}
I have tried reading other posts but nothing has helped me. Is there something I am overlooking that is causing this problem?
Your code is not using your Observer class, instead, is using the Java's Observer class
https://docs.oracle.com/javase/7/docs/api/java/util/Observer.html
You should rename your Observer interface name to another to see problem. For example MyObserver. You have conflict with JDK standard Observer interface ( please see your Data.java import section) and your Observer interface. Be more accurate with interface names.

Calling a non-static method from outside the class

I often have to deal with this kind an error when programming in Java on Android.
For example I have a class where I set a flag.
public class ViewActivity extends Activity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
...
}
In another class I want to reset the FLAG_KEEP_SCREEN_ON
class DrawOnTop extends View {
...
if (condition) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
but this doesn't work, since I get "The method getWindow is undefined for the type DrawOnTop".
So I try to define a clearFlags method in ViewActivity class
void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
and to call it from the DrawOnTop class:
if (condition) {
ViewActivity.clearFlags();
}
This doesn't work as well: I get "Cannot make a static reference to the non-static method clearFlags() from the type ViewActivity".
Well, let's make it static then.
static void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
and then I get "Cannot make a static reference to the non-static method getWindow from the type Activity"
How could I execute such a statement?
If your DrawOnTop class is nested within the ViewActivity you can create a local Context variable and use it to call the getWindow(). If that's not the case then create a receiver in your activity class then from DawOnTop send an intent with your trigger to do whatever the job is. Do not instantiate your activity class, bad idea!
You can send getWindow() as parameter into clearFlags method.
Call clearFlags(Window window) from your activity: WindowHelper.getInstance().clearFlags(getWindow());
Helper class:
public class WindowHelper {
public static final WindowHelper instance = new WindowHelper();
public static WindowHelper getInstance() {
return instance;
}
public void clearFlags(Window window) {
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
I tried to implement the solutions suggested by Aksaçlı and this turned out to be very simple:
In the ViewActivity class DrawonTop is called this way:
mDrawOnTop = new DrawOnTop(this);
The constructor of the second class contains this:
public DrawOnTop(Context context) {
super(context);
Therefore ViewActivity.clearFlags(); has simply to be rewritten as ((ViewActivity)getContext()).clearFlags();
Perhaps you should refer to an initialised object in your static method. So instead of:
void clearFlags() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
you should create a static instance variable of your window:
private static staticWindowInstance;
void clearFlags() {
getStaticWindowInstance().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
For more information, you should check out the Singleton design pattern.

Categories