Java Inheritance : 2nd instance calls 1st instance method - java

I have a very strange problem with a java class in my android application.
I have some sub classes which extend my abstract class GameDialog
GameDialog class
public abstract class GameDialog extends Sprite
{
private static boolean gd_visible = false;
protected GameDialog(GameScene scene, Camera camera, VertexBufferObjectManager pSpriteVertexBufferObject){
...
}
public boolean display(){
if(!GameDialog.gd_visible) {
...
}
}
protected boolean hide(){
if(GameDialog.gd_visible){
...
}
}
}
PauseDialog class
public class PauseDialog extends GameDialog {
public PauseDialog(GameScene scene, Camera camera, VertexBufferObjectManager pSpriteVertexBufferObject) {
super(scene, camera, pSpriteVertexBufferObject);
...
final ButtonSprite play_button = new ButtonSprite(...);
play_button.setOnClickListener(setPlayButtonListener());
}
private OnClickListener setPlayButtonListener() {
return new OnClickListener() {
#Override
public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {
hide();
}
};
}
}
Each time I want to display a dialog, I write this line :
new PauseDialog(GameScene.this, camera, vbom).display();
The first time, it works well : the dialog is displayed, user make a choice and it's hidden.
But the 2nd time, the dialog is not hidden (after user's choice).
I used the debugger to see what's going on, and the conclusion is :
In the 2nd instance, it calls the hide() method of the first instance !
If some one can explain me what it is doing that ... Thank you.

It is because gd_visible is static. Delete the static keyword and it should work. Static fields doesn't belong to the instances but they belong to the class.

Related

Refactoring a class implementing an interface by creating subclasses in GWT /java

I am implementing the frontend of an application in GWT (see attached picture) and I have view class which is getting bigger as more widgets are added to the frontend.
As stated in GWT tutorial, the view class must implement the Display interface of the presenter class. y problem is I have a lot a methods in that interface and as I implement them in the view class, it becomes too big. That's why I would like to refactor the code to reduce the size of the view class by implementing those methods in others
classes and reference them where needed in the view class;for instand by grouping them per group box (one class per group box).
Below is a sample code: Note that in the real application we have more widgets per group box.
The problem I am facing will be well explained as you read through the whole posting because I will be adding more details.
code to be refactored:
ContactPrewsenter.java
public class ContactPresenter {
public interface Display
{
void methodA();
void methodB();
void methodC();
void methodD();
void methodE();
void methodF();
.
.
.
void methodM();
}
public ContactPresenter()
{
//Some stuff here
}
......
......
#Override
public void bind(){
//Some stuff here
}
}
ContactView.java:
public class ContactView implements ContactPresenter.Display
{
private final Listbox listBoxA;
private final Listbox listBoxB;
private final Listbox listBoxC;
private final Listbox listBoxD;
private final Listbox listBoxE;
private final Listbox listBoxF;
private final Listbox listBoxG;
private final Listbox listBoxH;
private final Listbox listBoxI;
private final Listbox listBoxJ;
private final Listbox listBoxK;
private final Listbox listBoxL;
private final Listbox listBoxM;
public ContactView()
{
listBoxA = new ListBox();
listBoxB = new ListBox();
VerticalPanel vPanel1= new VerticalPanel();
vPanel1.add(listBoxA);
vPanel1.add(listBoxB);
GrooupBox groupBox1 = new GroupBox();
groupBox1.add(vPanel1);
listBoxC = new ListBox();
listBoxD = new ListBox();
VerticalPanel vPanel2 = new VerticalPanel();
vPanel2.add(listBoxC);
vPanel2.add(listBoxD);
GrooupBox groupBox2 = new GroupBox();
groupBox2.add(vPanel2);
listBoxE = new ListBox();
listBoxF = new ListBox();
VerticalPanel vPanel3 = new VerticalPanel();
vPanel3.add(listBoxE);
vPanel3.add(listBoxF);
GrooupBox groupBox3 = new GroupBox();
groupBox3.add(vPanel3);
listBoxE = new ListBox();
listBoxF = new ListBox();
VerticalPanel vPanel4 = new VerticalPanel();
vPanel4.add(ListBoxE);
vPanel4.add(ListBoxF);
....
GrooupBox groupBox3 = new GroupBox();
groupBox3.add(vPanel4);
listBoxG = new ListBox();
listBoxH = new ListBox();
....
VerticalPanel vPanel = new VerticalPanel();
vPanel.add(ListBoxG);
vPanel.add(ListBoxH);
....
GrooupBox groupBox4 = new GroupBox();
groupBox4.add(vPanel);
......
//create Horizontal/vertical panels, docklayout panel as well, to position the group boxes on the gui
....
}
#Override
void methodA(){
//uses listBoxA
}
#Override
void methodB(){
//used listBoxB
}
#Override
void methodC(){
//uses listBoxC
}
#Override
void methodD(){
//uses listBoxD
}
#Override
void methodE(){
//uses listBoxE
}
#Override
void methodF(){
//uses listBoxF
}
#Override
void methodG(){
//uses listBoxG
}
#Override
void methodH(){
//uses listBoxH
}
.
.
.
#Override
void methodM(){
//uses listBoxM
}
}
I have tried as follows:
ContactPreseter.java
public class ContactPresenter
{
public interface Display extends groupBox1View.Display, groupBox2View.Display, groupBox3View.Display, groupBox4View.Display
{
}
}
preseter classes of each group box
public class groupBox1Presenter
{
public interface Display
{
void methodA();
void methodB();
}
}
public class groupBox2Presenter
{
public interface Display
{
void methodC();
void methodD();
}
}
public class groupBox3Presenter
{
public interface Display
{
void methodE();
void methodF();
}
}
public class groupBox4Presenter
{
public interface Display
{
void methodG();
void methodH();
}
}
ContactView.java
public abstract class ContactView implements ContactPresenter.Display
{
// adds group boxes to horizontal/vertical panels, and docklayout panel
}
Below are the view classes for each group box:
But here I eclipse forces me to implement all the methods of the interface ContactPresenter.Display in each of these classes whereas , I wanted it to be the way you see implemented here.
I was wondering if there were a way to play with access modifiers in order to achieve that ? If not, please I would you to help with ideas how to do it ?
public groupBox1View extends ContactView implements groupBox1Presenter
{
public groupBox1View()
{
}
#Override
void methodA(){
//uses listBoxA
}
#Override
void methodB(){
//used listBoxB
}
}
public groupBox2View extends ContactView implements groupBox2Presenter
{
public groupBox2View()
{
}
#Override
void methodC(){
//uses listBoxC
}
#Override
void methodD(){
//used listBoxD
}
}
public groupBox3View extends ContactView implements groupBox3Presenter
{
public groupBox3View()
{
}
#Override
void methodE(){
//uses listBoxE
}
#Override
void methodF(){
//used listBoxF
}
}
public groupBox4View extends ContactView implements groupBox4Presenter
{
public groupBox4View()
{
}
#Override
void methodG(){
//uses listBoxG
}
#Override
void methodH(){
//used listBoxH
}
}
You are right, your view is growing too big. You need to cut it into components which are handling their own concerns.
The editor framework will prove helpful but has it's own caveats.
In the end, you have one presenter, working with the whole thing, but only reading and writing one contact object.
You build your view from multiple components, each may have it's own presenter and is responsible for one part of your large contact object.
An example: Instead of running 10 listboxes of generic type, make that 10 semantically different components, responsible for selection of different types of data: AgeListBox, CityListBox, FooListBox, BarListBox.
This will seperate the data provisioning for the boxes out of your central presenter, and into the specific presenters for each listbox.
Start at the lowest level and combine editing views for each semantic unit and combine them to larger return objects:
NameEditor, AgeEditor, FooEditor, BarEditor are combined into an AddressEditor, which assembles with a CVEditor into something bigger until you finally arrive at the contact level.
I hope this makes sense to you.
UPdate: You asked for code, let's try some pseudocode:
Let's say you have a profile you want to edit. It contains of
the user's personal data
contains the user address
a bunch of email or mobile addresses
an image or connection to Gravatar
payment information
the list of tags the user is interested in
the list of channels he subscribed
Newsletter/marketing information
public class UserProfile {
PersonalData person;
List<NewsTopic> topicsOfInterest;
List<NewsChannel> subscriptions;
MarketingInfo marketingInfo;
// bean stuff, constr, equals etc.
}
public class PersonalData {
String name;
String firstName;
List<ContactDevice>phoneAndMailList;
ImageContainer userImage;
BankAccount paymentData;
}
You get the idea, I guess...
You can now write ONE view class, detailing all the information you see here, resulting in a monolitic monster view and the matching monster presenter. Or you follow the advice in the gwtproject and cut the view in small as possible pieces (components). That is, subviews and presenters that form a hierarchy, matching the one of your UserProfile class. This is basically what the editor framework is really good at.
In the editor fw, the views are called "Editors" (makes sense), and they get fed the data from top editor down to the smallest part by an EditorDriver class. GWT will generate most of the code for you, which is very cool, but also is not working so perfect, if you have optional parts in the profile.
If we would implement this ourselves, you will build a structure like the following (I avoid the "Editor" and replaced by "Dialog"):
public class UserProfileDialogView extends Component implements HasValue<UserProfile> {
// subviews
#UiField
PersonalDataDialog personDataDlg;
#UiField
UserTopicListDialog topicListDlg;
#UiField
SubscriptionListDialog subscriptionListDlg;
#UiField
MarketingInfoDialog marketingInfoDlg;
#Overwrite
public UserProfile getValue() {
// we do not need to copy back the data from the sub-dialogs, because we gave them the values from the profile itself.
// Beware, substructures cannot be null in such a case!
return userProfile;
}
#Ovewrite
public void setValue(UserProfile profile) {
this.userProfile = profile;
// option one: manually distribute the profile parts
personDataDlg.getPresenter().setValue(profile.getPerson());
topicListDlg.getPresenter().setValue(profile.getTopicsOfInterest());
subscriptionListDlg.getPresenter().setValue(profile.getSubscriptions());
// option two: use eventbus and valuechanged event, dialogs are
}
}
There is now a variance of concerns: Who will set the value in the sub-dialogs. You can forward to the presenter of the sub-dialog, or you set it directly in the sub-dialog.
Anyway, what should get clear to you now, is that you do not have only one presenter to rule all parts of the view. You need to split the presenters to be responsible for one subview each. What I found useful in such a large dialog tree, was to have a separate model class, that keeps the object currently beeing edited and provides change communication logic for other dialogs. For example, if you add a list of topics, and you add one topic, the dialog for the channel subscription selection may want to know, that there is now one more topic to be shown in the topic-filter.

Java: How to do TextView.setText in another package?

I'm new to Java, I'm trying to build something in Android Studio.
The point is to 'push' a value for TextView baseTickVar in class BaseScreen, from another PACKAGE, where the class CoreFunctionality resides. Each time the tickNumber increases I want that shown in the TextView, so it's not a one time setting of text.
I have tried interfaces, but interfacing won't allow variables, only constants.
I've tried TextView.setText from the CoreFunctionality package, but that gave a nullpointerException and declaring the TextView to counter that didn't seem to help.
public class BaseScreen extends Activity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_screen);
// some irrelevant code here so i left it out.
TextView baseTickVar = (TextView)findViewById(R.id.baseTickVar);
baseTickVar.setText("1"); // just to not have it empty...
}
Now I want to set value of baseTickVar with a variable from the other package CoreFunctionality
public class CoreFunctionality extends Activity implements Runnable {
Thread tickThread = null;
volatile boolean playingGalactic;
long lastTick;
public int tickNumber;
int tickLength;
TextView baseTickVar;
public void controlTicks() {
tickLength = 2000;
long timeThisTick = (System.currentTimeMillis() - lastTick);
long timeToWait = tickLength - timeThisTick;
if (timeToWait > 0) {
try {
tickThread.sleep(timeToWait);
} catch (InterruptedException e) {
}
}
lastTick = System.currentTimeMillis();
}
#Override
public void run() {
while (playingGalactic) {
controlTicks();
tickNumber++;
Log.i("Tick number ", "" + tickNumber);
updateTick();
}
}
private void updateTick() {
// this is the whole point...
baseTickVar.setText("" + tickNumber);
}
public void resume() {
playingGalactic = true;
tickThread = new Thread(this);
tickThread.start();
}
I guess your BaseScreen is the main screen and CoreFunctionality is some component that is doing some work. Actually CoreFunctionality does not need to be Activity, it better fits to be a service.
You have to somehow pass reference to baseTickVar to the CoreFunctionality.
It is not allowed to mess with UI elements (such as TextView) from within another thread. You should consider using some inter-thread communication (such as Message).
Make BaseScreen to extend Handler or make a Handler object in it then override
public void handleMessage(Message msg) {
baseTickVar.setText("" + msg.obj);
}
In CoreFunctionality
private void updateTick() {
Message msg=new Message();
msg.obj=tickNumber;
h.sendMessage(msg);
}
Of course you'll have to pass the h reference to CoreFunctionality.
Maybe not 100% accurate but it should work with little tweaking.
Hope this will help.

Create Subclass and after super() call remove unnecessary items from parent

I have in my app 2 bars : topBar, bottomBar.
Basically each one of them creates images and set there positions on the screen. in my app I added a new screen that suppose to be with different bar - Advanced, but with some identical logic.
public class TopBar {
public TopBar () {
initImageA();
initImageB();
initResultManager();
initBG();
initLines()
}
}
public class BottomBar {
public BottomBar () {
initBg();
initBox();
initCover();
initcolorsLine();
initMenu()
}
}
In my app I crate bar according to the state:
private TopBar mTopBar;
private Bottom mBottomBar;
if (mState == "normal"){
mTopBar = new TopBar();
mBottomBar = new Bottom();
}
else {
mTopBar = new AdvancedTopBar();
mBottomBar = new AdvancedBottomBar();
}
mTopBar.setTitle()
mTopBar.setMainImage();
mBottomBar.drawLines()
.
.
.
AdvancedTopBar
public class AdvancedTopBar extends TopBar {
public AdvancedTopBar () {
super();
removeImageA();
removeImageB();
removeResultManager();
removeBG();
removeLines();
}
private removeImageA() {
.
.
.
}
}
Is it the right way to use inherence for creating the AdvancedTopBar for some identical logic (3,4 members) and calling to parent super() whats triggers initializing of images and then I just remove them one by one and create my own images, I think it's wrong... what options do I have to use different types of bars by on instance?
Just one of the many possible approaches: have one class and pass a boolean switch value in the constructor.
public class TopBar {
public TopBar(boolean advanced) {
doCommonStuff();
if (advanced) {
doAdvancedStuff();
}
}
}
So new TopBar(true) will give you an advanced bar, new TopBar(false) a standard one.

Why my boolean variable doesn't get updated on other classes?

I made a boolean called endGame, and when I click a button it will be set to false, and then on another class I made an object for the class where my boolean is. And when something happen the endGame will be set to true:
if(condition==true){ //the endGame variable will be equal to true only on this class
classObj.endGame=true;
}
//on the other class where the endGame is Located it is still false.
//button class
public boolean endGame;
public void create(){
endGame=false;
playButton.addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
endGame=false;
System.out.println(endGame);
return super.touchDown(event, x, y, pointer, button);
}
});
}
//second class
if(sprite.getY()>=700){
buttonObj.endGame=true;
enemyIterator.remove();
enemies.remove(sprite);
}
and then on another class I made an object for the class where my boolean is
I assume the endGame variable is not static. Otherwise you wouldn't need to create an object of the class where the boolean is in order to access it.
This means that if you set endGame to true in one object of the relevant class, it wouldn't update the value of endGame in different objects of that class.
you have several ways to fix that, maybe I'll say this is not the best, but without knowing anything of their code. because if the classes do not inherit from each other, or you can use a singleton pattern ?, I think this example may be worth it for you observer:
public class WraControlEndGame {
private ArrayList<EndGameOBJ> endGameOBJ = new ArrayList<EndGameOBJ>();
public void addEndGameOBJ(EndGameOBJ actor){
endGameOBJ.add(actor);
}
public void removeEndGameOBJ(EndGameOBJ actor){
endGameOBJ.remove(actor);
}
public void endGameOBJ_ChangeValue(boolean value){
for(int a = 0; a < endGameOBJ.size(); a++){
endGameOBJ.get(a).setEndGame(value);
}
}
}
.
public interface EndGameOBJ {
public void setEndGame(boolean value);
public boolean getEndGame();
}
.
public class YourClassThatNeedEndGameVariable implements EndGameOBJ{
..// other code
private boolean endGame = false;
..// other code Construct ect
#Override
public void setEndGame(boolean value) {
endGame = value;
}
#Override
public boolean getEndGame() {
return endGame;
}
}
.
in your code for example, this a pseudo code, you implements EndGameOBJ in your class you need, you view example in public class YourClassThatNeedEndGameVariable.
someClass buttonObj = new ....;//now this class implements EndGameOBJ
someClass classObj = new ....;//now this class implements EndGameOBJ
WraControlEndGame wraControlEndGame = new WraControlEndGame();
wraControlEndGame.addEndGameOBJ(buttonObj);
wraControlEndGame.addEndGameOBJ(classObj);
//bla bla bla
if(condition){
wraControlEndGame.endGameOBJ_ChangeValue(true);
}
I hope it will help and apologize for my English.

How can I access a class other than though passing in a method?

Let us say we have a class called World. Which contains a class called Data. We also have a third class called Input. If Input.clicked(Event event, int x, int y) were to be called I would not be able to access World which means I can't access Data. How do you go about resolving this?
Another way to ask this might be: How can you access something in a method from another class that can't be changed when what you need to access is not final?
Sorry, I am having a hard time explaining this.
Update bit: The world class already exists, can't create a new one. It would be inside the Game class.
Here is a code example, not working code. More pseudo.
public class World {
Data data = new Data();
Input input = new Input();
public void update(float delta) {
input.getInput();
input.makeChangesBasedOnInput();
}
public void render(float delta) {
}
}
public class Data {
public int importantNumber; // Static is not an option
// For me I have to get a user name... but same idea here
public Data() {
Random ran = new Random();
importantNumber = ran.nextInt(1000);
}
}
public class Input {
Button button = new Button();
public Input() { // passing the World class does not work, ex. public Input(World world) {
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) { // I can't add world here...
// HERE IS ISSUE
System.out.println(World.Data.importantNumber);
}
}
}
public void getInput() {
// MAGIC
}
public void makeChangesBasedOnInput() {
// MAGIC
}
}
Update 2: Here is another example of what I am trying to do with TextButton & ClickListener from libgdx.
statsButton is a TextButton() from libgdx.
You say passing the World class does not work, well that is probably because you tried to acces a local variable from anonymous function, example:
public Input(World world) {
button.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
// error: world is not final
System.out.println(world.data.importantNumber);
}
}
}
this is what probably happened (if not, please let me know). In Java 8, world would be effectivly final, but in Java 7 or earlier, you would have to declare it final explicitly, like
public Input(final World world) { ... }
Also a common approach is to store your world inside a field:
private World world;
public Input(World world) {
this.world = world;
...
}

Categories