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.
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()
;