Link to home
Start Free TrialLog in
Avatar of jkteater
jkteaterFlag for United States of America

asked on

Creating a Class variable

Right now I am creating a TableModel variable  in my method

private JPanel selectedTable(){
        
    tableLabel = new JLabel();
   GridBagLayout gridbag = new GridBagLayout();
    p.setLayout(gridbag);
   
    TableModel myModel = new SelectedTModel();

How would I make this a class variable?

I want to be able to write some functions in SelectedTModel() class and call them from my current class.
Avatar of for_yan
for_yan
Flag of United States of America image

You declare it imemedauiltely after class declataion
public class myTable {
 TableModel myModel;

....


  TableModel myModel = new SelectedTModel();

In orderr to access it form some other class
you may want to have some setter and getter finctions,
so with instance of your class and with these fuunctions you'll be able to get hold
of your model from any other class
Avatar of CEHJ
a. i wouldn't make it a class variable
b. i wouldn't make the model directly accessible anyway

Even in the same compilation unit, it's less error-prone to do


TableModel m = table.getModel(); // (cast 'm' if necessary)

as you can always be certain that the model state is correct.

From a DIFFERENT class, make an accessor method to get the *table* and use the line of code i posted above
Avatar of jkteater

ASKER

OK bare with me on this one :)

Right now I have selectedTable method in my class.  It basically gets my JTable from the class SelectedTModel() and displays it.

myModel = new SelectedTModel();
      // Create a new table instance
      selectTable = new JTable(myModel);
      selectTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
      selectTable.setCellSelectionEnabled(false);
      selectTable.setRowSelectionAllowed(true);
      selectTable.setColumnSelectionAllowed(false);
etc.....

So now I have to add a button that will remove the selected row from the table.  So I was writing a method in SelectedTModel() called removeSelectedRow(); so I am thinking my action for the button would be something like

SelectedTModel.removeSelectedRow();

But I am not sure I would get the same instance of the table in both classes as well do I have to pass to the method the selected row?
This is the SelectedTModel class

 
public class SelectedTModel extends AbstractTableModel {
   
   private static final long serialVersionUID = 1L;
   private ArrayList<RevDataset> aList;
   
   static final int ITEMID_COL   = 0;
   static final int REVID_COL    = 1;
   static final int PRL_COL      = 2;
   static final int DATASETNAME_COL  = 3;
   static final int DATASET_COL  = 4;
   
   static final int MAX_COLUMNS  = 5;
      
   //////////////////////////////////////////////////////////////////////////
   //                                                                      //
   //                              Constructor                             //
   //                                                                      //
   //////////////////////////////////////////////////////////////////////////
   public SelectedTModel() {
      super();
      this.aList = EdiSelection.rds;	
      if(aList == null) aList = new ArrayList<RevDataset>(); 
                
   } // end constructor
   
   //////////////////////////////////////////////////////////////////////////
   //                                                                      //
   //                             getColumnCount()                         //
   //                                                                      //
   //////////////////////////////////////////////////////////////////////////
   public int getColumnCount() {
	   
      return MAX_COLUMNS;
   } // end getColumnCount()
   
   //////////////////////////////////////////////////////////////////////////
   //                                                                      //
   //                             getRowCount()                            //
   //                                                                      //
   //////////////////////////////////////////////////////////////////////////   
   public int getRowCount() {
      return aList.size();
	  
   } // end getRowCount()
   
   //////////////////////////////////////////////////////////////////////////
   //                                                                      //
   //                             getValueAt()                             //
   //                                                                      //
   //////////////////////////////////////////////////////////////////////////  
   public Object getValueAt(int row, int column){
      Object o = null;
           
	  try {	   
	     switch (column) {
	        case ITEMID_COL: { o = aList.get(row).rev.getItem().getStringProperty("item_id"); break; }
	        case REVID_COL: { o = aList.get(row).rev.getStringProperty("item_revision_id"); break; }
	        case PRL_COL: { o = aList.get(row).rev.getRelatedComponent("IMAN_master_form_rev").getStringProperty("PRL"); break; }
	        case DATASETNAME_COL: { o = aList.get(row).componentdataset.getStringProperty("object_string"); break; }
	        case DATASET_COL: { o = aList.get(row).componentdataset.getStringProperty("object_type"); break; }
	     }
	  }
	  catch (Exception e) {
	     e.printStackTrace();
	 
      } 
	  return o;
   }
   
   //////////////////////////////////////////////////////////////////////////
   //                                                                      //
   //                             getColumnName()                          //
   //                                                                      //
   //////////////////////////////////////////////////////////////////////////
   public String getColumnName(int column) {
      String s = null;
      
      switch (column) {
      case ITEMID_COL:   { s = "ItemId"; break; }
      case REVID_COL:    { s = "RevId"; break; }
      case PRL_COL:      { s = "PRL"; break; }
      case DATASETNAME_COL:  { s = "Dataset Name"; break; }
      case DATASET_COL:  { s = "Dataset Type"; break; }
      }
   return s;
   } // end getColumnName()
   
   //////////////////////////////////////////////////////////////////////////
   //                                                                      //
   //                         removeSelectedRow()                          //
   //                                                                      //
   //////////////////////////////////////////////////////////////////////////
   public void removeSelectedRow() {
	  
   } 

}//end SelectedTModel

Open in new window

You should have one instance of JTable and one instance of your model and create them only once and pass it to all the classes you are dealing with
and decaler both of them instance vraibales and have these setter getter methods to ensure that you pass this
instance around and you'll be sure that you always access the same JTable and the same instance of model

but this is not waht you want as this sould not be static method
SelectedTModel.removeSelectedRow();


you mant

myModel.removeSelectedRow();

You want to make your model instance varaible, but I don't think there is any reason to make it static
So if you created your model in the instance of one class, but need to access it in the instance of another class - you need to have
the method to get the instamce of your m,oodel to the second class

Something like that:
-----
public class A {
SelectedTModel mtModel;


public Aclass{
myModel = new SelectedTModel();
...

Bclass bb = new Bclass(this,....);
}

public SelectedTModel getModel(){
return myModel;
}


}

---
pucblic class Bclass {
Aclass aaa;

public Bclass(Aclass aaa,...){
this.aaa = aaa;
...
}

SelectedTModel myModel = aaa.gteModel();

//do somethin with myModel - it will be the same instance which you creted in the Aclass

}




I am trying to follow your logic above - It does sound like what I am asking.  I am just trying to put it in real code.

public class EdiBaseDialog extends AbstractAIFDialog {

This is the class that gets the tablemodel and displays it to the users

public class SelectedTModel extends AbstractTableModel {

This is the class that gets the data and builds the rows and columns

So how does the above relate to these classes - is class A the same as EdiBaseDialog?

yes, Aclass is EdiBaseDialog
but by Bclass I meant some third class, where I thiought
you wanted to access the same table model.
If you access table model and create Jtable and
set model of your Jtabel alll in EdiBaseDialog - that's even simpler
ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
And you create instance of your model only once - maybe in the constructore of EdiBaseDialog
and make sure that you only once have theis new SelectedTModel()

and in all other place you'll be accessing the same instance
public EdiBaseDialog(Frame parent, TCSession theSession){
         super(parent, false);
         session = theSession;
         SelectedTModel es = new SelectedTModel();
         this.checkList = EdiSelection.rds;
          TableModel myModel = new SelectedTModel();
         createDialog();  
        
   } //end Constructor

So I create my instance in the constructor like above.

in EdiBaseDialog  I have a method to build my JTable and show it

private JPanel selectedTable(){
        
    tableLabel = new JLabel();
    JPanel p = new JPanel();
    GridBagLayout gridbag = new GridBagLayout();
    p.setLayout(gridbag);
   
       // Create a new table instance
      selectTable = new JTable(myModel); <== we created this instance in the constructor
      selectTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
      selectTable.setCellSelectionEnabled(false);
      selectTable.setRowSelectionAllowed(true);
      selectTable.setColumnSelectionAllowed(false);

I am writing a method in SelectedTModel class named removeSelectedRow();
The method will get the current selected row in the table and remove it.
This method will be called from a button click in EdiBaseDialog.

what do I need to do in order for the above to work?  I want to make sure that I the right instance of the table and that I am working with the same data that is in the table being displayed

No, in the constructioor you should do
No you should do it like that to become instance varaibel:

(and why do you create two instance dof model?)
public class EdiBaseDialog {

SelectedTModel es;

public EdiBaseDialog(Frame parent, TCSession theSession){
         super(parent, false);
         session = theSession;
         es = new SelectedTModel();
         this.checkList = EdiSelection.rds;
         // TableModel myModel = new SelectedTModel();
         createDialog();  
       
   } //end Constructor

You should declare the variable outside of any method (incl constructor) for it to beciome
instance variable
I may have done this all wrong.  I am very open to suggestions.  Maybe I should have used the class SelectedTModel to do all my table things and then pass the table to my panel in EdiBaseDialog Class.  I will increase the points if you can help me make this code the right (correct ) way to do this
One more issue that I am having with the table that maybe we can fix.  The table is built from a ArrayList and the user creates.  If the dialog is open and the table is displayed, if the user selects another object and it gets added to the arraylist, I would like for the table to display the new object.  I have no way to tell the table to refresh the way it is done today
You should just understand that you have one instance of JTable and one inastance of its model and
it does not really matter in waht particular palce you create and populate them - as you saw you can pass the reference to any object to any
class which you are ruunning and if you created it with new operator only once and after that just passing its reference
then you should be fine.

You also should clear understand the difference between the instance variable and the local vbraibale of
method (Or constructor)
The instance variable is something specifci to the instance of the whole class - think of oit as a proeprty
of the class - it uis declared outside of any method and it is accessible from everywheer in the class.
Local variables are declared within the metod and accessibke only within the method - see my previous post about where your model should be declared


Again, once you have one instance of model - you can frst populate it with ione array list
and then in another place just replace the contetns with the contents from another arraylist
or maybe replace the contents of the model or add to the rows form another
arraylist - - so you changed the model - and yourt table will always be tdetermined by the contetnst of this model

This is very critical - about instance variables and local variables  - just think about it - try to understand it once and for all -
you;'ll have all the time problesm with java if you don't understand this difference between instance and local -
think and ask questions, but it just makes no sense trying to do anything if you are not 100% clear
with this difference. Please, ask what you don't understand - this is crucial.
OK - I understand that we have one instance of the JTable and and Model.

Where would I create my method to remove a selected cell from the jtable.  I was leaning toward writing in it the SelectedTModel class.

I was thinking something like

public void removeSelectRow() {

int numRows = jTable.getSelectedRows().length;
for(int i=0; i<numRows ; i++ ) model.removeRow(jTable.getSelectedRow());

}

What would jTable and model be?  Or how should i remove a selected row from the table?

I know that a local variable is only in the method.  It can not be used outside that method.  I know that a class variable can be used in any method in the class.  I am never sure how you pass things from class to class.  That is where I get confussed
I am going home for the day.  Thanks for your help so far.  This it the first project I have done in Java of this size and complexity.  You have been a huge help for me.
I showed you how to pass variables - lookk at that, explain what you don;t understadn and we'll go through that once again;
this is very critical things.

I'm not sure that deleteing row in your model class will be the best thing.

Thisnk about the model class as some clothing over the data - and the data may be
two-dimansional array or arraylist of arraylists.
So I would make that arraylist of arraylists - the main inatnce variables which whould be accesible everywere
and your model should take data from this arraylist of arraylists and return it in the methods which JTable
expects. So in the place of your program where you will know which
row to remove - you jsut remove that ronw from this arraylist of arraylists and as a result
your model wioll be retuyrning to Jtable modified set of data.
That is what should be logical way.

So somehwre in yourt dialog you'll have event when user clicks on some row
then in the method which handles that even you determione which row was sleceted
and remove this arraylist form your main object with data
and then sometimes you'll need to reopiant the table - but those are alreadty detauils

Try to think in these terms and I hope it will become more clear







As i mentioned, references to Swing models should not be kept - whether as class OR instance variables. It's simply bad practice and error-prone
As I continue on with this project, I am seeing many bad practices.  but this is the first project I have done this size and after I get the code to testing, I will go back in and try to clean up the code.
>>As I continue on with this project, I am seeing many bad practices.

You will in your programming life. My concern is that they not be encouraged in this TA