GUI部分Java
Java我们之前接触的都是在控制台里面使用的,现在我们学到这一个就有了界面,有了窗口,窗口组件里面有容器、组件、版面处理以及事件与监听器。但是现实是这个已经淘汰好多年了,我们还是了解以下,方便以后前端设计思想。
1.组件简介
Java界面有两种架构awt和swing,swing是基于awt架构继承而来的。我们现在可以看看窗口设计组件:
java.awt.Component 或者 java.awt.MenuComponent包下,里面的组件都是窗口设计的子类别。
Compenent是Button、Lable、TextCompenent、Checkbox、Container等(文字编辑组的父类别)
MenuCompenent又是MenuBar(菜单列)、MenuItem(菜单项目)的父类别。
Container又是Component的子类别,可以容纳其他Component。awt里面还有Window、Panel等组件,awt现在很少有人直接使用,现在最多的是swing
swing继承了awt架构,其中,JComponent 里面有JLabal,JMenuItem等组件。Window有JFrame等组件,Panel等,我们现在开始进入。
2.设计方案
2.1 使用JFrame
我们先进行界面初始化:
import javax.swing.*;
public class Demo extends JFrame {
public Demo(){
setTitle("大型红娘公司创业基地");
setSize(500,400);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Demo();
}
}
首先我们要创建一个窗口,需要一个父类:JFrame。
JFrame来自javax.swing.*下面,需要导包。
我们看看里面的API:
setTitle表示设置标题,就是界面的标题。
setSize表示设置大小,参数是宽度和高度
setVisible表示是否可见,如果是false,就被隐藏了。
setResizable表示是否可以改变窗口大小,如果不想改变就设置为false
setDefaultCloseOperation表示关不关闭。JFrame里面的EXIT_ON_CLOSE表示点击X就可以关闭了,另外还有以下函数DO_NOTHING_ON_CLOSE什么也不做,HIDE_ON_CLOSE因此当前窗口,DISPOSE_ON_CLOSE因此窗口的同上释放资源
setBounds表示设置位置与大小
setLocationRelativeTo(null);
这个表示设置相对位置,如果为null就是居中。
方法名称 | 概述 |
---|---|
getContentPane() | 返回此窗体的 contentPane 对象 |
getDefaultCloseOperation() | 返回用户在此窗体上单击“关闭”按钮时执行的操作 |
setContentPane(Container contentPane) | 设置 contentPane 属性 |
setDefaultCloseOperation(int operation) | 设置用户在此窗体上单击“关闭”按钮时默认执行的操作 |
setDefaultLookAndFeelDecorated (boolean defaultLookAndFeelDecorated) | 设置 JFrame 窗口使用的 Windows 外观(如边框、关 闭窗口的 小部件、标题等) |
setIconImage(Image image) | 设置要作为此窗口图标显不的图像 |
setJMenuBar( JMenuBar menubar) | 设置此窗体的菜单栏 |
setLayout(LayoutManager manager) | 设置 LayoutManager 属性 |
2.2 菜单栏
我们可以通过JMenuBar来设置菜单列,JMenu设置菜单,JMenuItem设置菜单项目,我们具体来实现一下:
package com;
import javax.swing.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class Demo extends JFrame {
JMenuBar menuBar;
JMenu fileMenu;
JMenuItem filetitle;
public Demo(){
InitFrame();
setFile();
setMenuBar();
validate();
}
public void setMenuBar(){
menuBar = new JMenuBar();
menuBar.add(fileMenu);
setJMenuBar(menuBar);
}
public void setFile(){
fileMenu = new JMenu("文件");
fileMenu.add(new JMenuItem("打开"));
fileMenu.add(new JMenuItem("存储"));
filetitle = new JMenuItem("另存为");
filetitle.setAccelerator(KeyStroke.getKeyStroke("o"));
filetitle.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK));
fileMenu.add(filetitle);
fileMenu.add(new JMenuItem("项目"));
}
public void InitFrame(){
setTitle("大型红娘公司创业基地");
setSize(500,400);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new Demo();
}
}
我们的设计步骤是:先设置菜单项目,再加入菜单栏里面,最后把菜单放进菜单条。
2.3 布局设计
1.FlowLayout布局。
使用FlowLayout布局时,窗口中的组件就会象我们写字一样,首先在第一行写,写不下了再到下一行。
接下来我们在窗口中创建5个按扭,并用FlowLayout进行布局。
我们对窗口进行调整大小,可以发现,组件的位置会自己发生改变。
我们需要把false变成true
我们代码复制一下:
package com;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class Demo extends JFrame {
JMenuBar menuBar;
JMenu fileMenu;
JMenuItem filetitle;
JButton[] buttons;
JMenu aboutMenu;
public Demo(){
InitFrame();
setLayout(new FlowLayout());
setFile();
setAbout();
setMenuBar();
setButtons();
validate();
}
public void setButtons(){
buttons = new JButton[10];
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton(""+i);
add(buttons[i]);
}
}
public void setMenuBar(){
menuBar = new JMenuBar();
menuBar.add(fileMenu);
menuBar.add(aboutMenu);
setJMenuBar(menuBar);
}
public void setAbout(){
aboutMenu = new JMenu("关于");
aboutMenu.add(new JMenuItem("作者"));
aboutMenu.add(new JMenuItem("版本"));
}
public void setFile(){
fileMenu = new JMenu("文件");
fileMenu.add(new JMenuItem("打开"));
fileMenu.add(new JMenuItem("存储"));
filetitle = new JMenuItem("另存为");
filetitle.setAccelerator(KeyStroke.getKeyStroke("o"));
filetitle.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK));
fileMenu.add(filetitle);
fileMenu.add(new JMenuItem("项目"));
}
public void InitFrame(){
setTitle("大型红娘公司创业基地");
setSize(500,400);
setVisible(true);
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new Demo();
}
}
2.GridLayout生成一个m行n列的排列并且全部铺满,也可以改变大小与位置,不想铺满可以加两个参数。表示间隔
package com;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class Demo extends JFrame {
JMenuBar menuBar;
JMenu fileMenu;
JMenuItem filetitle;
JButton[] buttons;
JMenu aboutMenu;
public Demo(){
InitFrame();
setLayout(new GridLayout(5,2,50,50));
setFile();
setAbout();
setMenuBar();
setButtons();
validate();
}
public void setButtons(){
buttons = new JButton[10];
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton(""+i);
add(buttons[i]);
}
}
public void setMenuBar(){
menuBar = new JMenuBar();
menuBar.add(fileMenu);
menuBar.add(aboutMenu);
setJMenuBar(menuBar);
}
public void setAbout(){
aboutMenu = new JMenu("关于");
aboutMenu.add(new JMenuItem("作者"));
aboutMenu.add(new JMenuItem("版本"));
}
public void setFile(){
fileMenu = new JMenu("文件");
fileMenu.add(new JMenuItem("打开"));
fileMenu.add(new JMenuItem("存储"));
filetitle = new JMenuItem("另存为");
filetitle.setAccelerator(KeyStroke.getKeyStroke("o"));
filetitle.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK));
fileMenu.add(filetitle);
fileMenu.add(new JMenuItem("项目"));
}
public void InitFrame(){
setTitle("大型红娘公司创业基地");
setSize(500,400);
setVisible(true);
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
new Demo();
}
}
- BorderLayout
BorderLayout将界面分为5个区域,分为为North,South,West,East,Center,对应5个方向。可以添加5个组件。
package com;
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Demo01 extends JFrame {
private static final long serialVersionUID = 1L;
JButton b[]=new JButton[5];
public Demo01() {
this.setSize(400, 300);
this.setLocation(200, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
for(int i=0; i<5; i++)
b[i]=new JButton("Java");//创建对象
//注意在使用BorderLayout布局时,添加组件要用方向
this.add(b[0],BorderLayout.NORTH);
this.add(b[1],BorderLayout.SOUTH);
this.add(b[2],BorderLayout.EAST);
this.add(b[3],BorderLayout.WEST);
this.add(b[4],BorderLayout.CENTER);
}
public static void main(String[] args) {
Demo01 mf=new Demo01();
mf.setVisible(true);
}
}
2.4 面板
JPanel 面板
JPanel 是一种中间层容器,它能容纳组件并将组件组合在一起,但它本身必须添加到其他容器中使用。JPanel 类的构造方法如下。
- JPanel():使用默认的布局管理器创建新面板,默认的布局管理器为 FlowLayout。
- JPanel(LayoutManagerLayout layout):创建指定布局管理器的 JPanel 对象。
JPanel 类的常用方法如表 2 所示。
方法名及返回值类型 | 说明 |
---|---|
Component add(Component comp) | 将指定的组件追加到此容器的尾部 |
void remove(Component comp) | 从容器中移除指定的组件 |
void setFont(Font f) | 设置容器的字体 |
void setLayout(LayoutManager mgr) | 设置容器的布局管理器 |
void setBackground(Color c) | 设置组件的背景色 |
例 2
编写一个使用 JPanel 组件的窗口程序。要求设置标题为“Java的第二个GUI程序”,然后向窗口中添加一个面板,并设置面板上显示的文本为“这是放在JPanel上的标签”,设置面板背景颜色为白色。具体实现代码如下:
package ch17;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.*;
public class JPanelDemo{
public static void main(String[] agrs){
JFrame jf=new JFrame("Java第二个GUI程序");
//创建一个JFrame对象
jf.setBounds(300, 100, 400, 200); //设置窗口大小和位置
JPanel jp=new JPanel(); //创建一个JPanel对象
JLabel jl=new JLabel("这是放在JPanel上的标签"); //创建一个标签
jp.setBackground(Color.white); //设置背景色
jp.add(jl); //将标签添加到面板
jf.add(jp); //将面板添加到窗口
jf.setVisible(true); //设置窗口可见 }}
如上述代码,首先创建了一个 JFrame 对象,并设置其大小和位置,然后创建了一个 JPanel对象表示面板,调用 setBackground() 方法设置面板的背景色为白色,调用 add() 方法将标签添加到此面板。JFrame 类的 add() 方法将 JPanel 面板添加到 JFmme 窗口中。最后调用 setVisible() 方法将窗口设置为可见。
2.5 复选框
一个复选框有选中和未选中两种状态,并且可以同时选定多个复选框。Swing 中使用 JCheckBox 类实现复选框,该类的常用构造方法如下。
- JCheckBox():创建一个默认的复选框,在默认情况下既未指定文本,也未指定图像,并且未被选择。
- JCheckBox(String text):创建一个指定文本的复选框。
- JCheckBox(String text,boolean selected):创建一个指定文本和选择状态的复选框。
package ch17;
import java.awt.Font;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class JCheckBoxDemo
{
public static void main(String[] agrs)
{
JFrame frame=new JFrame("Java复选组件示例"); //创建Frame窗口
JPanel jp=new JPanel(); //创建面板
JLabel label=new JLabel("流行编程语言有:");
label.setFont(new Font("楷体",Font.BOLD,16)); //修改字体样式
JCheckBox chkbox1=new JCheckBox("C#", true); //创建指定文本和状态的复选框
JCheckBox chkbox2=new JCheckBox("C++"); //创建指定文本的复选框
JCheckBox chkbox3=new JCheckBox("Java"); //创建指定文本的复选框
JCheckBox chkbox4=new JCheckBox("Python"); //创建指定文本的复选框
JCheckBox chkbox5=new JCheckBox("PHP"); //创建指定文本的复选框
JCheckBox chkbox6=new JCheckBox("Perl"); //创建指定文本的复选框
jp.add(label);
jp.add(chkbox1);
jp.add(chkbox2);
jp.add(chkbox3);
jp.add(chkbox4);
jp.add(chkbox5);
jp.add(chkbox6);
frame.add(jp);
frame.setBounds(300,200,400,100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
2.6 下拉列表
下拉列表的特点是将多个选项折叠在一起,只显示最前面的或被选中的一个。选择时需要单击下拉列表右边的下三角按钮,这时候会弹出包含所有选项的列表。用户可以在列表中进行选择,也可以根据需要直接输入所要的选项,还可以输入选项中没有的内容。
下拉列表由 JComboBox 类实现,常用构造方法如下。
- JComboBox():创建一个空的 JComboBox 对象。
- JComboBox(ComboBoxModel aModel):创建一个 JComboBox,其选项取自现有的 ComboBoxModel。
- JComboBox(Object[] items):创建包含指定数组中元素的 JComboBox。
JComboBox 类提供了多个成员方法用于操作下拉列表框中的项,如表 1 所示。
方法名称 | 说明 |
---|---|
void addItem(Object anObject) | 将指定的对象作为选项添加到下拉列表框中 |
void insertItemAt(Object anObject,int index) | 在下拉列表框中的指定索引处插入项 |
JComboBox 能够响应 ItemEvent 事件和 ActionEvent 事件,其中 ItemEvent 触发的时机是当下拉列表框中的所选项更改时,ActionEvent 触发的时机是当用户在 JComboBox 上直接输入选择项并回车时。
package ch17;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
public class JListDemo
{
public static void main(String[] args)
{
JFrame frame=new JFrame("Java列表框组件示例");
JPanel jp=new JPanel(); //创建面板
JLabel label1=new JLabel("证件类型:"); //创建标签
String[] items=new String[]{"身份证","驾驶证","军官证"};
JList list=new JList(items); //创建JList
jp.add(label1);
jp.add(list);
frame.add(jp);
frame.setBounds(300,200,400,100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
2.7 单选框
JRadioButton 通常位于一个 ButtonGroup 按钮组中,不在按钮组中的 JRadioButton 也就失去了单选按钮的意义。
在同一个 ButtonGroup 按钮组中的单选按钮,只能有一个单选按钮被选中。
JRadioButton 类的常用构造方法如下。
- JRadioButton():创建一个初始化为未选择的单选按钮,其文本未设定。
- JRadioButton(Icon icon):创建一个初始化为未选择的单选按钮,其具有指定的图像但无文本。
- JRadioButton(Icon icon,boolean selected):创建一个具有指定图像和选择状态的单选按钮,但无文本。
- JRadioButton(String text):创建一个具有指定文本但未选择的单选按钮。
- JRadioButton(String text,boolean selected):创建一个具有指定文本和选择状态的单选按钮。
- JRadioButton(String text,Icon icon):创建一个具有指定的文本和图像并初始化为未选择的单选按钮。
- JRadioButton(String text,Icon icon,boolean selected):创建一个具有指定的文本、图像和选择状态的单选按钮。
package ch17;
import java.awt.Font;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class JRadioButtonDemo
{
public static void main(String[] agrs)
{
JFrame frame=new JFrame("Java单选组件示例"); //创建Frame窗口
JPanel panel=new JPanel(); //创建面板
JLabel label1=new JLabel("现在是哪个季节:");
JRadioButton rb1=new JRadioButton("春天"); //创建JRadioButton对象
JRadioButton rb2=new JRadioButton("夏天"); //创建JRadioButton对象
JRadioButton rb3=new JRadioButton("秋天",true); //创建JRadioButton对象
JRadioButton rb4=new JRadioButton("冬天"); //创建JRadioButton对象
label1.setFont(new Font("楷体",Font.BOLD,16)); //修改字体样式
ButtonGroup group=new ButtonGroup();
//添加JRadioButton到ButtonGroup中
group.add(rb1);
group.add(rb2);
panel.add(label1);
panel.add(rb1);
panel.add(rb2);
panel.add(rb3);
panel.add(rb4);
frame.add(panel);
frame.setBounds(300, 200, 400, 100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
3.文本框例
Swing 中使用 JTextField 类实现一个单行文本框,它允许用户输入单行的文本信息。该类的常用构造方法如下
- JTextField():创建一个默认的文本框。
- JTextField(String text):创建一个指定初始化文本信息的文本框。
- JTextField(int columns):创建一个指定列数的文本框。
- JTextField(String text,int columns):创建一个既指定初始化文本信息,又指定列数的文本框
方法名称 | 说明 |
---|---|
Dimension getPreferredSize() | 获得文本框的首选大小 |
void scrollRectToVisible(Rectangle r) | 向左或向右滚动文本框中的内容 |
void setColumns(int columns) | 设置文本框最多可显示内容的列数 |
void setFont(Font f) | 设置文本框的字体 |
void setScrollOffset(int scrollOffset) | 设置文本框的滚动偏移量(以像素为单位) |
void setHorizontalAlignment(int alignment) | 设置文本框内容的水平对齐方式 |
源代码可以参考这个:
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class JTextFieldDemo
{
public static void main(String[] agrs)
{
JFrame frame=new JFrame("Java文本框组件示例"); //创建Frame窗口
JPanel jp=new JPanel(); //创建面板
JTextField txtfield1=new JTextField(); //创建文本框
txtfield1.setText("普通文本框"); //设置文本框的内容
JTextField txtfield2=new JTextField(28);
txtfield2.setFont(new Font("楷体",Font.BOLD,16)); //修改字体样式
txtfield2.setText("指定长度和字体的文本框");
JTextField txtfield3=new JTextField(30);
txtfield3.setText("居中对齐");
txtfield3.setHorizontalAlignment(JTextField.CENTER); //居中对齐
jp.add(txtfield1);
jp.add(txtfield2);
jp.add(txtfield3);
frame.add(jp);
frame.setBounds(300,200,400,100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
文本域与文本框的最大区别就是文本域允许用户输入多行文本信息。在 Swing 中使用 JTextArea 类实现一个文本域,其常用构造方法如下。
- JTextArea():创建一个默认的文本域。
- JTextArea(int rows,int columns):创建一个具有指定行数和列数的文本域。
- JTextArea(String text):创建一个包含指定文本的文本域。
- JTextArea(String text,int rows,int columns):创建一个既包含指定文本,又包含指定行数和列数的多行文本域。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class JTextAreaDemo
{
public static void main(String[] agrs)
{
JFrame frame=new JFrame("Java文本域组件示例"); //创建Frame窗口
JPanel jp=new JPanel(); //创建一个JPanel对象
JTextArea jta=new JTextArea("请输入内容",7,30);
jta.setLineWrap(true); //设置文本域中的文本为自动换行
jta.setForeground(Color.BLACK); //设置组件的背景色
jta.setFont(new Font("楷体",Font.BOLD,16)); //修改字体样式
jta.setBackground(Color.YELLOW); //设置按钮背景色
JScrollPane jsp=new JScrollPane(jta); //将文本域放入滚动窗口
Dimension size=jta.getPreferredSize(); //获得文本域的首选大小
jsp.setBounds(110,90,size.width,size.height);
jp.add(jsp); //将JScrollPane添加到JPanel容器中
frame.add(jp); //将JPanel容器添加到JFrame容器中
frame.setBackground(Color.LIGHT_GRAY);
frame.setSize(400,200); //设置JFrame容器的大小
frame.setVisible(true);
}
}
4.事件处理
前面我们讲解了如何放置各种组件,使图形界面更加丰富多彩,但是还不能响应用户的任何操作。若使图形界面能够接收用户的操作,必须给各个组件加上事件处理机制。在事件处理的过程中,主要涉及三类对象。
- Event(事件):用户对组件的一次操作称为一个事件,以类的形式出现。例如,键盘操作对应的事件类是 KeyEvent。
- Event Source(事件源):事件发生的场所,通常就是各个组件,例如按钮 Button。
- Event Handler(事件处理者):接收事件对象并对其进行处理的对象事件处理器,通常就是某个 Java 类中负责处理事件的成员方法。
例如,如果鼠标单击了按钮对象 Button,则该按钮 Button 就是事件源,而 Java 运行时系统会生成 ActionEvent 类的对象 ActionEvent,该对象中描述了单击事件发生时的一些信息。之后,事件处理者对象将接收由 Java 运行时系统传递过来的事件对象 ActionEvent,并进行相应的处理。
开始处理:
动作事件监听器是 Swing 中比较常用的事件监听器,很多组件的动作都会使用它监听,像按钮被里击、列表框中选择一项等。与动作事件监听器有关的信息如下。
- 事件名称:ActionEvent。
- 事件监听接口: ActionListener。
- 事件相关方法:addActionListener() 添加监听,removeActionListener() 删除监听。
- 涉及事件源:JButton、JList、JTextField 等。
相关包:
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
package ch17;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class ActionListenerDemo extends JFrame
{
JList list;
JLabel label;
JButton button1;
int clicks=0;
public ActionListenerDemo()
{
setTitle("动作事件监听器示例");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,400,200);
JPanel contentPane=new JPanel();
contentPane.setBorder(new EmptyBorder(5,5,5,5));
contentPane.setLayout(new BorderLayout(0,0));
setContentPane(contentPane);
label=new JLabel(" ");
label.setFont(new Font("楷体",Font.BOLD,16)); //修改字体样式
contentPane.add(label, BorderLayout.SOUTH);
button1=new JButton("我是普通按钮"); //创建JButton对象
button1.setFont(new Font("黑体",Font.BOLD,16)); //修改字体样式
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
label.setText("按钮被单击了 "+(clicks++)+" 次");
}
});
contentPane.add(button1);
}
//处理按钮单击事件的匿名内部类
class button1ActionListener implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
label.setText("按钮被单击了 "+(clicks++)+" 次");
}
}
public static void main(String[] args)
{
ActionListenerDemo frame=new ActionListenerDemo();
frame.setVisible(true);
}
}
上述代码使用了匿名内部类的方法,才使得我们可以操作,我们还可以使用lambda表达式,后面我们再慢慢说lambda表达式。
键盘事件处理:
在用户按下或松开键盘上的某键时,会产生键盘事件KeyEvent。
Java中的键盘事件处理由事件监听接口KeyListener描述
. KeyListener接口中声明了3个抽象方法:
① void keyPressed(KeyEvent e):为响应某键按下时,即响应“按下键” (KEY_PRESSED)事件将调用此方法。
② void keyReleased(KeyEvent e):为响应某键被释放时,即响应“释放键” (KEY_RELEASED)事件将调用此方法。
③ void keyTyped(KeyEvent e):为响应某键被键入时,即响应“键入键” (KEY_TYPED) 事件将调用此方法。
在keyPressed或keyTyped事件之后释放键时,将调用keyReleased方法。
char getKeyChar() :返回与此事件中的键相关联的Unicode 字符字符或 CHAR_UNDEFINED(仅对KEY_TYPED 事件有意义)。
int getKeyCode() :返回与此事件中的键相关联的虚拟键码keyCode(仅对按下键和释放键事件有意义)。
对于按下键和释放键事件,getKeyCode 方法返回该事件的 keyCode。
对于键入键事件,getKeyCode 方法总是返回 VK_UNDEFINED。
static String getKeyText(int keyCode)
返回描述 keyCode 的 String,如“HOME”、“F1”或“A”。
(4) boolean isActionKey()
返回此事件中的键是否为“动作”键。
n调用组件方法addKeyListener ,注册实现KeyListener接口的事件监听器。
KeyListener接口对应的键盘适配器是KeyAdapter
鼠标监听:
MouseEvent事件对象包含了鼠标事件发生时的信息。
MouseEvent对象的常用方法:
① int GetX()和int getY():获取鼠标的X坐标和Y坐标。
② Point getPoint():获取鼠标的位置。
③ int getClickout():获取鼠标单击次数。
为Component组件注册合适的事件监听器对象,调用方法addMouseListener()与 addMouseMotionListener().
则在鼠标与Component进行交互时,将调用MouseListener和MouseMotionListener接口中实现的方法。
程序员在实现鼠标事件接口时,必须实现接口中的所有方法。
该程序在JFrame组件上监听鼠标事件。程序给JFrame组件分别注册了实现接口MouseListener和实现接口MouseMotionListener的事件监听对象this(this指向当前的JFrame对象)。每个鼠标事件的动作处理,都会在窗口底部的JLabel对象中显示一个字符串,以指明当前用户鼠标操作类型和鼠标光标位置。程序运行结果如图9-20
5.菜单
菜单支撑:
主菜单栏(JMenuBar):类JApplet、JFrame构件均有一个setJMenuBar()方法能够容纳一个菜单栏。
弹出式菜单(JPopupMenu):用户在支持弹出式菜单的控件上,单击鼠标右标时显示弹出式菜单。
创建菜单栏****JMenuBar。
JMenuBar bar = new JMenuBar(); //创建空的菜单栏
JMenuBar meunBar=new JMenuBar(new JMenu(“File”));
//创建一个带有菜单的菜单栏语句
创建完菜单栏**,使用JApplet或JFrame类的setJMenuBar****方法将菜单栏添加到窗体中**。
例如:将前面创建的bar添加到JFrame中:
JFrame myJFrame=new JFrame();
myJFrame.setJMenuBar**(bar);**
nAbstractButton的所有子类都可以使用快捷键。添加快捷键的方法有两种:
① 在创建菜单项的同时定义快捷键。例如:
JMenuItem exitItem = new JMenuItem( “Exit”, (int)‘x’); ② 为已经存在的菜单项定义快捷键。例如:
JMenu fileMenu = new JMenu( “File” );
fileMenu.setMnemonic( ‘F’ );
n 使用setAccelerator方法为菜单项指定一个加速器。
n 加速器和快捷键的区别是:快捷键用来从当前打开的菜单中选择一个子菜单或者菜单项,而加速器可以在不打开菜单的情况下选择菜单项。。
nJPopupMenu是一个可弹出并显示一系列选项的小窗口,它并不固定在菜单栏中,而是能够自由浮动。JPopupMenu具有很好的环境相关(context-sensitive)特性,每一个JPopupMenu都与相应的控件相关联,该控件被称做调用者(invoker)。
**1.**创建弹出式菜单
n 创建JPopupMenu对象的常用构造方法:
①JPopupMenu()
构造一个不带“调用者”的 JPopupMenu。
n 在弹出式菜单创建后,程序员可使用add方法和insert方法向JPopupMenu中添加或者插入JMenuItem与JComponent。
2**.弹出式菜单对象常用的方法:**
① void add(JMenuItem menuItem)
将指定菜单项追加到此菜单的末尾。
② void addSeparator()
将新分隔符追加到菜单的末尾。
③ void show(Component invoker, int x, int y)
在控件调用者的坐标空间中的位置(x,y ) 处,显示弹出菜单。
3**.弹出式菜单触发事件**
n用户在支持弹出式菜单的控件上,单击鼠标右标时产生弹出式触发事件(popup trigger event)。程序员应该检查所有的MouseEvent事件,看其是否是弹出式菜单触发器,然后显示弹出式菜单。
例如,
void checkForTriggerEvent**(** MouseEvent event )
{ if ( event.isPopupTrigger**() )**
popupMenu.show**(event.getComponent(),event.getX(),** event.getY**() );**
}
6.选项卡面板
nTabbedPane控件是一个容器,它允许用户通过单击给定标题或图标的选项卡,在一组组件之间进行切换。JTabbedPane类是JComponent的子类。
1**.**JTabbedPane 常用的构造方法
(1)JTabbedPane()
创建一个的空 TabbedPane对象。
(2) JTabbedPane**(int** tabPlacement**)**
建立一个空的JTabbedPane对象,并指定选项卡布局(摆放位置)。
TabPlacement可为JTabbedPane类中的四个静态常量:
TOP(缺省值)、BOTTOM、LEFT、RIGHT。
. JTabbedPane****对象常用的方法
① void addTab(String title, Component component):添加一个具有指定选项卡标题且没有图标的组件。
② void addTab(String title, Icon icon, Component component):添加一个具有指定选项卡标题 title 和/或 icon 表示的组件,其任意一个都可以为 null。
③ void addTab(String title, Icon icon, Component component, String tip):添加由 title 和/或 icon 表示的 component 和 tip,其中任意一个都可以为 null。
④ int getSelectedIndex() :返回当前选择的此选项卡标签的索引。JTabbedPane上的每个标签都有索引值(index),从左到右依次是0,1,2…。
nJTabbedPane以处理javax,swing.event事件为主。 每当用户在JTabbedpane上选换标签时,都会产生ChangeEvent事件。
n 调用addChangeListener(ChangeListener e)方法:
v给选项卡面板组件注册实现ChangeListener接口的监听器
v实现接口中的stateChanged(ChangeEvent e)方法。
7.综合实例
我们来做一个简单的计算器:
package com.java.gui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;
public class Calculate extends JFrame implements ActionListener {
private JButton bt1, bt2, bt3, bt4, bt5, bt6, bt7, bt8, bt9, bt0;
private JButton plus, minus, multiply, divide, equal, cancel, point;
private JTextField item;
private String lastCommand;
private String input = "";
public static void main(String[] args) {
new Calculate();
}
public Calculate() {
setTitle("计算器");
setLayout(new GridLayout(2, 1));
setSize(150, 200);
setVisible(true);
setLocationRelativeTo(null);
setText();
setButtons();
validate();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void setText() {
JPanel text = new JPanel();
text.setLayout(new GridLayout(2, 1, 5, 5));
text.setSize(150, 40);
JLabel label1 = new JLabel("欢迎使用计算器");
text.add(label1);
item = new JTextField(20);
text.add(item);
pack();
add(text);
}
public void setButtons() {
JPanel button = new JPanel();
button.setLayout(new GridLayout(4, 4));
button.setSize(150, 160);
bt1 = new JButton("1");
bt1.addActionListener(this);
button.add(bt1);
bt2 = new JButton("2");
bt2.addActionListener(this);
button.add(bt2);
bt3 = new JButton("3");
bt3.addActionListener(this);
button.add(bt3);
bt4 = new JButton("4");
bt4.addActionListener(this);
button.add(bt4);
bt5 = new JButton("5");
bt5.addActionListener(this);
button.add(bt5);
bt6 = new JButton("6");
bt6.addActionListener(this);
button.add(bt6);
bt7 = new JButton("7");
bt7.addActionListener(this);
button.add(bt7);
bt8 = new JButton("8");
bt8.addActionListener(this);
button.add(bt8);
bt9 = new JButton("9");
bt9.addActionListener(this);
button.add(bt9);
bt0 = new JButton("0");
bt0.addActionListener(this);
button.add(bt0);
plus = new JButton("+");
plus.addActionListener(this);
button.add(plus);
minus = new JButton("-");
minus.addActionListener(this);
button.add(minus);
multiply = new JButton("*");
multiply.addActionListener(this);
button.add(multiply);
divide = new JButton("/");
divide.addActionListener(this);
button.add(divide);
equal = new JButton("=");
equal.addActionListener(this);
button.add(equal);
cancel = new JButton("C");
cancel.addActionListener(this);
button.add(cancel);
point = new JButton(".");
point.addActionListener(this);
button.add(point);
pack();
add(button);
}
public void actionPerformed(ActionEvent e) {
String text = e.getActionCommand();
int cnt = 0;
if (text.equals("*") || text.equals("/") || text.equals("+") || text.equals("-")) {
input += " " + text + " ";
} else if (text.equals("=")) {
input = Calculate(input);
item.setText(input);
input = "";
cnt = 1;
}else if(text.equals("C")){
input = "";
}
else {
input += text;
}
if (cnt == 0)
item.setText(input);
}
public String Calculate(String input){
String str[];
str = input.split(" ");
Stack<Double> s = new Stack<>();
double m = Double.parseDouble(str[0]);
s.push(m);
for(int i = 0; i < str.length;i++){
if(i % 2 == 1){
if (str[i].compareTo("+") == 0){
double help = Double.parseDouble(str[i+1]);
s.push(help);
}
if (str[i].compareTo("-") == 0){
double help = Double.parseDouble(str[i+1]);
s.push(-help);
}
if (str[i].compareTo("*") == 0){
double help = Double.parseDouble(str[i+1]);
double ans = s.peek();
s.pop();
ans *= help;
s.push(ans);
}
if (str[i].compareTo("/") == 0){
double help = Double.parseDouble(str[i+1]);
double ans = s.peek();
s.pop();
try{
ans /= help;
}catch(Exception e){
item.setText(e.getMessage());
s.clear();
}finally {
s.push(ans);
}
}
if (str[i].compareTo("C") == 0){
s.clear();
}
}
}
double result = 0;
while (!s.empty()){
result += s.peek();
s.pop();
}
String answer = String.valueOf(result);
return answer;
}
}
代码是这样的,我们首先采用一些面板来存储我们主要部分,然后采用事件监听问题来进行处理算法。代码略有借鉴,发现有bug。