views:

157

answers:

3

I have a class CommonTableModel that has several instance methods and each operate on the two instance variables

  • columnNames
  • data

Now, I have six tables, each has diff. column names but should have all the instance methods of the CommonTableModel class. So to pass an instance of the CommonTableModel to a JTable instance, I should first initialize both of the instance variables (columnNames and data).

Q1. Should I make six TableModels, each corresponding to each table and then extends them to the CommonTableModel?

public class FirstTableModel extends CommonTableModel {

    public FirstTableModel() {
        columnNames = {"id", "name"};
        data = {{1, "John"}};
    }
}

In the above example, I tried to initialize inherited data members so that each of the six TableModel can populate columnNames according to the table that they denote.

But I got an error which is restricting me to initialize the inherited members in this way. I think that we can't initialize instance variables in this way.

Then how can I populate the instace variables of CommonTableModel so that the instance methods of the CommonTableModel process the data that I populate them later.

One of the solution is to pass the data in the constructor of CommonTableModel but in that way, I will have to pass the whole columnNames each time when I make a Table.

I am very confused as I don't have much experience in programming and don't know good coding practices.

Please, also refer some good design pattern books so that I can have a better understanding of design patterns.

+2  A: 

But I got an error which is restricting me to initialize the inherited members in this way. I think that we can't initialize instance variables in this way.

Arrays which aren't initialized with new are array constants. You can only initialize them directly after declaration. E.g.

String[] strings = {"foo", "bar"};

Thus, you should replace the particular lines by (assuming those are already protected fields of CommonTableModel):

columnNames = new String[] {"id", "name"};
data = new Object[][] {{1, "John"}};

Edit as per the comments: you can of course also define a constructor for that and make use of the super() call. The advantage is that this improves the degree of encapsulation, i.e. you don't need to declare the fields protected, but they can now be declared private. Here's a kickoff example:

public abstract class CommonTableModel {
    private String[] columnNames;
    private Object[][] data;

    protected CommonTableModel(String[] columnNames, Object[][] data) {
        this.columnNames = columnNames;
        this.data = data;
    }
}

.

public class FirstTableModel extends CommonTableModel {
    public FirstTableModel() {
        super(new String[] {"id", "name"}, new Object[][] {{1, "John"}});
    }
}

Note that you still need the new keyword to instantiate them (rsp was wrong here in his answer). You should only NOT make the properties static!! It would affect every instance of the same class. You really don't want to have that. Also see my comment here below.

BalusC
+1 for "... Arrays which aren't intialized with new ..." Thanks
Yatendra Goel
rsp's and your answer are looking great. Could you please which one would be better?
Yatendra Goel
It's your choice. You should for sure only not make them `static` as you mentioned in a comment of rsp's answer. It will affect **ALL** instances of the same class!! You should also use the `new` keyword to instantiate them before passing through the superclass' constructor. I'll edit the answer soon with an example:
BalusC
A very-2 thanks for such a detailed answer.
Yatendra Goel
+1  A: 

If the only differences between your table models are the column names I would just pass them to the constructor of your CommonTableModel as an array of strings. Use the same class for all of your tables, but different data.

mjh2007
Agreed -- it really looks like the only difference between his objects is within the data. The different table models should be separate instances of the same class, rather than separate classes.
Jim Kiley
+1  A: 

Your table models extend the common table model, the common table model can initialise the columns and data in its constructor, I think you are looking for a pattern like this:

public class CommonTableModel {

    protected CommonTableModel (String[] n, Object[] d) {
        columnNames = n;
        data = d;
    }
}

public class FirstTableModel extends CommonTableModel {

    public FirstTableModel() {

        super(new String[] {"id", "name"}, new Object[][] {{1, "John"}});
    }
}
rsp
If I pass reference variables in the super() call, it shows a compile-time errors as "cannot reference n before super type constructor has been called"
Yatendra Goel
Oh.. I remember... we can't pass instance variables in super(). I make them static and now it is working fine.
Yatendra Goel
If you make them static, they will have application scope. You need to make them private atributes of CommonTableModel and instantiate the arrays with `new[]`.
rsp