jkteater
asked on
Java - Explain Singleton
I have 2 classes that I was told I will need to merge them together and to look up Singleton. I have never heard of that before. I look it up on google and it seems some what complicated. Can someone explain what it is?
It's actually very simple: it's a class of which there can only ever be one instance
This is the classic desing - you have private constructor and static instance getIntsance method where
you check that instance should be zero befire yyou create it - in this way no omne can create two instances of this class in one application
you check that instance should be zero befire yyou create it - in this way no omne can create two instances of this class in one application
public class ClassicSingleton {
private static ClassicSingleton instance = null;
protected ClassicSingleton() {
// Exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(instance == null) {
instance = new ClassicSingleton();
}
return instance;
}
}
What they mean bout merging two classes together - that's another story and can be meant in amny different ways
SO with that design above just to reiterate - you may be sure that wherever you access an instance of thsi calss
in your appliction you will always access one and the same instacne; that is bcecauyse if instance is not null
it will return to getInstance() method already existying instance.
in your appliction you will always access one and the same instacne; that is bcecauyse if instance is not null
it will return to getInstance() method already existying instance.
ASKER
I have a EdiSelection class ( you may remember helping with it ) and I have a SelectedTModel class.
The EdiSelection class creates my ArrayList using a add() that is being called when the user selects objects
EdiSelection.add(tcRevisio n,selected Dataset); <- that is called in my EdiHandler class.
EdiSelection Class
my SelectedTModel class basically builds my tablemodel I am using to populate my jtable in my base dialog.
It is using the ArrayList we created in EdiSelection
I have been told that I need to merge these 2 classes and use a singleton to do it?
The main problem is there are 2 entries to this program.
1. EdiHeader class - The user selects objects using a shortcut menu and then the objects create the ArrayList
2. EdiBaseDialog class - The user can select a button on the top menu - this opens the base dialog with the jtable
EdiHeader way calls the EdiSelection class and that is the only way it is called
EdiBaseDialog way calls the SelectedTModel class and that is only way it is called
so if the user goes in the proper order and selects his objects first shortcut menu( EdiHeader ) and then selects the program button at the top menu ( EdiBaseDialog ) it works great.
but what if the user wants to start the base dialog with a empty table and then shortcut menu his object selections. The user needs to see the jtable update with his selections. Today that have to close the base dialog and re open it to show the new selections.
So I was told if we merge the classes it would fix that issue
The EdiSelection class creates my ArrayList using a add() that is being called when the user selects objects
EdiSelection.add(tcRevisio
EdiSelection Class
public class EdiSelection {
static ArrayList<RevDataset> rds = new ArrayList<RevDataset>();
//////////////////////////////////////////////////////////////////////////
// //
// Constructor //
// //
//////////////////////////////////////////////////////////////////////////
public EdiSelection() {
// rds = new ArrayList<RevDataset>();
}// end Constructor
//////////////////////////////////////////////////////////////////////////
// //
// add() //
// //
//////////////////////////////////////////////////////////////////////////
public static void add(TCComponentItemRevision tcRevision, TCComponentDataset selectedDataset){
//rds.add(new RevDataset(tcRevision,selectedDataset));
//System.out.println("Key :" + tcRevision.toString() + " Value : " + selectedDataset.toString() + " \n");
RevDataset pp = new RevDataset(tcRevision,selectedDataset);
if(!rds.contains(pp))rds.add(pp);
}// end add
//////////////////////////////////////////////////////////////////////////
// //
// getList() //
// //
//////////////////////////////////////////////////////////////////////////
public static ArrayList<RevDataset> getList(){
return rds;
}// end GetList
//////////////////////////////////////////////////////////////////////////
// //
// clearList() //
// //
//////////////////////////////////////////////////////////////////////////
public static ArrayList<RevDataset> clearList(){
rds.clear();
return rds;
}// end GetList
} // end class EdiSelection
my SelectedTModel class basically builds my tablemodel I am using to populate my jtable in my base dialog.
It is using the ArrayList we created in EdiSelection
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;
} // 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(int row) {
boolean b = (aList.remove(row) != null);
//fireTableDataChanged();
fireTableRowsDeleted(row, row);
}
}//end SelectedTModel
I have been told that I need to merge these 2 classes and use a singleton to do it?
The main problem is there are 2 entries to this program.
1. EdiHeader class - The user selects objects using a shortcut menu and then the objects create the ArrayList
2. EdiBaseDialog class - The user can select a button on the top menu - this opens the base dialog with the jtable
EdiHeader way calls the EdiSelection class and that is the only way it is called
EdiBaseDialog way calls the SelectedTModel class and that is only way it is called
so if the user goes in the proper order and selects his objects first shortcut menu( EdiHeader ) and then selects the program button at the top menu ( EdiBaseDialog ) it works great.
but what if the user wants to start the base dialog with a empty table and then shortcut menu his object selections. The user needs to see the jtable update with his selections. Today that have to close the base dialog and re open it to show the new selections.
So I was told if we merge the classes it would fix that issue
No, frankly I don't see the connection with merguing the classes.
What you need to have is to establish proper connection between your classes.
So when the user starts the base dialog with an emapty table and then makes selsections in the menu - you jtable should get populated and refreshed
and then they will see it upddated. Ti achive this you don't need to merge them into one class - you just need to mainitain proper handles to
instances of one class in another class and excute methods of easch other when necesssary.
I think we went through similar situations already
What you need to have is to establish proper connection between your classes.
So when the user starts the base dialog with an emapty table and then makes selsections in the menu - you jtable should get populated and refreshed
and then they will see it upddated. Ti achive this you don't need to merge them into one class - you just need to mainitain proper handles to
instances of one class in another class and excute methods of easch other when necesssary.
I think we went through similar situations already
ASKER
we have and I still can not get it to work
ASKER
Also after the user adds something to the jtable, I can resize the dialog box and it updates the table
If you see the change only after you do resize - it means you need to add repaint() in your code after you made the change
and then you should not need to resize to see the change.
Beciuse that is the reason you see it after resize - it does repaint() when resizing
and then you should not need to resize to see the change.
Beciuse that is the reason you see it after resize - it does repaint() when resizing
>we have and I still can not get it to work
You need to understand how these interactions wroek - I;d even suggest that you
for a time loook at some very simple exmples of interactions between class through these handles - this
is a very importnat part and you need to understand it.
I don't rememeber was it for you that I made this simple example with three windows - one main and two children passing references to each other.
If that was not for you i can post it for you - and try to understand how these interactions work - it is very importnat for any java work
With something like this it's very difficult to help without runnable code
ASKER
Even though I now know you don't think it will not fix my issue, I would love to learn how to merge those two classes using simpleton - I am curious now
>With something like this it's very difficult to help without runnable code
I very much agree. And it does not look like this is some classical case for singleton.
Your case is not that you cannot have two imnstances of some entity, but rather
that you want to be sure to access this very instance which you need from another place
in your code.
And merging classes does not have direct effect on the flow of operation - you can put bunch of methods in one class or in
different classes - the way your program operates will not necessarily depend on that.
I very much agree. And it does not look like this is some classical case for singleton.
Your case is not that you cannot have two imnstances of some entity, but rather
that you want to be sure to access this very instance which you need from another place
in your code.
And merging classes does not have direct effect on the flow of operation - you can put bunch of methods in one class or in
different classes - the way your program operates will not necessarily depend on that.
ASKER
OK - I understand about the runnable code.
I would suggest that in a spare moment you look at this ismple example of how
classes intreact with each other - you can compile and see
how parent window intercats with childeren and chikldern with each other and look
at the ccode - in this cvase they represent framses - but this intercation throough
the handles between the classes in java application can work the same way between any classes,
not necessarily corresponding to visual elements
and it shows how in another class you can reach the same instance of some class
which you creted in the third class.
These things need to be understood clearly, then you'll be able to update
the table you created somewhere form another location in your application.
If you don't uinderstand this stuff, ask questions, it is really important.
classes intreact with each other - you can compile and see
how parent window intercats with childeren and chikldern with each other and look
at the ccode - in this cvase they represent framses - but this intercation throough
the handles between the classes in java application can work the same way between any classes,
not necessarily corresponding to visual elements
and it shows how in another class you can reach the same instance of some class
which you creted in the third class.
These things need to be understood clearly, then you'll be able to update
the table you created somewhere form another location in your application.
If you don't uinderstand this stuff, ask questions, it is really important.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyMainWindow extends JFrame implements ActionListener {
JTextField txt;
JButton button;
MyChildWindow child1;
MyChildWindow child2;
public MyMainWindow(){
super("main");
txt = new JTextField(10);
button = new JButton("press");
button.addActionListener(this);
Container c = this.getContentPane();
c.setLayout(new FlowLayout());
c.add(txt);
c.add(button);
this.setSize(200,200);
this.setLocation(100, 100);
child1 = new MyChildWindow(this, 1);
child2 = new MyChildWindow(this,2);
child1.setVisible(true);
child2.setVisible(true);
this.setVisible(true);
}
public void setText(String s){
txt.setText(s);
}
public void actionPerformed(ActionEvent e) {
child1.setText(txt.getText());
child2.setText(txt.getText());
}
public MyChildWindow getChild(int i){
if(i==1)return child1;
else return child2;
}
public static void main(String[] args) {
new MyMainWindow();
}
}
class MyChildWindow extends JFrame implements ActionListener {
MyMainWindow parent;
JTextField txt;
JButton button;
int num;
public MyChildWindow(MyMainWindow parent, int num){
super("child " + num );
this.parent = parent;
this.num = num;
txt = new JTextField(10);
button = new JButton("press");
button.addActionListener(this);
Container c = this.getContentPane();
c.setLayout(new FlowLayout());
c.add(txt);
c.add(button);
this.setSize(200,200);
this.setLocation(num*200, num*200);
}
public void setText(String s){
txt.setText(s);
}
public void actionPerformed(ActionEvent e) {
parent.setText(txt.getText());
MyChildWindow childNotMe = null;
if(num == 1){
childNotMe = parent.getChild(2);
} else childNotMe = parent.getChild(1);
childNotMe.setText(txt.getText());
}
}
ASKER
Can a singleton extend AbstractTableModel?
ASKER
I am being requested to create this singleton class. I do understand that it is too hard to help with the merging classes because of runnable code. But if someone could layout a simpleton class for me I will try and merge the code myself. The class will need to extend AbstractTableModel.
Thanks
Thanks
I think you can - this reposrts error when I try to instatiate directkly TestSingleton class
import javax.swing.table.AbstractTableModel;
import java.awt.*;
public class TestSingleton extends AbstractTableModel{
private static TestSingleton instance = null;
private TestSingleton() {
// Exists only to defeat instantiation.
}
public static TestSingleton getInstance() {
if(instance == null) {
instance = new TestSingleton();
}
return instance;
}
public int getRowCount(){ return 1; }
public int getColumnCount(){return 1;}
public Object getValueAt(int row, int column){return null;}
}
class Try {
public static void main(String[] args) {
TestSingleton ts = new TestSingleton(); // compilation error - cannot dierctly instantiatite
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for that!
Before when I was passing in my tablemodel it was like this
//SelectedTModel myModel;
SingletonSelectTable myModel;
////////////////////////// ////////// ////////// ////////// ////////// ////////
// //
// Constructor //
// //
////////////////////////// ////////// ////////// ////////// ////////// ////////
public EdiBaseDialog(Frame parent, TCSession theSession){
super(parent, false);
session = theSession;
//myModel = new SelectedTModel();
myModel = SingletonSelectTable.getIn stance();
createDialog();
} //end Constructor
then is the method to draw the table
selectTable = new JTable(myModel);
I am not getting anything to the table - You can see the old way using SelectdTModel - that worked what am I doing wrong?
Before when I was passing in my tablemodel it was like this
//SelectedTModel myModel;
SingletonSelectTable myModel;
//////////////////////////
// //
// Constructor //
// //
//////////////////////////
public EdiBaseDialog(Frame parent, TCSession theSession){
super(parent, false);
session = theSession;
//myModel = new SelectedTModel();
myModel = SingletonSelectTable.getIn
createDialog();
} //end Constructor
then is the method to draw the table
selectTable = new JTable(myModel);
I am not getting anything to the table - You can see the old way using SelectdTModel - that worked what am I doing wrong?
ASKER
THis is a static method now inside my new simpleton class
public static void add(TCComponentItemRevisio n tcRevision, TCComponentDataset selectedDataset){
RevDataset pp = new RevDataset(tcRevision,sele ctedDatase t);
if(!rds.contains(pp))rds.a dd(pp);
}
How can I add a fireTableDataChanged?
If I take away the static then i get a error on my ediHandler class
SingletonSelectTable.add(t cRevision, selectedDa taset); Says that is a static call
public static void add(TCComponentItemRevisio
RevDataset pp = new RevDataset(tcRevision,sele
if(!rds.contains(pp))rds.a
}
How can I add a fireTableDataChanged?
If I take away the static then i get a error on my ediHandler class
SingletonSelectTable.add(t
Did you populate
SingletonSelectTable
with your model?
Post both old SelectdTModel and new SingletonSelectTable
SingletonSelectTable
with your model?
Post both old SelectdTModel and new SingletonSelectTable
SingletonSelectTable.add(t
It is a static call.
You need to create insance of SingletonSelectTable and use everywhere this iinstance
the same way you use instance myModel = new SelectedTModel();
So you should say:
myModel = SingletonSelectTable.getIn
and then
myModel.add(....)
The only thing changed is the way you obtain initially instance
of myModel - you dodn't cconstruct it with constructor but rather
cretd it with getInstance() - this is the only difference
I think you even don't need to change the name - just modify
this class like below (I marked after // added parts) and replace
SelectedTModel myModel = new SelectedTModel ()
with
SelectedTModel myModel = SelectedTModel.getInstance ();
this class like below (I marked after // added parts) and replace
SelectedTModel myModel = new SelectedTModel ()
with
SelectedTModel myModel = SelectedTModel.getInstance
public class SelectedTModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private ArrayList<RevDataset> aList;
private static SelectedTModel instance = null; //add this varaible
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;
public static SelectedTModel getInstance() { //add thi method
if(instance == null) {
instance = new SelectedTModel ();
}
return instance;
}
//////////////////////////////////////////////////////////////////////////
// //
// Constructor //
// //
//////////////////////////////////////////////////////////////////////////
private SelectedTModel() { //change constructir to privatae
super();
this.aList = EdiSelection.rds;
} // 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(int row) {
boolean b = (aList.remove(row) != null);
//fireTableDataChanged();
fireTableRowsDeleted(row, row);
}
}//end SelectedTModel
ASKER
Here is my singleton class - This class is creating my ArrayList as well as my TableModel. I am no longer using EdiSelection class or SelectedTModel class
This is the EdiHandler Class - This class is where I am calling the add function from the singleton Class
this is how I am trying to call the add
Does this look right? Do I still need to create that instance in the constructor?
In my EdiBaseDialog Class I an doing it different
Which way it correct - if any?
public class SingletonSelectTable extends AbstractTableModel{
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;
static ArrayList<RevDataset> rds = new ArrayList<RevDataset>();
private static SingletonSelectTable instance = null;
//////////////////////////////////////////////////////////////////////////
// //
// Constructor //
// //
//////////////////////////////////////////////////////////////////////////
private SingletonSelectTable() {
}
public static SingletonSelectTable getInstance() {
if(instance == null) {
instance = new SingletonSelectTable();
}
return instance;
}
//////////////////////////////////////////////////////////////////////////
// //
// getRowCount() //
// //
//////////////////////////////////////////////////////////////////////////
public int getRowCount() {
return rds.size();
} // end getRowCount()
//////////////////////////////////////////////////////////////////////////
// //
// getColumnCount() //
// //
//////////////////////////////////////////////////////////////////////////
public int getColumnCount() {
return MAX_COLUMNS;
} // end getColumnCount()
//////////////////////////////////////////////////////////////////////////
// //
// getValueAt() //
// //
//////////////////////////////////////////////////////////////////////////
public Object getValueAt(int row, int column){
Object o = null;
try {
switch (column) {
case ITEMID_COL: { o = rds.get(row).rev.getItem().getStringProperty("item_id"); break; }
case REVID_COL: { o = rds.get(row).rev.getStringProperty("item_revision_id"); break; }
case PRL_COL: { o = rds.get(row).rev.getRelatedComponent("IMAN_master_form_rev").getStringProperty("PRL"); break; }
case DATASETNAME_COL: { o = rds.get(row).componentdataset.getStringProperty("object_string"); break; }
case DATASET_COL: { o = rds.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(int row) {
boolean b = (rds.remove(row) != null);
fireTableRowsDeleted(row, row);
}
//////////////////////////////////////////////////////////////////////////
// //
// add() //
// //
//////////////////////////////////////////////////////////////////////////
public static void add(TCComponentItemRevision tcRevision, TCComponentDataset selectedDataset){
//rds.add(new RevDataset(tcRevision,selectedDataset));
//System.out.println("Key :" + tcRevision.toString() + " Value : " + selectedDataset.toString() + " \n");
RevDataset pp = new RevDataset(tcRevision,selectedDataset);
if(!rds.contains(pp))rds.add(pp);
//fireTableDataChanged();
}// end add
//////////////////////////////////////////////////////////////////////////
// //
// getList() //
// //
//////////////////////////////////////////////////////////////////////////
public static ArrayList<RevDataset> getList(){
return rds;
}// end GetList
//////////////////////////////////////////////////////////////////////////
// //
// clearList() //
// //
//////////////////////////////////////////////////////////////////////////
public static ArrayList<RevDataset> clearList(){
rds.clear();
return rds;
}// end GetList
}//end SingletonSelectTable
This is the EdiHandler Class - This class is where I am calling the add function from the singleton Class
public class EdiHandler extends AbstractHandler {
/* The constructor */
public EdiHandler() {
//EdiSelection es = new EdiSelection();
SingletonSelectTable sst = SingletonSelectTable.getInstance();
}
this is how I am trying to call the add
SingletonSelectTable.add(tcRevision,selectedDataset);
Does this look right? Do I still need to create that instance in the constructor?
In my EdiBaseDialog Class I an doing it different
public class EdiBaseDialog extends AbstractAIFDialog {
SingletonSelectTable myModel;
//////////////////////////////////////////////////////////////////////////
// //
// Constructor //
// //
//////////////////////////////////////////////////////////////////////////
public EdiBaseDialog(Frame parent, TCSession theSession){
super(parent, false);
session = theSession;
//myModel = new SelectedTModel();
myModel = SingletonSelectTable.getInstance();
createDialog();
} //end Constructor
Which way it correct - if any?
ASKER
I think I everything working but really need a answer to the above question. What is the correct place to create the instance of the Singleton Class
Right Now I am doing it like the EdiBaseDialog from above
Right Now I am doing it like the EdiBaseDialog from above
This is OK place to create instance - just where you where doing it through constructor (with new) before
myModel = SingletonSelectTable.getIn
And the advantage of singleton is that you can call the same getInstance in another place like EdiHandler
and may be sure that you get the reference to the same instance.