Overriding constructors in Java - java

For school I need to learn Java and since I'm used to C++ (like Cocoa/Objective-C) based languages, I get really frustrated on Java.
I've made a super-class (that can also be used as a base-class):
public class CellView {
public CellViewHelper helper; // CellViewHelper is just an example
public CellView() {
this.helper = new CellViewHelper();
this.helper.someVariable = <anything>;
System.out.println("CellView_constructor");
}
public void draw() {
System.out.println("CellView_draw");
}
public void needsRedraw() {
this.draw();
}
}
public class ImageCellView extends CellView {
public Image someImage;
public ImageCellView() {
super();
this.someImage = new Image();
System.out.println("ImageCellView_constructor");
}
public void setSomeParam() {
this.needsRedraw(); // cannot be replaced by this.draw(); since it's some more complicated.
}
#Override public void draw() {
super.draw();
System.out.println("ImageCellView_draw");
}
}
Now, when I call it like this:
ImageCellView imageCellView = new ImageCellView();
imageCellView.setSomeParam();
I get this:
CellView_constructor
ImageCellView_constructor
CellView_draw
However, I want it to be:
CellView_constructor
ImageCellView_constructor
CellView_draw
ImageCellView_draw
How can I do this?
Thanks in advance,
Tim
EDIT:
I also implemented this method to CellView:
public void needsRedraw() {
this.draw();
}
And this to ImageCellView:
public void setSomeParam() {
this.needsRedraw(); // cannot be replaced by this.draw(); since it's some more complicated.
}
And I've been calling this:
ImageCellView imageCellView = new ImageCellView();
imageCellView.setSomeParam();
Does this causes the problem (when I call a function from the super it calls to the super only)? How can I solve this... (without having to redefine/override the needsRedraw()-method in every subclass?)

You should get proper output.
I tried you example just commented unrelated things:
import java.awt.Image;
public class CellView {
//public CellViewHelper helper; // CellViewHelper is just an example
public CellView() {
//this.helper = new CellViewHelper();
//this.helper.someVariable = <anything>;
System.out.println("CellView_constructor");
}
public void draw() {
System.out.println("CellView_draw");
}
public static void main(String[] args) {
ImageCellView imageCellView = new ImageCellView();
imageCellView.draw();
}
}
class ImageCellView extends CellView {
public Image someImage;
public ImageCellView() {
super();
//this.someImage = new Image();
System.out.println("ImageCellView_constructor");
}
#Override public void draw() {
super.draw();
System.out.println("ImageCellView_draw");
}
}
and I get following output:
CellView_constructor
ImageCellView_constructor
CellView_draw
ImageCellView_draw
This is exactly what you want, and this is what your code print's.

The short answer is "you can't."
Objects are constructed from the bottom up, calling base class initializers before subclass initializers and base class consrtuctors before subclass constructors.
EDIT:
The code you have looks good, based on your edit. I would go through the mundane tasks like ensuring that you have compiled your code after you've added you System.out.println calls to your subclass

Related

How do I check if an instance of a class has access to a method in another class?

I'm working on a small project where I want to have a list of a class called "DevelopmentEmployee", but only one of them is allowed to manipulate certain methods in another class "Project". The way I have implemented it, the class Project has a field called projectLeader, which is of the type DevelopmentEmployee. When a DevelopmentEmployee attempts to access methods in the class Project, I want to check if the DevelopmentEmployee is equal to the specific instance of Project's projectLeader.
Something like
public class Project {
private DevelopmentEmployee projectLeader;
private List < Activity > activities = new ArrayList < Activity > ();
public Project(DevelopmentEmployee pL) {
this.projectLeader = pL;
}
public void addActivity(String activityName) {
if (projectLeader.equals(DevelopmentEmployee * ) {
activities.add(activity);
}
}
}
But I can't figure out a way to make the access requirement work. How can the instance of the class Project know who is trying to access it?
You should also pass the DevelopementEmployee in addActivity for checking it against the projectLeader.
public void addActivity(String activityName,DevelopmentEmployee employee) {
if (projectLeader.equals(employee) {
activities.add(activity);
}
}
Then you need to override equals method in DevelopmentEmployee class, for proper checking of equality, like the one as shown below :
public boolean equals(DevelopementEmployee e){
if(e!=null && this.employeeId==e.employeeId)
return true;
else
return false;
}
Several possibilities come to mind:
Provide the instance of the one accassing the project method to the method:
public void addActivity(String activityName, DevelpmentEmployee user) {
if (projectLeader.equals(user)) {`
Create some class that holds information about active user and use that inside the methods:
public class Project {
private UserRegistry userRegistry;
private List<Activity> activities = new ArrayList<Activity>();
public Project(UserRegistry userRegistry) {
this.userRegistry = userRegistry;
}
public void addActivity(String activityName) {
if (userRegistry.isActiveUserProjectLeader()) {
activities.add(activity);
}
}
}
public class UserRegistry {
private DevelpmentEmployee projectLeader;
private DevelpmentEmployee activeUser;
private List<DevelpmentEmployee> user;
public void addUser(DevelpmentEmployee user) { ... }
public void makeProjectLeader(DevelpmentEmployee newLeader) { ... }
public void makeActiveUser(DevelpmentEmployee newActiveUser) { ... }
public boolean isActiveUserProjectLeader() { ... }
}`

Type symbol not found in inner class

[EDIT: I've rewritten the code to further simplify it and focus on the issue at hand]
I'm working on this particular piece of code:
class SimpleFactory {
public SimpleFactory build() {return null}
}
class SimpleFactoryBuilder {
public Object build(final Class builderClazz) {
return new SimpleFactory() {
#Override
public SimpleFactory build() {
return new builderClazz.newInstance();
}
};
}
}
However, the builder in the return statement triggers the error "Cannot find symbol newInstance". It's as if builderClazz wasn't recognized as a class object.
How can I make it work?
EDIT: SOLUTION (thanks to dcharms!)
The code above is a partial simplification of the code I was dealing with. The code below is still simplified but includes all the components involved and includes the solution provided by dcharms.
package com.example.tests;
interface IProduct {};
interface ISimpleFactory {
public IProduct makeProduct();
}
class ProductImpl implements IProduct {
}
class SimpleFactoryBuilder {
public ISimpleFactory buildFactory(final Class productMakerClazz) {
return new ISimpleFactory() {
#Override
public IProduct makeProduct() {
try {
// the following line works: thanks dcharms!
return (IProduct) productMakerClazz.getConstructors()[0].newInstance();
// the following line -does not- work.
// return new productMakerClazz.newInstance();
}
catch (Exception e) {
// simplified error handling: getConstructors() and newInstance() can throw 5 types of exceptions!
return null;
}
}
};
}
}
public class Main {
public static void main(String[] args) {
SimpleFactoryBuilder sfb = new SimpleFactoryBuilder();
ISimpleFactory sf = sfb.buildFactory(ProductImpl.class);
IProduct product = sf.makeProduct();
}
}
You cannot instantiate a new object this way. builder is a Class object. Try instead the following:
return builder.getConstructors()[0].newInstance(anInput);
Note: this assumes you are using the first constructor. You may be able to use getConstructor() but I'm not sure how it would behave with the generic type.

Is it possible to write your own objects that give out ActionEvents?

I've looked at the java tutorials online and they all seem concerned with catching ActionEvents given out by other components that are already written. Is it possible to write your own objects that have there own set of criteria that trigger actionEvents that can then be caught by other classes that have registered as listeners?
So for example: If I wanted an object that was counting sheep to send out an actionEvent when 100 sheep had been counted to all the sleeper objects that had registered as listeners.
Is there a way to do this are there any tutorials online?
Any help is greatly appreciated.
Yes, it's pretty straightforward, once someone shows you how to create your own listeners.
First, you create your own EventObject. Here's an example from one of my projects.
import gov.bop.rabid.datahandler.bean.InmateDataBean;
import java.util.EventObject;
public class InmatePhotoEventObject extends EventObject {
private static final long serialVersionUID = 1L;
protected InmateDataBean inmate;
public InmatePhotoEventObject(Object source) {
super(source);
}
public InmateDataBean getInmate() {
return inmate;
}
public void setInmate(InmateDataBean inmate) {
this.inmate = inmate;
}
}
There's nothing special about this class, other than it extends EventObject. Your constructor is defined by EventObject, but you can create any methods you want.
Second, you define an EventListener interface.
public interface EventListener {
public void handleEvent(InmatePhotoEventObject eo);
}
You would use the EventObject you created. You can use any method name or names that you want. This is the interface for the code that will be written as a response to the listener.
Third, you write a ListenerHandler. Here's mine from the same project.
import gov.bop.rabid.datahandler.bean.InmateDataBean;
import gov.bop.rabid.datahandler.main.EventListener;
import gov.bop.rabid.datahandler.main.InmatePhotoEventListener;
import gov.bop.rabid.datahandler.main.InmatePhotoEventObject;
import java.util.ArrayList;
import java.util.List;
public class InmatePhotoListenerHandler {
protected List<EventListener> listeners;
public InmatePhotoListenerHandler() {
listeners = new ArrayList<EventListener>();
}
public void addListener(EventListener listener) {
listeners.add(listener);
}
public void removeListener(EventListener listener) {
for (int i = listeners.size() - 1; i >= 0; i--) {
EventListener instance = listeners.get(i);
if (instance.equals(listener)) {
listeners.remove(i);
}
}
}
public void fireEvent(final InmatePhotoEventObject eo,
final InmateDataBean inmate) {
for (int i = 0; i < listeners.size(); i++) {
final EventListener instance = listeners.get(i);
Runnable runnable = new Runnable() {
public void run() {
eo.setInmate(inmate);
instance.handleEvent(eo);
}
};
new Thread(runnable).start();
}
}
public static void main(String[] args) {
System.out.println("This line goes in your DataHandlerMain class "
+ "constructor.");
InmatePhotoListenerHandler handler = new InmatePhotoListenerHandler();
System.out.println("I need you to put the commented method in "
+ "DataHandlerMain so I can use the handler instance.");
// public InmatePhotoListenerHandler getInmatePhotoListenerHandler() {
// return handler;
// }
System.out.println("This line goes in the GUI code.");
handler.addListener(new InmatePhotoEventListener());
System.out.println("Later, when you've received the response from "
+ "the web service...");
InmateDataBean inmate = new InmateDataBean();
inmate.setIntKey(23);
handler.fireEvent(new InmatePhotoEventObject(handler), inmate);
}
}
The main method in this class shows you how you use a ListenerHandler. The rest of the methods in the class are standard. You would use your own EventObject and EventListener.
Yes.
I suggest you look at the java API documentation for ActionEvent and EventListenerList.
I also suggest that you read about the Listener (also called Observer) pattern.

Implementation of aggregator pattern in Java

[edit] Hmm, clearly I'm not asking this properly. Could you tell me why this is a bad question?
To put this differently, I want to find a why to implement what is define in this article as "Pure object aggregation" instead of "Object organized as a blob".
I'm doing my first attempt at implementing the aggregation pattern in Java.
At first glance Interfaces seems to be the answer, I ran into confusion when I needed default values for attributes.
Since constants are static, if I define anything in the interface it will be shared with every class that implements it. What I was going for was that I only need to implement this in cases when I wanted a value different from default.
Here an abstract class seems a better fit but I fall back to a multiple inheritance problem.
Here is the (impossible) skeleton I can up with:
public interface MenuItemPopup {
// Defaults
int windowHeight = 200;
int windowWidth = 350;
public void open();
public void setWindowHeight(int newHeight){
windowHeight = newHeight;
}
public void setWindowWidth(int newWidth){
windowWidth = newWidth;
}
}
public interface WindowButton {
// Defaults
Point size = new Point (5, 120);
public void initialize();
public void setSize(Point newSize){
size = newSize;
}
}
public class SomeFuncGUI extends MandatoryParentClass implements WindowButton, MenuItemPopup{
public void open(){
// do stuff
}
public void initialize(){
// do more stuff
}
}
public class OtherFuncGUI extends MandatoryParentClass implements MenuItemPopup{
public OtherFuncGUI(Point customPosition){
setSize(new Point(45, 92));
}
public void open(){
// do stuff
}
}
public class MainClass{
ArrayList <MandatoryParentClass> list = new ArrayList <MandatoryParentClass>();
list.add(new SomeFuncGUI());
list.add(new OtherFuncGUI());
for( MandatoryParentClass button : list){
// process buttons
if(button instanceof WindowButton){
button.open();
}
// process popups
if(button instanceof MenuItemPopup){
button.initialize();
}
}
}
I realise this doesn't compile.
How would I change this to implement aggregation pattern for MenuItemPopup and WindowButton?

How to navigate in a circle

the title might be not very descriptive but i couldn't think of a better one.
The problem is as follows:
I have one screen (ScreenOne) with a link to another screen (ScreenTwo).
On the ScreenTwo is a link back to ScreenOne.
I implemented this via custom RichTextFields and a custom ChangeListener.
Now the problem is that i keep getting a StackOverflowError!
Is there any way to navigate back and forth in that way?
regards matt
public class MyApp extends UiApplication
{
public static void main(String[] args)
{
MyApp theApp = new MyApp();
theApp.enterEventDispatcher();
}
public MyApp()
{
ScreenOne so = ScreenProvider.getInstance().getScreenOne();
so.initialize();
ScreenProvider.getInstance().getScreenTwo().initialize();
pushScreen(so);
}
}
public class ScreenOne extends MainScreen {
MyTextField link;
public ScreenOne() {
link = new MyTextField("FirstScreen");
add(link);
}
public void initialize(){
link.setChangeListener((FieldChangeListener) new MyFieldChangeListener(ScreenProvider.getInstance().getScreenTwo()));
}
}
public class ScreenTwo extends MainScreen {
MyTextField link;
public ScreenTwo() {
link = new MyTextField("SecondScreen");
add(link);
}
public void initialize(){
link.setChangeListener((FieldChangeListener) new MyFieldChangeListener(ScreenProvider.getInstance().getScreenOne()));
}
}
public class MyFieldChangeListener implements FieldChangeListener {
private Screen nextScreen;
public MyFieldChangeListener(Screen nextScreen) {
this.nextScreen = nextScreen;
}
public void fieldChanged(Field field, int context) {
UiApplication.getUiApplication().pushScreen(nextScreen);
}
}
public class MyTextField extends RichTextField {
public MyTextField() {
super();
}
public MyTextField(String text) {
super(text);
}
protected boolean touchEvent(TouchEvent message) {
if (TouchEvent.CLICK == message.getEvent()) {
FieldChangeListener listener = getChangeListener();
if (null != listener)
listener.fieldChanged(this, 1);
}
return super.touchEvent(message);
}
}
public class ScreenProvider {
private static ScreenProvider instance = null;
private ScreenProvider(){}
public static ScreenProvider getInstance() {
if (instance == null) {
instance = new ScreenProvider();
}
return instance;
}
private ScreenOne screenOne = new ScreenOne();
private ScreenTwo screenTwo = new ScreenTwo();
public ScreenOne getScreenOne() {
return screenOne;
}
public ScreenTwo getScreenTwo() {
return screenTwo;
}
}
The constructor of ScreenOne creates a ScreenTwo instance, and the constructor of ScreenTwo creates a ScreenOne instance. You have an infinite loop here.
Regarding revision 5 of this question:
new ScreenProvider() -> new ScreenOne() -> ScreenProvider.getInstance() -> new ScreenProvider() -> ...
still infinite. Again, the problem is that you're trying to setup a cycle via object constructors. You need to create the objects first, then assign the next and previous.
Regarding revision 4 of this question:
getScreenOne() -> new ScreenOne() -> getScreenTwo() -> new ScreenTwo() -> getScreenOne() -> newScreenOne() -> ...
you still have an infinite loop, because the constructors are trying to store an instance of each other. You need to construct the objects first, then add the cyclic references.
In your ScreenProvider you don't need to make screen1/screen2 static -- they're members of the singleton instance.
Outside of that the other problem I see in this current version is that you're going to be pushing a screen onto the stack -- that's already on the stack. Try popping the prior screen first.
That overflow error is likely the result of an infinite loop caused by constantly jumping from ScreenOne and ScreenTwo. Could you describe what you actually would want to accomplish and/or show a snippet of code?

Categories

Resources