patternjavaMinor
GUI design in Java Swing
Viewed 0 times
swingdesignguijava
Problem
I am developing a GUI using Swing, but before my project gets too complex. I would like to have a good design structure. I have a few ideas and will use a simple example to illustrate. Some feedback on whether or not this is a good approach would be great.
This is what my GUI looks like:
There are 2 Jpanels
My approach for this is:
-
If a component is used more than once, I write a class(
-
I write a class for each panel. As the project gets bigger, the JFrame class won't get too cluttered and changes to a panel won't affect the JFrame class.
Here is the code:
LeftPanel
RightPanel
```
public class RightPanel extends JPanel implements ActionListener{
JLabel name = new JLabel("bar");
GetNameButton gnb = new GetNameButton();
public RightPanel(){
this.setLayout(null)
This is what my GUI looks like:
There are 2 Jpanels
LeftPanel and RightPanel. When Show Name is clicked the name in that panel pops up.My approach for this is:
-
If a component is used more than once, I write a class(
GetNameButton,NameLabel).-
I write a class for each panel. As the project gets bigger, the JFrame class won't get too cluttered and changes to a panel won't affect the JFrame class.
Here is the code:
public class MyFrame extends JFrame{
public MyFrame(){
this.setLayout(null);
this.setBounds(100,100,400,400);
this.add(new LeftPanel());
this.add(new RightPanel());
this.setVisible(true);
}
public static void main(String[] args) {
new MyFrame();
}
}LeftPanel
public class LeftPanel extends JPanel implements ActionListener{
CloseButton cb = new CloseButton();
JLabel name = new JLabel("foo");
GetNameButton gnb = new GetNameButton();
public LeftPanel(){
this.setLayout(null);
this.setBounds(20, 20, 160, 320);
this.setBorder(new SoftBevelBorder(BevelBorder.RAISED, null, null, null, null));
this.add(new NameLabel());
name.setBounds(50,10,40,10);
this.add(name);
this.add(cb);
this.add(gnb);
gnb.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==gnb){
JOptionPane.showMessageDialog(null, name.getText());
}
}
}RightPanel
```
public class RightPanel extends JPanel implements ActionListener{
JLabel name = new JLabel("bar");
GetNameButton gnb = new GetNameButton();
public RightPanel(){
this.setLayout(null)
Solution
-
Variable names. Imagine yourself a couple of months from now on, when you look back at the code. Will you remember without looking at the variable declaration what
-
You seem to use
-
You seem to
Here's code for such a
-
jliv902 has a good point in his comment of putting common features into a base class for your panels. However, think about whether or not you really should extend them or not. Personally I think that extending a
If you would write a class like that, it will encapsulate the
Variable names. Imagine yourself a couple of months from now on, when you look back at the code. Will you remember without looking at the variable declaration what
gnb is short for? I suggest you use longer variable names so that you even won't have to try to remember it. getNameBtn would be a better name, and it's still not too long. Using closeBtn instead of cb is also better. cb could just as well mean clearbright or something else totally irrelevant.-
You seem to use
setBounds to set the exact layout positions in pixels for your components. This is not recommended as this will not be flexible for resizing the windows. Instead use a proper LayoutManager such as BorderLayout and add some margins to make your buttons be placed approximately where they belong and still be flexible for if someone wants to resize the window. (Trust me, this can be more important than you think).-
You seem to
extend a lot of JButtons and other things. Technically, what's different between a CloseButton and a GetNameButton? The only differences are their positions, labels and I suppose there will be a difference in what happens when you click them. All these things are properties, it does not warrant extension of the original class. Instead you can use a public static method that creates a JButton with the initialized properties of a "close-button" or a "get-name-button". (The same goes for NameLabel, it does not need to extend JLabel)Here's code for such a
public static method:public static JButton createGetNameButton() {
JButton btn = new JButton();
btn.setText("Show Name");
btn.setBounds(20,100,120,20);
return btn;
}-
jliv902 has a good point in his comment of putting common features into a base class for your panels. However, think about whether or not you really should extend them or not. Personally I think that extending a
JPanel or a JFrame is more OK than extending a button, but I want you to know that there are even reasons for why a JFrame shouldn't be extended. Instead of extending, consider this:public class MyJPanelContainer implements ActionListener {
private final JPanel panel;
public MyJPanelContainer() {
this.panel = new JPanel();
// code to setup the panel the way you want it
someComponent.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
// ...
}
public JPanel getPanel() {
// Technically, in another approach, you might not even need this getter, but that's a whole other story.
return this.panel;
}
}If you would write a class like that, it will encapsulate the
JPanel and thus hide several methods. The easiest effect to describe for using this approach is that it will drastically decrease the number of visible elements when you press Ctrl + Space, which will make it easier to see the method you are looking for.Code Snippets
public static JButton createGetNameButton() {
JButton btn = new JButton();
btn.setText("Show Name");
btn.setBounds(20,100,120,20);
return btn;
}public class MyJPanelContainer implements ActionListener {
private final JPanel panel;
public MyJPanelContainer() {
this.panel = new JPanel();
// code to setup the panel the way you want it
someComponent.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
// ...
}
public JPanel getPanel() {
// Technically, in another approach, you might not even need this getter, but that's a whole other story.
return this.panel;
}
}Context
StackExchange Code Review Q#36220, answer score: 5
Revisions (0)
No revisions yet.