菜单创建
创建菜单,首先要创建一个菜单栏:
JMenuBar menuBar = new JMenuBar()
菜单栏可以添加到任何位置。通常放置在框架顶部。可以调用setJMenuBar()方法将菜单栏添加到框架上:frame.setJmenuBar(menuBar)
为每个菜单建立一个菜单对象:
JMenu editMenu = new Jmenu("Edit");
然后将菜单添加到菜单栏中:
menuBar.add(editMenu);
向菜单对象中添加菜单项、分隔符和子菜单:
JmenuItem pasteItem = new JMenuItem("Paste");
editMenu.add(pasteItem);
editMenu.addSeparator();
JMenu optionsMenu = ...;
editMenu.add(optionsMenu);
当用户选择菜单时,将触发一个动作事件。这里需要为每个菜单项安装一个动作监听器。
ActionListener listener = ...;
pasteItem.addActionListener(listener);
可以使用JMenu.add(String s)方法将菜单项插入到菜单的尾部:
editMenu.add("Paste");
Add方法返回创建的子菜单项。可以用下列方式获取它,并添加监听器:
JMenuItem pasteItem = editMenu.add("Paste");
paste.addActionListener(Listener);
通过采用扩展抽象类AbstractAction来定义一个实现的Action接口的类。需要在AbstractAction对象的构造器中指定菜单项标签并且覆盖actionPerformed方法来获得菜单动作处理器。
Action exitAction = new AbstractAction("Exit")
{
public void actionPerformed(ActionEvent event)
{
action code goes here
System.exit(0);
}
};
然后将动作添加到菜单中:
JMenuItem exitItem = fileMenu.add(exitAction);
这个命令利用动作名将一个菜单项添加到菜单中。上面的语句是下面的语句的快捷方式:
JMenuItem exitItem = new JMenuItem(exitAction);
fileMenu.add(exitItem);
JMenu(String label)
用给定的标签构造一个菜单JMenuItem add(JMenuItem item)
添加一个菜单项(或一个菜单)JMenuItem add(String label)
用给定的标签将一个菜单项添加到菜单中。并返回这个菜单项JMenuItem add(Action a)
用给定的一个动作将一个菜单添加到菜单中,并返回这个菜单项void addSeparator()
将一个分割符行添加到菜单中JMenuItem insert(JMenuItem menu, int index)
将一个新菜单项添加到菜单的指定位置JMenuItem insert(Action a, int index)
用给定动作在菜单的指定位置添加一个新的菜单项void insertSeparator(int index)
将一个分隔符添加到菜单中
index : 添加分隔符的位置void remove(int index)
void remove(JMenuItem item)
从菜单中删除指定的菜单项JMenuItem(String label)
用给定的标签构造一个菜单项JMenuItem(Action a)
为给定动作构造一个菜单项void setAction(Action a)
为这个按钮或菜单设置动作void setJMenuBar(JMenuBar menuBar)
为这个框架设置菜单栏
菜单项中的图标
菜单可以利用JMenuItem类中的setIcon方法指定一个图标:
JMenuItem cutItem = new JMenuItem("Cut", new ImageIcon("cut.gif"));
默认情况下,菜单项的文本被放置在图标的右侧。如果要文本放置在左侧,可以调用JMenuItem类中的setHorizontalTextPosition方法设置:
cutItem.setHorizontalTextPosition(SwingConstants.LEFT); //把菜单项文本移动到图标的左侧
也可以将图标添加到一个动作上:
cutAction.putValue(Action.SMALL_ICON, new ImageIcon("cut.gif"));
当使用动作构造菜单项时,Action.NAME值将会作为菜单项的文本,而Action.SMALL_ICON将会作为图标。
还可以用AbstractAction构造器设置图标:
cutAction = new AbstractAction("Cut", new ImageIcon("cut.gif"))
{
public void actionPerformed(ActionEvent event)
{
...
}
}
JMenuItem(String label, Icon icon)
用给定的标签和图标构造一个菜单项void setHorizontialTextPosition(int pos)
设置文本对应图标的水平位置
pos : SwingConstants.RIGHT(文本在图标的右侧)或SwingConstants.LEFTAbstractAction(String name, Icon smallIcon);
用给定的名字和图标构造一个抽象的动作
复选框和单选按钮菜单项
复选框和单选按钮菜单项在文本旁边显示额一个复选框或一个单选按钮。当用户选择一个菜单项时,菜单项会自动的在选择和未选择间进行切换。
下面创建复选框:
JCheckBoxMenuItem readonlyItem = new JCheckBoxMenuItem("Read-only");
optionsMenu.add(readonlyItem);
单选按钮菜单项与普通单选按钮的工作方式一样,必须将他们加入到按钮组中。当按钮组中的一个按钮被选中时,其他按钮都自动地变为为选择项。
ButtonGroup group = new ButtonGroup();
JRadioButtonMenuItem insertItem = new JRadioButtonMenuItem("Insert");
insertItem.setSelected(true); //设置菜单项的当前状态
JRadioButtonMenuItem overtypeItem = new JRadioButtonMenuItem("Overtype");
group.add(insertItem);
group.add(overtypeItem);
optionsMenu.add(insertItem);
optionsMenu.add(overtypeItem);
JCheckBoxMenuItem(String label)
用给定的标签构造一个复选框菜单项JCheckBoxMenuItem(String label, boolean state);
用给定的标签和给定的初始状态构造一个复选框菜单JRadioButtonMenuItem(String label)
用给定的标签构造一个单选按钮菜单项JRadioButtonMenuItem(String label, boolean state)
用给定的标签和给定的状态构造一个单选按钮菜单项boolean isSelected()
测试菜单项的当前状态void setSelected(boolean state)
获取或设置这个菜单的选择状态
弹出菜单
不固定在菜单栏中随处浮动过得菜单。
创建方法和常规菜单类似,但是弹出菜单没有标题:
JPopupMenu popup = new JPopupMenu();
然后用常规的方法添加菜单项:
JMenuItem item = new JMenuItem("Cut");
item.addActionListener(listener);
popup.add(item);
弹出的菜单需要使用show方法才能显示出来。调用时需要给出父组件以及父组件坐标的显示位置:
popup.show(panel, x, y);
弹式触发器:当用户点击某个鼠标键时弹出菜单:
component.setComponentPopupMenu(popup);
当弹出菜单的组件中放置一个组件的情况。这个子组件可以调用下面方法继承父组件的弹出菜单:
child.setInheritsPopupMenu(true);
-
void show(Component panel, int x, int y)
显示一个弹出菜单
panel : 显示弹出菜单的组件
x, y :弹出菜单左上角的坐标(panel 的坐标空间内) -
boolean isPopupTrigger(MouseEvent event)
如果鼠标事件是弹出菜单触发器,则返回true -
boolean isPopupTrigger()
如果鼠标事件是弹出菜单触发器,则返回true -
void setComponentPopupMenu(JPopupMenu popup)
获取或设置用于这个组件的弹出菜单 -
void setInheritsPopupMenu(boolean b)
获取或设置 inheritsPopupMenu 特性。如果这个特性被设置或这个组件的弹出菜单为null,则应用上一级弹出菜单。
快捷键和加速器
可以通过在菜单项的构造器中指定一个快捷字母来为菜单项设置快捷键:
JMenuItem aboutItem = new JMenuItem("About", 'A');
快捷键会自动地显示在菜单项中,并带有一条下划线。
有时候不需要在菜单项的第一个快捷键字母下面加下划线。可以指定setDisplayedMnemonicIndex 方法指定希望加下划线的字符。
如果有一个Action对象,就可以把快捷键作为Action.MNEMONIC_KEY的键值添加到对象中:
cutAction.putValue(Action.MNEMONIC_KEY, new Integer('A'));
只能在菜单项的构造器中设定快捷字母,而不是在菜单构造器中。如果想为菜单设置快捷键,需要调用setMnemonic方法:
JMenu helpMenu = new JMenu("help");
helpMenu.setMnenonic('H');
可以同时按下ALT键和菜单的快捷键来实现在菜单栏中选择一个顶层菜单的操作。
可以使用快捷键从当前打开的菜单中选择一个子菜单或菜单项。而加速器是在不打开菜单的情况下选择菜单项的快捷键。可以使用setAccelerator将加速器键关联到一个菜单项上。
openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl 0"));
当用户按下加速器组合键时,就会自动地选择相应的菜单项,同时激活一个动作事件。加速器只能关联到菜单项上,不能关联到菜单上。加速器键并不实际打开菜单,直接激活菜单关联的动作事件。
JMenuItem(String label, int mnemonic)
用给定的标签和快捷键字符构造一个菜单项
label :菜单项的标签
mnemonic : 菜单项的快捷键字符,在标签中这个字符下面会有一个下划线。void setAccelerator(KeyStroke k)
将k设置为这个菜单项的加速器,加速器显示在标签的旁边void setMnemonic(int mnemonic)
设置按钮的快捷字符,该字符会在标签中以下划线的形式显示void setDisplayedMnemonicIndex(int index);
将按钮文本中的index字符设定为带下划线。如果不希望第一个出现的快捷键字符待下划线,就可以使用这个方法
启用和禁用菜单项
启用或禁用菜单项需要调用setEnabled方法:saveItem.setEnabled(false)
有两种策略:
- 每次环境发生变化就对相关的菜单项或动作调用setEnabled。
- 在显示菜单之前禁用这写菜单项。(不适用于带有加速键的菜单项。因为在按下加速键时并没有打开菜单,所以动作并没有被禁用)包含三个方法:
void menuSelected(MenuEvent event)
void menuDeselected(MenuEvent event)
void menuCanceled(MenuEvent event)
下面代码显示了只读复选框菜单项被选择后,如何禁用Save和Save As动作。
public void menuSelected(MenuEvent event)
{
saveAction.setEnabled(!readonlyItem.isSelected());
saveAction.setEnabled(!readonlyItem.isSelected());
}
void setEnabled(boolean b)
启用或禁用菜单项void menuSelected(MenuEvent e)
在菜单被选择但尚未打开之前调用void menuDeselected(MenuEvent e)
在菜单被取消并且已经关闭后被调用void menuCanceled(MenuEvent e)
当菜单被取消时被调用
package menu;
import java.awt.event.*;
import javax.swing.*;
public class MenuTest extends JFrame{
private static final long serialVersionUID = 1L;
public static void main(String[] args){
MenuTest menuTest = new MenuTest();
menuTest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menuTest.setVisible(true);
}
private static final int DEFAULT_WIDTH = 500;
private static final int DEFAULT_HEIGHT = 300;
private Action saveAction;
private Action saveAsAction;
private JCheckBoxMenuItem readonlyItem;
private JPopupMenu popup;
class TestAction extends AbstractAction{
private static final long serialVersionUID = 1L;
public TestAction(String name){
super(name);
}
public void actionPerformed(ActionEvent event){
System.out.println(getValue(Action.NAME) + " selected.");
}
}
public MenuTest(){
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
/**
* 创建 File 菜单
*/
JMenu fileMenu = new JMenu("File");
fileMenu.add(new TestAction("New"));
JMenuItem openItem = fileMenu.add(new TestAction("Open")); // File 菜单下添加 Open 菜单项
openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl 0")); // 使用加速器键快速打开 Open 菜单项
fileMenu.addSeparator(); //添加一行分割线
saveAction = new TestAction("Save");
JMenuItem saveItem = fileMenu.add(saveAction); //将动作事件添加到菜单项中
saveItem.setAccelerator(KeyStroke.getKeyStroke("ctrl 5")); //将加速器键与之绑定
saveAsAction = new TestAction("Save As");
fileMenu.add(saveAsAction); //将 Save As 添加到 File 菜单中
fileMenu.addSeparator(); // 添加一行分割线
fileMenu.add(new AbstractAction("Exit"){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
readonlyItem = new JCheckBoxMenuItem("Read-Only"); //创建复选框
readonlyItem.addActionListener(new ActionListener(){ //监听事件
public void actionPerformed(ActionEvent event){ //做出响应
boolean saveOk = ! readonlyItem.isSelected(); //获取当前菜单状态的相反状态
//根据前面的状态来启用或禁用菜单项
saveAction.setEnabled(saveOk);
saveAsAction.setEnabled(saveOk);
}
});
/**
* 创建一组按钮
*/
ButtonGroup group = new ButtonGroup();
JRadioButtonMenuItem insertItem = new JRadioButtonMenuItem("Insert");
insertItem.setSelected(true); //设置该按钮已经被选
JRadioButtonMenuItem overtypeItem = new JRadioButtonMenuItem("Overtype");
group.add(insertItem);
group.add(overtypeItem);
/**
* 给动作按钮添加图标
*/
Action cutAction = new TestAction("Cut");
cutAction.putValue(Action.SMALL_ICON, new ImageIcon("cut.gif"));
Action copyAction = new TestAction("Copy");
copyAction.putValue(Action.SMALL_ICON, new ImageIcon("copy.gif"));
Action pasteAction = new TestAction("Paste");
pasteAction.putValue(Action.SMALL_ICON, new ImageIcon("paste.gif"));
/**
* 创建 Edit 菜单
*/
JMenu editMenu = new JMenu("Edit");
editMenu.add(cutAction);
editMenu.add(copyAction);
editMenu.add(pasteAction);
/**
* 创建 Options 菜单
*/
JMenu optionMenu = new JMenu("Options");
optionMenu.add(readonlyItem);
optionMenu.addSeparator(); //将分割符添加到菜单中
optionMenu.add(insertItem);
optionMenu.add(overtypeItem);
editMenu.addSeparator();
editMenu.add(optionMenu);
/**
* 创建 Help 菜单
*/
JMenu helpMenu = new JMenu("Help");
helpMenu.setMnemonic('H'); //设置快捷键
JMenuItem indexItem = new JMenuItem("Index"); //创建 Index 菜单项
indexItem.setMnemonic('I'); //为该菜单项设置快捷键
helpMenu.add(indexItem); //将 Index 菜单项添加到 Help 菜单中
//为动作Action添加快捷键
Action aboutAction = new TestAction("About");
aboutAction.putValue(Action.MNEMONIC_KEY, Integer.valueOf('A'));
helpMenu.add(aboutAction); //将 About 菜单项添加到 Help 菜单中
JMenuBar menuBar = new JMenuBar(); //设置一个菜单栏
setJMenuBar(menuBar); //将菜单栏放置到框架上
//将菜单项添加到菜单栏上
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(helpMenu);
//创建弹出菜单
popup = new JPopupMenu();
popup.add(cutAction);
popup.add(copyAction);
popup.add(pasteAction);
//在空白面板上点击鼠标键时弹出菜单
JPanel panel = new JPanel();
panel.setComponentPopupMenu(popup);
add(panel);
panel.addMouseListener(new MouseAdapter() {});
}
}
工具栏
工具栏特殊之处在于它可以随处移动,可以把它拖拽到框架的四个边框上。
工具栏只有位于采用边框布局或任何支持North,East,South 和 West约束布局的管理器的容器内才能被拖拽。
工具栏可以完全脱离框架,这样工具栏将会包含在自己的框架中,当关闭包含工具栏的框架时,它会回到原始的框架中。
下面是创建工具栏的代码,并将组件添加到工具栏中:
JToolBar bar = new JToolBar();
bar.add(blueButton);
//也可以用Action对象
bar.add(blueAction);
可以用分割符将按钮分组:
bar.setSeparator();
最后,把工具栏添加到框架中:
add(bar, BorderLayout.NORTH);
当工具栏没有停靠时也可以指定工具栏的标题:
bar = new JToolBar(titleSring);
在默认情况下,工具栏最初是水平的。如果想要垂直放置,可以使用下面代码:
bar = new JToolBar(SwingConstants.VERTICAL);
或者
bar = new JToolBar(titleString, SwingConstants.VERTICAL);
工具提示
当光标放在工具栏某个按钮上片刻时,工具提示就会被激活。工具提示的文本显示在一个有颜色的矩形里。当用户移开光标时,工具提示会自动的消失。
在Swing中,可以使用setToolText方法将工具提示添加到JComponent上:
exitButton.setToolTipText("Exit");
另一种方法,如果使用Action对象,就可以使用SHORT_DESCRIPTION关联工具提示:
exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit");
package toolBar;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ToolBarFrame extends JFrame{
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
ToolBarFrame frame = new ToolBarFrame();
frame.setTitle("ToolBarTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static final int DEFAULT_WIDTH = 700;
private static final int DEFAULT_HEIGHT = 500;
private JPanel panel;
public ToolBarFrame(){
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
panel = new JPanel();
add(panel, BorderLayout.CENTER);
/**
* 创建三个动作事件,每个事件对应一种颜色
*/
Action blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE);
Action yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"), Color.YELLOW);
Action redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED);
//创建退出按钮,退出程序
Action exitAction = new AbstractAction("Exit", new ImageIcon("exit.gif")){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
};
exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit"); //鼠标悬停显示描述内容
/**
* 创建工具栏
*/
JToolBar bar = new JToolBar();
bar.add(blueAction);
bar.add(yellowAction);
bar.add(redAction);
bar.addSeparator();
bar.add(exitAction);
add(bar, BorderLayout.NORTH);
/**
* 创建 Color 菜单,并把按钮添加
*/
JMenu menu = new JMenu("Color");
menu.add(blueAction);
menu.add(yellowAction);
menu.add(redAction);
menu.add(exitAction);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
setJMenuBar(menuBar);
}
class ColorAction extends AbstractAction{
private static final long serialVersionUID = 1L;
//初始化按钮的名称,图标,提示
public ColorAction(String name, Icon icon, Color c){
putValue(Action.NAME, name);
putValue(Action.SMALL_ICON, icon);
putValue(Action.SHORT_DESCRIPTION, name + " background");
putValue("Color", c);
}
public void actionPerformed(ActionEvent event){
Color c =(Color) getValue("Color");
panel.setBackground(c);
}
}
}