I have created an array which I wanted to control from main. My code runs, but I don't know how to add integers to the array from the main class. Also as each ConcreteSubject has its own storage array, how would i change this to store them all in the same array?
public class ConcreteSubject extends AbstractSpy
{
private AbstractSpy[] spies = new AbstractSpy[10];
private int i = 0;
public void addSpy(AbstractSpy s) {
if (i < spies.length) {
spies[i] = s;
System.out.println("spy added at index " + i);
i++;
}
}
}
public class TestClass
{
public static void main(String[] args) {
ConcreteSubject cs = new ConcreteSubject();
AbstractSpy spies = new AbstractSpy() {
#Override
public void addSpy(AbstractSpy spies) {
}
};
cs.addSpy(cs);
spies.addSpy(spies);
}
}
It seems like your program logic is a little borked. This bit in particular doesn't make much sense:
***AbstractSpy spies = new AbstractSpy() {
#Override
public void addSpy(AbstractSpy spies) {
}
};
cs.addSpy(cs);
***spies.addSpy(spies);
What you're doing is creating TWO AbstractSpy instances, one named cs and one named spies. On that last line you're adding spies to itself! That doesn't help you at all.
Note that AbstractSpy is the most granular unit in your setup - it shouldn't have an addSpy() method and its own internal array, it should be the thing that's added to something else's array!
Here's the same code, but cleaned up a bit:
public abstract class AbstractSpy { }
public class ConcreteSpy extends AbstractSpy { }
public class ConcreteSubject {
private AbstractSpy[] spies = new AbstractSpy[10];
private int i = 0;
public void addSpy(AbstractSpy spy) {
if (i < spies.length)
{
spies[i] = spy;
System.out.println("spy added at index " + i);
i++;
}
}
}
public class TestClass {
public static void main(String[] args) {
ConcreteSubject cs = new ConcreteSubject();
AbstractSpy spy = new ConcreteSpy();
cs.addSpy(spy);
}
}
The big difference here is that ConcreteSpy is an implementation of AbstractSpy that you can add to your ConcreteSubject's array of spies. I think you might have been confused by Java's insistence that you can't create an instance of an abstract class on its own unless you supply an anonymous class that inherits from the abstract class.
Related
Dataset.java
package base_project;
import ....
public class Dataset extends javax.swing.JFrame {
public Dataset() {
initComponents();
addRowToJTable();
}
static ArrayList<a> ar = new ArrayList<a>();
public void Read()
{
}
public void addRowToJTable()
{
DefaultTableModel model = (DefaultTableModel) jTableDataset.getModel();
Read();
String Data[][]=new String[ar.size()][12];
for (int i=0;i<ar.size();i++)
{ }
}
private void jButtonDSNextActionPerformed(java.awt.event.ActionEvent evt) {
Classification c = new Classification();
c.setVisible(true);
this.setVisible(false);
}
public static void main(String args[]) {
}
This is my first JFrame form which is named as Dataset.java . In this file i have used Read() method. This file contains one buttton which leads to next JFrame called Classification. The code of Classification.java is as follows:
Classification.java
package base_project;
import ....
public class Classification extends javax.swing.JFrame {
public Classification() {
initComponents();
addRowToJTable();
}
static ArrayList<a> ar = new ArrayList<a>();
static ArrayList<q> aq = new ArrayList<q>();
static ArrayList<s> as = new ArrayList<s>();
public static void Read()
{}
public static void Set_Q()
{}
public static void Set_s()
{}
public void addRowToJTable()
{
DefaultTableModel modelQID = (DefaultTableModel) jTableQID.getModel();
DefaultTableModel modelSA = (DefaultTableModel) jTableSA.getModel();
Read();
Set_Q();
Set_s();
String DataQ[][]=new String[aq.size()][6];
for (int i=0;i<aq.size();i++)
{
}
String DataS[][]=new String[as.size()][6];
for (int i=0;i<as.size();i++)
{
}
}
public static void main(String args[]) {
}
This runs fine. But the problem is that i have to again write the whole Read() method in this Classification.java also. So eachtime whenever i want to use that method i have to again write it in every new JFrame , which i don't want. So what can i do to avoid that?
I'm no expert in java so please bear with me. I've tried looking through the java docs and on this site but cannot seem to find a solution to my problem.
THANKS in advance.
Theres a few things that are a little confusing, as followd:
Firstly, there should only ever be one public static void main(String args[]) {} method because this is the start of the program which there can only ever be one.
Secondly, when a class extends another class it shares all of the methods in the super class. This is what you are doing when you go "Classification extends JFrame" and "Dataset extends JFrame" both classes now technically have the same methods, plus whatever you add on top in each class.
Therefore, one of the key OOP principals is that if two classes share the exact same code, you put that code in the super class. In this case both classes extend JFrame, but you cannot edit JFrame as it is part of the existing Java API. Therefore, to make the read() method common between both files, you should create a wrapper such as (AbstractReadFrame.java):
public abstract class AbstractReadFrame extends JFrame {
// AbstractReadFrame shares all methods within JFrame
public void read() {
// code for reading, this is shared between all classes which extends AbstractReadFrame
}
// other common code
}
public class Classification extends AbstractReadFrame {
// shares all methods within AbstractReadRame and JFrame
public void addRowToJTable() {
DefaultTableModel modelQID = (DefaultTableModel) jTableQID.getModel();
DefaultTableModel modelSA = (DefaultTableModel) jTableSA.getModel();
Read();// calls read() in AbstractReadFrame
Set_Q();
Set_s();
String DataQ[][] = new String[aq.size()][6];
for (int i = 0; i < aq.size(); i++) {
}
String DataS[][] = new String[as.size()][6];
for (int i = 0; i < as.size(); i++) {
}
}
// other code
}
public class Dataset extends AbstractReadFrame {
// shares all methods within AbstractReadRame and JFrame
public void addRowToJTable() {
DefaultTableModel model = (DefaultTableModel) jTableDataset.getModel();
Read(); // calls read() in AbstractReadFrame
String Data[][] = new String[ar.size()][12];
for (int i = 0; i < ar.size(); i++) {
}
}
// other code
}
However, in classification.java you have declared read() to be static which means it will not be work with in the way i have mentioned above. I'd recommend reading about inheritance in Java (such as https://www.tutorialspoint.com/java/java_inheritance.htm)
as this will help you a lot with structuring your program.
By having the super class hold all common code, you only have to write it once and run it whenever you wish.
I am trying to apply varargs. I have declared a method which requires an indefinite amount of variables like this:
private Subject carMonitor;
public AdvancedMonitor(Subject ... carMonitors){
for (Subject carMonitor : carMonitors){
this.carMonitor = carMonitor;
carMonitor.registerObserver(this);
}
}
However, when I try to call it in my main method, I am not able to use anything other than one argument:
BigCar bigCar = new BigCar();
SmallCar smallCar = new SmallCar();
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
Only the second one works. Why is this?
Is it related to my interface?
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
big car interface -- small car is pretty much the same for now :
public class BigCar implements Subject {
private ArrayList observers;
private int state;
public BigCar(){
observers = new ArrayList();
}
public void registerObserver(Observer o){
observers.add(o);
}
public void removeObserver(Observer o){
int i = observers.indexOf(o);
if (i >= 0){
observers.remove(i);
}
}
public void notifyObservers(){
for (int i = 0; i < observers.size(); i++){
Observer observer = (Observer)observers.get(i);
observer.update(state);
}
}
public void stateChanged() {
notifyObservers();
}
public void setState(int state){
this.state = state;
stateChanged();
}
}
I write following code:
public class Test {
public static class AdvancedMonitor {
private String carMonitor;
public AdvancedMonitor(String... carMonitors) {
for (String carMonitor : carMonitors) {
this.carMonitor = carMonitor;
System.out.println(this.carMonitor);
}
}
}
public static void main(String[] args) {
String bigCar = "bigCar";
String smallCar = "smallCar";
System.out.println("step 1");
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
System.out.println();
System.out.println("step 2");
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
System.out.println();
System.out.println("step 3");
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
}
}
And I have following result:
step 1
step 2
bigCar
step 3
bigCar
smallCar
In my opinion, all correct. What is wrong in your case? Do you use logging or System.out.println to debug your problem? It's look like your problem isn't with Java varagrs, but you have some exception in carMonitor.registerObserver(this).
P.S. Also, you understand that every AdvancedMonitor has only a one varible carMonitor? And using new AdvancedMonitor(bigCar, smallCar); in result you have AdvancedMonitor only with smallCar in private String carMonitor;?
P.P.S. Also bad idea to use this in construstor, because object isn't really create when running construstor.
Actually the Constructor works.
Please check these statements:
SmallCar and BigCar both implements Subject
class AdvancedMonitor implements Observer
AdvancedMonitor doubleAdvancedDisplay is not declared several times but in your code it is. It should be smth like:
AdvancedMonitor doubleAdvancedDisplay1 = new AdvancedMonitor();
AdvancedMonitor doubleAdvancedDisplay2 = new AdvancedMonitor(bigCar);
AdvancedMonitor doubleAdvancedDisplay3 = new AdvancedMonitor(bigCar, smallCar);
I hope it'll help you
I have three classes.
public class PutController{
public PutController[] putControllerArray = new PutController[2];
public void controlar(int players) {
if(numeroJugadores==0){
putControllerArray[0] = new PutAutoController(tablero, tableroView, turno, turnoView);
putControllerArray[1] = new PutAutoController(tablero, tableroView, turno, turnoView);
}
if(numeroJugadores==1){
putControllerArray[0] = new PutManualController(tablero, tableroView, turno, turnoView);
putControllerArray[1] = new PutAutoController(tablero, tableroView, turno, turnoView);
}
}
}
public class PutManualController extends PutController {
public void methodToCall(){
.....
}
}
public class PutAutoController extends PutController {
public void methodToCall(){
.....
}
}
class Principal{
private PutController putController = new PutController(tablero, tableroView, turno, turnoView);
}
and in my Principal class i want to call a method of an element in the array of put class, like this.
putController.putControllerArray[0].methodToCall();
Hope you can help me. Thanks!
As long as PutController contains the method methodToCall() (either as an abstract method implemented by the sub classes, or with a concrete implementation in the base class), you can call it on any element of your array.
public class PutController
{
...
public void methodToCall ()
{
....
}
...
}
The sub-classes can override methodToCall() if they require different implementations.
This would make the code putControllerArray[0].methodToCall() valid. Of course, if you need to access that array from outside your class, you need to create an instance of your class, since it's not a static member. It would be better, though, to make the array private and access it via a method that returns the i'th element of the array.
public class PutController
{
...
public PutController getElement (int i)
{
if (i < 0 || i >= putControllerArray.length) {
// TODO throw some exception
}
return putControllerArray[i];
}
...
}
Then you can execute methodToCall() via putController.getElement(0).methodToCall();
In my code, I have a seperate Runner class that instantiates a World, which has a 4x4 array of Locations (a separate class) stored as a Location[][] array. When I print/try to use the Location array, its value is null, and it throws a NullPointerException.
public class Runner
{
public static void main(String[] args)
{
...
WumpusWorld test_loc = new WumpusWorld();
System.out.print(test_loc) //This prints an ID for the WumpusWorld object
System.out.print(test_loc.world) //Null value prints here
//I'd like to pass the test_loc.world values to an actor here
...
}
}
The applicable code for the WumpusWorld is as follows:
public class WumpusWorld
{
public Location[][] world;
public WumpusWorld()
{
new WumpusWorld((byte) 4); //this constructor is used
}
...
public WumpusWorld(byte size)
{
this.world = new Location[size][size];
for(byte i = 0; i<size; i++)
{
for(byte j = 0;j<size;j++)
{
world[i][j] = new Location(j,i,true,false,false);
}
//Location instances called in the form world[x][y]
//are error free in constructor
...
}
}
Your problem might be in the way you call public WumpusWorld(byte size) from the default constructor.
Try this:
public WumpusWorld()
{
this((byte) 4);
}
With new in the call, I had uninitialized values in the inner class
I come from writing a lot of JavaScript, so bear with me.
I've got 3 HashMaps, which i reference in a method in a different class. My code (very simply) looks like so:
public class MainClass {
private HashMap<String,Nation> randomHashMap = new HashMap<String,Nation>();
DifferentClass d = new DifferentClass(this);
} //with getters/setters
public class DifferentClass {
private MainClass mc;
public void randomMethod() {
System.out.println("randomHashMap is " + (mc.getRandomHashMap() == null));
} //returns null
public DifferentClass(MainClass c) {
this.mc = c;
}
}
However, when I call them in my other method, they're null.
How do I create a new, empty HashMap?
You need to initialize your MainClass mc variable before using it in the DifferentClass#randomMethod method. Also, make sure you're using the mc variable instead of the MainClass.getRandomHashMap() method (by your actual code, we don't know how it behaves). Your code will look like this:
public class DifferentClass {
private MainClass mc = new MainClass();
public void randomMethod() {
//assuming getRandomHashMap is the getter of randomHashMap attribute (and non static)
System.out.println("randomHashMap is " + (mc.getRandomHashMap() == null));
}
}
public class MainClass {
private HashMap<String,Nation> randomHashMap = new HashMap<String,Nation>();
DifferentClass d = new DifferentClass(this);
public HashMap<String,Nation> getRandomHashMap() {
return this.randomHashMap;
}
} //with getters/setters
The code you posted is in fact perfectly all right as far as field initialization. I made an SSCCE from it with minimal intervention:
class Nation{}
public class MainClass {
private HashMap<String,Nation> randomHashMap = new HashMap<String,Nation>();
DifferentClass d = new DifferentClass(this);
public Object getRandomHashMap() {
return randomHashMap;
}
public static void main(String[] args) {
new MainClass().d.randomMethod();
}
} //with getters/setters
class DifferentClass {
private MainClass mc;
public void randomMethod() {
System.out.println("randomHashMap is " + (mc.getRandomHashMap() == null));
} //returns null
public DifferentClass(MainClass c) {
this.mc = c;
}
}
and it prints
randomHashMap is false
which proves that randomHashMap is indeed non-null.