S
Shawn
I have finished my little gui program. Code is pasted below. Two things
I feel proud about my code:
(1)I wrote one class JMenuPower, subclass of JMenu. I can put objects of
JMenuItem, which will 1)automatically register ActionListener to "this"
object 2)setActionCommand to the String parameter passed in 3)put both
the actionCommand string and the Mapper reference into a HashMap for
later retrieval.
In conclusion, my JMenuPower class is in higher level than JMenu class.
JMenu class is like primitive class for me now.
So my brain can have less burden.
(2)When user clicks the different Menu Item, the corresponding operation
is evoked dynamically. I achieved this goal by using an interface
Mapper. So if I need to add one Menu Item, I only need to do two things:
a)
MenuItem m = new JMenuItem("new one");
memoMenu.addMenuItemAndListener(m, "newone", newoneMapper,
this); //throw it into my JMenuPower object, which takes care of the rest
b) //write the Maper do what I want to do
Mapper newoneMapper = new Mapper()
{
public void menuItemAction()
{
//put code here
}
};
Do you think I am twisting too much or I am doing correct thing?
Thank you very much for your feedback.
===============JMenuPower.java==============
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/****************************************************************************************
* My class extends from JMenu: the objects of JMenuItem can be added
into the object of
* this class. It will automatically register the actionlistener so the
lines in the client
* class is reduced and concept is clearer: add the menu item and
register the action listener.
* In another words, JMenuPower class is higher level than JMenu class now.
*
*/
public class JMenuPower extends JMenu
{
private Map<String, Mapper> myActions = new HashMap<String,
Mapper>(); //hold the String and its corresponding Mapper (different
action)
public JMenuPower(String s)
{
super(s);
}
void addMenuItemAndListener(JMenuItem mi, ActionListener al)
{
mi.addActionListener(al);
this.add(mi);
}
void addMenuItemAndListener(JMenuItem mi, String str, Mapper
mapper, ActionListener al)
{
mi.addActionListener(al);
mi.setActionCommand(str);
this.add(mi);
myActions.put(str, mapper);
}
public Mapper getActionMapper(String str)
{
return myActions.get(str);
}
}
=================MemoGui3.java======================
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;
interface Mapper {
public void menuItemAction();
}
public class MemoGUI3 extends JFrame implements ActionListener
{
public static final int WIDTH = 600;
public static final int HEIGHT = 300;
public static final int LINES = 10;
public static final int CHAR_PER_LINE = 40;
private JTextArea theText;
private String memo1 = "No Memo 1";
private String memo2 = "No Memo 2";
JMenuPower memoMenu;
public MemoGUI3()
{
this.setSize(WIDTH, HEIGHT);
this.addWindowListener(new WindowDestroyer());
this.setTitle("Memo Saver");
Container contentPane = this.getContentPane();
contentPane.setLayout(new BorderLayout());
memoMenu = new JMenuPower("Memos"); //my own JMenuPower class
JMenuItem m;
//Just throw the Menu Item object into the object of JMenuPower
class. It will take care of the rest:
m = new JMenuItem("Save Memo 1");
memoMenu.addMenuItemAndListener(m, "save1", save1Mapper, this);
m = new JMenuItem("Save Memo 2");
memoMenu.addMenuItemAndListener(m, "save2", save2Mapper, this);
m = new JMenuItem("Get Memo 1");
memoMenu.addMenuItemAndListener(m, "get1", get1Mapper, this);
m = new JMenuItem("Get Memo 2");
memoMenu.addMenuItemAndListener(m, "get2", get2Mapper, this);
m = new JMenuItem("Clear");
memoMenu.addMenuItemAndListener(m, "clear", clearMapper, this);
m = new JMenuItem("Exit");
memoMenu.addMenuItemAndListener(m, "exit", exitMapper, this);
JMenuBar mBar = new JMenuBar();
mBar.add(memoMenu);
this.setJMenuBar(mBar);
JPanel textPanel = new JPanel();
textPanel.setBackground(Color.blue);
theText = new JTextArea(LINES, CHAR_PER_LINE);
theText.setBackground(Color.white);
textPanel.add(theText);
contentPane.add(textPanel, BorderLayout.CENTER);
}
//this part of code never needs to be changed, even when a new Menu
Item needs to be added. I feel this is great:
public void actionPerformed(ActionEvent e)
{
String actionStr = e.getActionCommand();
(memoMenu.getActionMapper(actionStr)).menuItemAction();
}
//All the mess (the details of what the program should do when user
clicks the Menu Item) is pushed to here, -- the lowest level
//Mapper definitions
Mapper save1Mapper = new Mapper()
{
public void menuItemAction()
{
memo1 = theText.getText();
}
};
Mapper save2Mapper = new Mapper()
{
public void menuItemAction()
{
memo2 = theText.getText();
}
};
Mapper get1Mapper = new Mapper()
{
public void menuItemAction()
{
theText.setText(memo1);
}
};
Mapper get2Mapper = new Mapper()
{
public void menuItemAction()
{
theText.setText(memo2);
}
};
Mapper clearMapper = new Mapper()
{
public void menuItemAction()
{
theText.setText("");
}
};
Mapper exitMapper = new Mapper()
{
public void menuItemAction()
{
System.exit(0);
}
};
//end of Mapper definition block
public static void main(String[] args)
{
MemoGUI3 gui = new MemoGUI3();
gui.setVisible(true);
}
}
I feel proud about my code:
(1)I wrote one class JMenuPower, subclass of JMenu. I can put objects of
JMenuItem, which will 1)automatically register ActionListener to "this"
object 2)setActionCommand to the String parameter passed in 3)put both
the actionCommand string and the Mapper reference into a HashMap for
later retrieval.
In conclusion, my JMenuPower class is in higher level than JMenu class.
JMenu class is like primitive class for me now.
So my brain can have less burden.
(2)When user clicks the different Menu Item, the corresponding operation
is evoked dynamically. I achieved this goal by using an interface
Mapper. So if I need to add one Menu Item, I only need to do two things:
a)
MenuItem m = new JMenuItem("new one");
memoMenu.addMenuItemAndListener(m, "newone", newoneMapper,
this); //throw it into my JMenuPower object, which takes care of the rest
b) //write the Maper do what I want to do
Mapper newoneMapper = new Mapper()
{
public void menuItemAction()
{
//put code here
}
};
Do you think I am twisting too much or I am doing correct thing?
Thank you very much for your feedback.
===============JMenuPower.java==============
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/****************************************************************************************
* My class extends from JMenu: the objects of JMenuItem can be added
into the object of
* this class. It will automatically register the actionlistener so the
lines in the client
* class is reduced and concept is clearer: add the menu item and
register the action listener.
* In another words, JMenuPower class is higher level than JMenu class now.
*
*/
public class JMenuPower extends JMenu
{
private Map<String, Mapper> myActions = new HashMap<String,
Mapper>(); //hold the String and its corresponding Mapper (different
action)
public JMenuPower(String s)
{
super(s);
}
void addMenuItemAndListener(JMenuItem mi, ActionListener al)
{
mi.addActionListener(al);
this.add(mi);
}
void addMenuItemAndListener(JMenuItem mi, String str, Mapper
mapper, ActionListener al)
{
mi.addActionListener(al);
mi.setActionCommand(str);
this.add(mi);
myActions.put(str, mapper);
}
public Mapper getActionMapper(String str)
{
return myActions.get(str);
}
}
=================MemoGui3.java======================
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;
interface Mapper {
public void menuItemAction();
}
public class MemoGUI3 extends JFrame implements ActionListener
{
public static final int WIDTH = 600;
public static final int HEIGHT = 300;
public static final int LINES = 10;
public static final int CHAR_PER_LINE = 40;
private JTextArea theText;
private String memo1 = "No Memo 1";
private String memo2 = "No Memo 2";
JMenuPower memoMenu;
public MemoGUI3()
{
this.setSize(WIDTH, HEIGHT);
this.addWindowListener(new WindowDestroyer());
this.setTitle("Memo Saver");
Container contentPane = this.getContentPane();
contentPane.setLayout(new BorderLayout());
memoMenu = new JMenuPower("Memos"); //my own JMenuPower class
JMenuItem m;
//Just throw the Menu Item object into the object of JMenuPower
class. It will take care of the rest:
m = new JMenuItem("Save Memo 1");
memoMenu.addMenuItemAndListener(m, "save1", save1Mapper, this);
m = new JMenuItem("Save Memo 2");
memoMenu.addMenuItemAndListener(m, "save2", save2Mapper, this);
m = new JMenuItem("Get Memo 1");
memoMenu.addMenuItemAndListener(m, "get1", get1Mapper, this);
m = new JMenuItem("Get Memo 2");
memoMenu.addMenuItemAndListener(m, "get2", get2Mapper, this);
m = new JMenuItem("Clear");
memoMenu.addMenuItemAndListener(m, "clear", clearMapper, this);
m = new JMenuItem("Exit");
memoMenu.addMenuItemAndListener(m, "exit", exitMapper, this);
JMenuBar mBar = new JMenuBar();
mBar.add(memoMenu);
this.setJMenuBar(mBar);
JPanel textPanel = new JPanel();
textPanel.setBackground(Color.blue);
theText = new JTextArea(LINES, CHAR_PER_LINE);
theText.setBackground(Color.white);
textPanel.add(theText);
contentPane.add(textPanel, BorderLayout.CENTER);
}
//this part of code never needs to be changed, even when a new Menu
Item needs to be added. I feel this is great:
public void actionPerformed(ActionEvent e)
{
String actionStr = e.getActionCommand();
(memoMenu.getActionMapper(actionStr)).menuItemAction();
}
//All the mess (the details of what the program should do when user
clicks the Menu Item) is pushed to here, -- the lowest level
//Mapper definitions
Mapper save1Mapper = new Mapper()
{
public void menuItemAction()
{
memo1 = theText.getText();
}
};
Mapper save2Mapper = new Mapper()
{
public void menuItemAction()
{
memo2 = theText.getText();
}
};
Mapper get1Mapper = new Mapper()
{
public void menuItemAction()
{
theText.setText(memo1);
}
};
Mapper get2Mapper = new Mapper()
{
public void menuItemAction()
{
theText.setText(memo2);
}
};
Mapper clearMapper = new Mapper()
{
public void menuItemAction()
{
theText.setText("");
}
};
Mapper exitMapper = new Mapper()
{
public void menuItemAction()
{
System.exit(0);
}
};
//end of Mapper definition block
public static void main(String[] args)
{
MemoGUI3 gui = new MemoGUI3();
gui.setVisible(true);
}
}