Reputation: 175
I have a "standard" JPanel
with two panels inside. I was trying to create a kind of template class and then extend it and implement the content. The question is about which would be the way to implement it.
The code below is what I'm trying to make it work but I've just started to read the Effective Java book and I'm not familiar with static factory method. Specially trying to abstract them.
Some tips from the book that i'm trying to follow specially are
but I couldn't find out a good solution respecting these points (and without them :P).
public abstract class CentralPage {
static JPanel getInstance() {
JPanel container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = getUp(container);
container.add(up);
JPanel down = getDown(container);
container.add(down);
return container;
}
abstract JPanel getDown(JPanel container);
abstract JPanel getUp(JPanel container);
}
Feel free to ask if you need more information about other parts of code.
Upvotes: 0
Views: 2488
Reputation: 8803
My congratulations for reading "Effective Java" and trying to put it into practice. It will bring more usability and clearness to your code.
Now, let's see:
1.In the first place, if your abstraction CentralPage
just needs two Panel objects in the moment of construction, the simplest way would be a non-abstract class with two parameters in its constructor:
public class CentralPage
{
public CentralPage(Panel up, Panel dn)
{
...
}
}
2.If, appart from receiving parameters at construction, there is some behaviour which is not known to the CentralPage
and it must be delegated to a third party at any time within the object's lifecycle (after the constructor ended), the proper pattern would be an abstract class with one abstract method for each required behaviour:
public abstract class CentralPage
{
protected CentralPage(...)
{
...
}
protected abstract return-type myBehaviour1(parameters...)
{
...
}
protected abstract return-type myBehaviour2(parameters...)
{
...
}
}
And, of corse, each non-abstract subclass must provide each required behaviour implemeting its corresponding method.
3.Static factory methods are aimed to non-abstract classes. Its purpose is to decide if an object has to be created (maybe an existing object could be reused, like in the singleton pattern), and eventually to decide which class must be instantiated (maybe the owner class itself, or maybe some subclass).
Upvotes: 0
Reputation: 1112
A Java static method cannot be abstract -- longer discussion here.
Now let's break down your construction: your end result should be a JPanel
with two children, also JPanels
, whose own construction depends on the parent JPanel
. You would like this construction to be done in static factory method.
If that is correct, this could be a solution:
public interface UpDown{
public JPanel getUp(JPanel parent);
public JPanel getDown(JPanel parent);
}
public class CentralPage{
static JPanel getInstance(UpDown components){
JPanel container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = components.getUp(container);
container.add(up);
JPanel down = components.getDown(container);
container.add(down);
return container;
}
}
Another solution closer to your original proposal would be like this:
public abstract class CentralPage{
private static CentralPage page;
protected JPanel container;
protected CentralPage(){
container = new JPanel();
container.setBackground(Color.white);
container.setBorder(
BorderFactory.createCompoundBorder(new LineBorder(Color.BLACK), new EmptyBorder(10, 10, 10, 10)));
container.setMinimumSize(new Dimension(960, 400));
container.setPreferredSize(new Dimension(960, 400));
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JPanel up = getUp(container);
container.add(up);
JPanel down = getDown(container);
container.add(down);
}
static JPanel getInstance(){
if(page==null){
page=new CentralPage();
}
return page.getContainer();
}
abstract JPanel getDown(JPanel container);
abstract JPanel getUp(JPanel container);
protected JPanel getContainer(){
return this.container;
}
}
The downside to this (rather anti-pattern) approach is that you need to remember to create a constructor on your concrete class that calls super()
;
Upvotes: 3