GUI
GUI 工具集(了解)
AWT
- 本地平台捆绑,依靠本地系统决定组件外观和功能,重量级组件
SWING
-
大多Swing组件不依赖本地窗口部件们可以在每个平台实现每个窗口部件。
-
缺省的情况下采用本地平台的显示外观
-
不依赖于底层平台的Swing组件,称为轻量级组件
SWT
- 吸收了AWT 和 Swing实现的最好部分,保证了与本地窗口部件相当的外观和响应度
区别
- AWT、SWT依赖底层平台,不同操作系统显示效果不一样
- Swing 基于 AWT 架构之上,保持了平台独立的特点
- AWT 和 SWT有对本地组件的引用,必须正确释放这些引用
组件分类(了解)
顶层容器
JFrame, JApplet, JDialog, JWindow
这四个组件被称为重量级组件
根面板结构(了解)
- 玻璃面板: 默认不可见。接受鼠标键盘等响应事件
- 内容面板: 一个可见的容器,不包括菜单条
- 工具条: 可选组件
- 分层面板:定位内容面板和菜单条
可插入式外观
- Swing将组建和组建绘制相分离,因此可以动态改变外观不影响程序功能
- UI为结尾的类,是Swing组建提供用户界面的,实际上是进行组件绘制的类
- LookAndFeel子类提供了构建特定外观的全局信息,包括颜色,字体,边框等。
UIManager
-
包含嵌套类LookAndFeelInfo来维护外观信息
-
调用UIManager类的setLookAndFeel来设定当前外观
looks = UIManager.getInstalledLookAndFeels() UIManager.setLookAndFeel(looks[value ].getClassName()) SwingUtilities.updateComponentTreeUI(this)
事件处理机制
事件处理机制包含三个部分
- 事件源 与用户进行交互的某个GUI组件
- 事件对象 事件的信息例如 ActionEvent 包含在 java.awt.event包中 是类AWTEvent或其子类的示例对象
- 监听器 接受事件对象,并处理事件对象
JButton btn = new JButton("按钮") // btn 代表事件源
btn.addActionListener(new ActionListener() {
@Override
public void ActionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
})
// 上面的匿名内部类为监听器
// ActionEvent 为事件对象
事件监听器接口与事件监听器(了解)
- 事件的处理方法都被定义在继承了 java.util.EventListener 类的 EventListener 接口中
- 任何一个类想操作EventListener接口中定义的方法,都必须实现这个接口,也就是成为事件监听者
GUI事件处理关键过程
- 为将要产生事件的组件注册监听者 (addActionListner)
- 为监听者实现事件处理的方法 (ActionPerformed)
java事件类型(了解)
- java.awt.event中定义的事件类型同时为AWT和Swing组件所使用
- 一些新的Swing组件事件类型被定义在javax.swing.event中
事件
ActionEvent
一些方法
ActionEvent e;
e.getSource(); // 获得事件源对象的引用
e.getActionCommand(); // 获得文本框中数的文本
ItemEvent
一些方法
ItemEvent e;
e.getStateChange(); // 获得是选中还是未选中
// 例如 e.getStateChange() === ItemEvent.SELECTED // 表示选中
ListSelectionEvent
一些方法
ListSelectionEvent e;
changeEvent
一些方法
changeEvent e;
MouseEvent
一些方法
mouseEvent e;
e.getX();
e.getY(); // 鼠标x,y坐标
e.isPopupTrigger() // 鼠标右键
/**
Pane.addMouseListener(new MouseListener() {
})
pane.addMouseMotionListener(new MouseMotionListner(){
})
// 第一个主要是一些瞬发的事件 有 mouseClickd 等五个方法
// 第二个主要是移动 有 mouseMoved mouseDragged 两个方法
*/
// 由于这些接口内方法太多,有时候只要一个方法要写很多没用的方法,怎么办
// 适配器类
// MouseListener -> MouseAdpater
e.getClickCount(); // 鼠标单击次数
e.getMetaDown(); // 右键
e.getAltDown(); // 中键
// 以上两个都不是那么就是左键
KeyEvent
Pane.addKeyListener(new KeyListner() {
// ....
})
1. keyPressed() // 任意键按下
2. keyTyped(); // 不为动作键按下
3. keyReleased(); // 任意键松开
KeyEvent e;
e.getKeyCode();
e.getKeyChar();
e.geyKeyText(e.getKeyCode());
组件
JFrame
特点
-
是具有标题栏和边框的窗口
-
JFrame是 java.awt.Frame 的子类
-
JFrame不完全是由Java编写的
-
窗口是本地平台的窗口显示工具集提供的,不同平台窗口将有所不同的
构造方法
public JFrame()
public JFrame(String title)
内部方法
JFrame f = new JFrame("示例");
f.setSize(100, 200); // width and height
f.setVisible(true); // 显示窗口
f.setLocationRelativeTo(null); //设置居中
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
// 可以选择
EXIT_ON_CLOSE 退出
HIDE_ON_CLOSE 隐藏
DO_NOTHING_ON_CLOSE 什么都不做(关不掉了)
f.setLayout(new FlowLayout());
// 可以选择各种布局
// 这些布局一般都在 java.awt包内
f.add(Component c); // 通过add方法可以加入Swing组件
f.getContentPane(); // 可以获得这个JFrame的内容面板,显示的所有组件实际上都是在这个内容面板里面 返回的是一个Container对象
f.setContentPane(); // 设置内容面板
// 通过建立一个JPanel 等中间容器可以把组件添加到容器中, 用setContentPane() 方法将该容器设为内容面板
f.validate(); // 当布局改变或内部元素发生改变,刷新使生效
// 上面这个方法呢,在内容面板里也可以用
// 内容面板还可以设置背景
f.getContentPane().setBackground(Color.BLACK);
f.getContentPane().setForeground(Color.YELLOW); //设置前景色
JLabel
构造方法
public JLabel(Icon icon);
public JLabel(String text);
public JLable(String text, Icon icon, int align);
public JLable();
内部方法
JLable l = new JLabel();
Icon icon = new ImageIcon(getClass().getSource("xxx.png"));
// icon 是 interface 用实现他的类 ImageIcon
// getClass() 可以获得当前类的引用
// getSource() 基于当前类的位置获取图片(相对路径)
l.setText("标签");
l.setIcon(icon);
l.setHorizontalTextPostion(SwingConstants.CENTER);
l.setVerticalTextPostion(SwingConstants.BOTTOM);
// SwingConstants 是 java.swing包内的
// 关键是处理布局用的, JLabel构造函数的第三个参数也可以用这个 (第三个参数代表是横向的布局)
l.setToolTipText("这是一个标签"); // 设置鼠标移动进去的时候的文字提示
JButton
构造方法
public JButton(String text);
public JButton();
内部方法
JButton btn = new JButton("按钮");
btn.addActionListener(new ActionListener() {
@Override // 重写方法
public void actionPerformed(ActionEvent e) {
dispose(); // 直接退出程序
}
});
JTextField && JPasswordField
构造方法
public JTextField(String text);
public JTextField(int cols);
public JTextField();
public JTextField(String text, int cols);
内部方法
JTextField input = new JTextField(10);
input.setText("文本框");
input.getText(); // 获得内容 (JTextField)
input.getPassword(); // 获得内容 (JPasswordField) 获得的是char[] 需要转化为String
// new String(input.getPassword())
input.setEditable(false); // 设为不可编辑
input.setFont(new Font("Serif", Font.PLAIN, 12));
/**
第一个参数是 font family
第二个参数是 Font.PLAIN FONT.BOLD FONT.ITALIC 等 表示正常,加粗,斜体
第三个参数是 font size
*/
JOptionPane
静态方法
JOptionPane.showMessageDialog(null, "msg"); // 第一个是相对的父容器(主要是确定位置), 第二是信息
JOpitonPane.showInputDialog("Enter a integer"); // 显示一个输入框,返回String
JCheckBox
构造方法
public JCheckBox(String text);
public JCheckBox(String text, boolean isSelected); // 第二个表示初始状态是否被选中,默认是false
public JCheckBox();
内部方法
JCheckBox chkbox = new JCheckBox("Bold");
chkbox.addItemListener(new ItemListener() {
@Override
public void ItemStateChanged(ItemEvent e) {
// statements...
}
})
chkbox.isSelected(); // 返回是否被选中了
JRadioButton
构造方法
public JRadioButton(String text);
public JRadioButton(String text, boolean isSelected); // 第二个表示初始状态是否被选中,默认是false
public JRadioButton();
内部方法
JRadioButton radioBtn = new JRadioButton("Bold");
radioBtn.addItemListener(new ItemListener() {
@Override
public void ItemStateChanged(ItemEvent e) {
// statements...
}
})
chkbox.isSelected(); // 返回是否被选中了
ButtonGroup radioGroup = new ButtonGroup();
radioGroup.add(radioBtn); // 可以组织,使得这里面的按钮只有一个会被选中
// ButtonGroup 并不是 GUI 组件 不会显示 但是引入的话 javax.swing.ButtonGroup
JComboBox
- 默认第一个添加到 JComboBox中的这个元素是选中的
构造方法
public JComboBox();
public JComboBox(Object[] objs); // 传入一个数组对象
内部方法
JComboBox comboBox = new JComboBox();
comboBox.addItemListener(new ItemListener() {
@Override
public void ItemStateChanged(ItemEvent e) {
// statements...
}
})
comboBox.setMaximumRowCount(3); // 默认显示3行 多余的呢 ***Combox 会自动提供滚动条
comboBox.addItem(Object obj); // 增加列表项
comboBox.getSelectedIndex(); // 获得被选中的这个索引 (默认从0开始的
JList
构造方法
public JList();
public JList(Object[] objs); // 传入一个数组对象
内部方法
JList list = new JList();
comboBox.addItemListener(new ItemListener() {
@Override
public void ItemStateChanged(ItemEvent e) {
// statements...
}
})
list.setVisibleRowCount(3); // 默认显示3行 多余的呢 ***JList 不会自动提供滚动条
list.addItem(Object obj); // 增加列表项
list.setSelectionMode(ListSelectionMode.SINGLE_SELECTION);
list.getSelectedIndex(); // 一个选中索引
list.getSelectedIndices(); // 多个选中索引
list.getSelectedValues(); // 获得选中的这个值
list.setListData(); // 设置值
/**
SINGLE_SELECTION // 只能选中一条
SINGLE_INTERVAL_SELECTION // 在一个连续范围内选择
MUTIPLE_INTERVAL_SELECTION // 任意多选
*/
add(new JScrollPane(list)); // 添加的时候如果要滚动条,放在 JScrollPane中
list.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
// statement...
}
})
JTextArea
- 不提供动作事件
- 默认不提供滚动条
构造方法
public JTextArea();
public JTextArea(String text);
public JTextArea(int rows, int cols);
public JTextArea(int rows, int cols, String text);
内部方法
textarea.setDisabledTextColor(Color.BLACK); // 设置颜色
JTabbedPane
- 标签栏
构造方法
public JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
// JTabbedPane.TOP 表示标签栏出现在顶部
// JTabbedPane.SCROLL_TAB_LAYOUT 表示一行容纳不下,应该折行
内部方法
tabbedPane.addTab(String title, Icon icon, Component component, String tip);
// tip 是鼠标移入的显示
// component 一般是个panel
JSlider
- 使用户可以从某个整数范围内进行选择
- 默认水平方向 左小,右大 垂直方向 下小,上大
构造方法
public JSlider(); // 水平 默认 0-100
public JSlider(int orientation);
/** 可以取值
JSlider.HORIZONTAL
JSlider.VERTICAL
*/
public JSlider(int min, int max, int value);
public JSlider(int min, int max);
public JSlider(int orientation, int min, int max, int value);
内部方法
JSlider j = new JSlider();
j.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(changeEvent e) {
// statement...
}
})
j.setMajorTickSpacing(); //设置主刻度线的值差
j.setPaintTicks(); //是否显示刻度线,默认不显示
j.getValue(); // 获得当前的值
JMenu
- JMenu 菜单容器
- JMenuBar 菜单栏
- JMenuItem(包括下面单选按钮) 被选中会触发ActionEvent
- JCheckBoxMenuItem 复选框 (这个是ItemListener)
- JRadioButtonMenuItem 单选按钮
- JPopupMenu
- JFrame 和 JApplet 有setMenuBar() 方法
构造方法
JMenu fileMenu = new JMenu("File");
JMenuItem aboutItem = new JMenuItem("About...");
JMenuBar bar = new JMenuBar();
JCheckBoxMenuItem item = new JCheckBoxMenuItem(Object[] objs);
JRadioButtonMenuItem item = new JRadioButtonMenuItem (Object[] objs);
JPopupMenu popupMenu = new JPopupMenu();
内部方法
fileMenu.setMnemonic('F'); //Mnemonic 助记符
aboutItem.setMnemonic('A'); // 设置快捷键为A
fileMenu.add(aboutItem);
fileMenu.addSeparator(); // 加个分割符号
aboutItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// statement...
}
})
setJMenuBar(bar);
bar.add(fileMenu);
popupMenu.show(Component parent, int x, int y); // 位置相对元素,距离相对元素左上角的x, y
JDeskTopPane 和 JInternalFrame
- JDeskTopPane用来管理JInternalFrame的子窗口容器
- 这样的话呢可以实现多文档界面程序
// 示例
JDesktopPane pane = new JDesktopPane();
add(pane);
JInternalFrame frame = new JInternalFrame(String title);
pane.add(frame);
frame.pack(); // 设置子窗口大小
frame.add(new JPanel()); // 可以当做他就是一个JFrame差不多的东西
frame.setVisible(); // 设为可看见
布局管理
-
绝对定位(了解)
通过将Container的布局设置为null,接下来用setLocation, setBounds, setSize等方法指定每一个元素相对于Container左上角的绝对位置
setLayout(null); JButton btn = new JButton("按钮"); btn.setSize(100, 200); btn.setLocation(100, 200); // 以上两个相等于 btn.setBounds(100, 200, 100, 200);
-
布局管理器
利用布局管理器
FlowLayout
- 默认是居中对齐
- 流式布局,一行放不下,自动换行
- 是Applet, Panel, JPanel 的默认布局方式
构造方法
public FlowLayout();
public FlowLayout(int alignment);
// FlowLayout.LEFT
// FlowLayout.CENTER
// FlowLayout.RIGHT
public FlowLayout(int alignment, int horz, int vert);
// 设置组件之间的一个水平距离和垂直距离
内部方法
FlowLayout flay = new FlowLayout();
flay.setAlignment(FlowLayout.LEFT); // 设置左对齐
flay.layoutContainer(container); // 重置内容面板布局
BorderLayout
- 容器包含上下左右中五个部分,每个区域一个组件
- 加入的时候如果不写添加在哪里,默认在CENTER区域
构造方法
public BorderLayout();
public BorderLayout(int horz, int vert);
// 设置组件之间的一个水平距离和垂直距离, 默认为0
内部方法
BorderLayout blay = new BorderLayout();
setLayout(blay);
add(Component c, BorderLayout.SOUTH);
/** 取值可以为
BorderLayout.NORTH
BorderLayout.WEST
BorderLayout.EAST
BorderLayout.SOUTH
BorderLayout.CENTER
*/
GirdLayout
- 每一行高度和宽度都一样
- 从左到右从上到下安排组件
构造方法
public GirdLayout();
public GirdLayout(int row, int col); // 设置行和列
public GridLayout(int row, int col, int horz, int vert);
// 设置组件之间的一个水平距离和垂直距离, 默认为0
CardLayout
- 一个压着一个
构造方法
public CardLayout();
内部方法
CardLayout clay = new CardLayout();
clay.next(cardPanel); // cardPanel是设置了卡片式布局的容器
clay.previos(cardPanel); // 同上
BoxLayout
- 一个压着一个
- Box容器提供了4种透明的组件
- rigid area 填充一块尺寸
- glue 尽量填充满一个方向的尺寸
- strut 填充一个方向的尺寸
- filler 与 rigidarea类似 但是可以设置最小,最大,优先尺寸
构造方法
public BoxLayout(Panel p, BoxLayout.Y_AXIS);
// 可以选择
// Y_AXIS 纵向
// X_AXIS 横向
静态方法
Box.createHorizontalBox(); // 创建一个box 默认是BoxLayout布局的
Box.createVerticalBox(); // 纵向box
Box.createHorizontalGlue(); // glue 填充
Box.createHorizontalStrut(int width); // strut
Box box = Box.createRigidArea(new Dimension(int width, int height)); // rigid area
box.add(Component c);
GridBagLayout
- 比GridLayout 类似但强大的布局管理器
- 由于比较复杂,布局需要设置很多属性,被抽象为GridBagConstraints对象
- 几个重要的参数
constraints = new GridBagConstraints();
fill, weightx, weighty, gridx, girdy, gridwidth, gridheight
layout.setConstraints(component c, GridBagConstraints g);