学习内容:图形界面系列教材
学习关于多线程的内容(一)
## 按钮监听 创建一个匿名类实现ActionListener接口,当按钮被点击时,actionPerformed方法就会被调用
b.addActionListener(new ActionListener() {
// 当按钮被点击时,就会触发 ActionEvent事件
// actionPerformed 方法就会被执行
public void actionPerformed(ActionEvent e) {
l.setVisible(false);
}
});
键盘监听
键盘监听器: KeyListener
keyPressed 代表 键被按下
keyReleased 代表 键被弹起
keyTyped 代表 一个按下弹起的组合动作
KeyEvent.getKeyCode() 可以获取当前点下了哪个键
f.addKeyListener(new KeyListener() {
// 键被弹起
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 39) {
//39代表方向键右键
l.setLocation(l.getX() + 100, l.getY()+100);
//x坐标+100 y坐标+100
}
}
//键被按下
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
// 按下弹起的组合动作
public void keyTyped(KeyEvent e) {
}
});
鼠标监听
MouseListener 鼠标监听器
mouseReleased 鼠标释放
mousePressed 鼠标按下
mouseExited 鼠标退出
mouseEntered 鼠标进入
mouseClicked 鼠标点击
l.addMouseListener(new MouseListener() {
// 释放鼠标
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
// 按下鼠标
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
// 鼠标退出
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
// 鼠标进入
public void mouseEntered(MouseEvent e) {
Random r = new Random();
int x = r.nextInt(f.getWidth() - l.getWidth());
int y = r.nextInt(f.getHeight() - l.getHeight());
l.setLocation(x, y);
}
// 按下释放组合动作为点击鼠标
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
});
鼠标监听适配器
使用鼠标监听的时候有很多方法没有用到,可以使用鼠标监听适配器,只要重写需要用到的方法就可以
l.addMouseListener(new MouseAdapter() {
// 只有mouseEntered用到了
public void mouseEntered(MouseEvent e) {
Random r = new Random();
int x = r.nextInt(f.getWidth() - l.getWidth());
int y = r.nextInt(f.getHeight() - l.getHeight());
l.setLocation(x, y);
}
});
容器
java的图形界面中,容器是用来存放 按钮,输入框等组件的。
窗体型容器有两个,一个是JFrame,一个是JDialog
JFrame就是我们之前学习的那个容器
而JDialog也是窗体型容器,右上角没有最大和最小化按钮
模态JDialog 便是那些平时我们遇到的如果不进行操作,将无法继续对其背后的父窗口进行操作的模态窗口
我们可以通过调用方法 setResizable(false), 做到窗体大小不可变化
public class Rongqi {
public static void main(String[] args) {
JFrame f = new JFrame("外部窗体");
f.setSize(800, 600);
f.setLocation(100, 100);
// 根据外部窗体实例化JDialog
JDialog d = new JDialog(f);
// 设置为模态
d.setModal(true);
d.setTitle("模态的对话框");
d.setSize(400, 300);
d.setLocation(200, 200);
d.setLayout(null);
JButton b = new JButton("锁定大小");
b.addActionListener(new ActionListener() {
// 当按钮被点击时,就会触发 ActionEvent事件
// actionPerformed 方法就会被执行
public void actionPerformed(ActionEvent e) {
if(b.getText().equals("解锁大小")) {
d.setResizable(true);
b.setText("锁定大小");
}else {
d.setResizable(false);
b.setText("解锁大小");
}
}
});
b.setBounds(50, 50, 280, 30);
d.add(b);
d.setResizable(true);
f.setVisible(true);
d.setVisible(true);
}
}
布局器
布局器是用来决定容器上的组件摆放的位置和大小的
绝对定位就是指不使用布局器,组件的位置和大小需要单独指定
设置布局器为FlowLayout,顺序布局器
容器上的组件水平摆放
加入到容器即可,无需单独指定大小和位置
设置布局器为BorderLayout
容器上的组件按照上下左右中 四方一中的顺序摆放
设置GridLayout
容器上的组件将呈网格状排列
如 :
// 该GridLayerout的构造方法表示该网格是2行3列
f.setLayout(new GridLayout(2, 3));
即便 使用 布局器 ,也可以 通过setPreferredSize,向布局器建议该组件显示的大小.
public class Rongqi {
public static void main(String[] args) {
JFrame f = new JFrame("外部窗体");
f.setSize(800, 600);
f.setLocation(100, 100);
f.setLayout(new GridLayout(4, 5));
JButton b1 = new JButton("7");
JButton b2 = new JButton("8");
JButton b3 = new JButton("9");
JButton b4 = new JButton("/");
JButton b5 = new JButton("sq");
JButton b6 = new JButton("4");
JButton b7 = new JButton("5");
JButton b8 = new JButton("6");
JButton b9 = new JButton("*");
JButton b10 = new JButton("%");
JButton b11 = new JButton("1");
JButton b12= new JButton("2");
JButton b13= new JButton("3");
JButton b14= new JButton("-");
JButton b15= new JButton("1/x");
JButton b16= new JButton("0");
JButton b17= new JButton("+/-");
JButton b18= new JButton(".");
JButton b19= new JButton("+");
JButton b20 = new JButton("=");
// 加入到容器的时候,需要指定位置
f.add(b1);
f.add(b2);
f.add(b3);
f.add(b4);
f.add(b5);
f.add(b6);
f.add(b7);
f.add(b8);
f.add(b9);
f.add(b10);
f.add(b11);
f.add(b12);
f.add(b13);
f.add(b14);
f.add(b15);
f.add(b16);
f.add(b17);
f.add(b18);
f.add(b19);
f.add(b20);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
组件
JAVA的图形界面下有两组控件,一组是awt,一组是swing。
一般都是使用swing
JLabel
标签
JLabel l = new JLabel("LOL文字");
//文字颜色
l.setForeground(Color.red);
l.setBounds(50, 50, 280, 30);
setIcon
使用JLabel显示图片
JLabel l = new JLabel();
//根据图片创建ImageIcon对象
ImageIcon i = new ImageIcon("e:/project/j2se/shana.png");
//设置ImageIcon
l.setIcon(i);
//label的大小设置为ImageIcon,否则显示不完整
l.setBounds(50, 50, i.getIconWidth(), i.getIconHeight());
JButton
按钮
前面学过不再过多描述
JCheckBox
复选框
JCheckBox bCheckBox = new JCheckBox("物理英雄");
//设置 为 默认被选中
bCheckBox.setSelected(true);
bCheckBox.setBounds(50, 50, 130, 30);
JCheckBox bCheckBox2 = new JCheckBox("魔法 英雄");
bCheckBox2.setBounds(50, 100, 130, 30);
//判断 是否 被 选中
f.add(bCheckBox);
f.add(bCheckBox2);
JRadioButton
单选框
使用isSelected来获取是否选中了
为了实现只能选中一个,还需要用到ButtonGroup对按钮进行分组,把不同的按钮,放在同一个分组里,就是下面的按钮组
JRadioButton b1 = new JRadioButton("物理英雄");
// 设置 为 默认被选中
b1.setSelected(true);
b1.setBounds(50, 50, 130, 30);
JRadioButton b2 = new JRadioButton("魔法 英雄");
b2.setBounds(50, 100, 130, 30);
f.add(b1);
f.add(b2);
ButtonGroup
按钮组
JRadioButton b1 = new JRadioButton("物理英雄");
// 设置 为 默认被选中
b1.setSelected(true);
b1.setBounds(50, 50, 130, 30);
JRadioButton b2 = new JRadioButton("魔法 英雄");
b2.setBounds(50, 100, 130, 30);
// 按钮分组
ButtonGroup bg = new ButtonGroup();
// 把b1,b2放在 同一个 按钮分组对象里 ,这样同一时间,只有一个 按钮 会被选中
bg.add(b1);
bg.add(b2);
JComboBox
下拉框
使用getSelectedItem来获取被选中项
使用setSelectedItem() 来指定要选中项
String[] heros = new String[] { "卡特琳娜", "库奇" };
JComboBox cb = new JComboBox(heros);
cb.setBounds(50, 50, 80, 30);
f.add(cb);
JOptionPane
对话框
int option = JOptionPane.showConfirmDialog(f, "是否 使用外挂 ?");
//表示询问,第一个参数是该对话框以哪个组件对齐
if (JOptionPane.OK_OPTION == option) {
String answer = JOptionPane.showInputDialog(f, "请输入yes,表明使用外挂后果自负");
//接受用户的输入
if ("yes".equals(answer))
JOptionPane.showMessageDialog(f, "你使用外挂被抓住! 罚拣肥皂3次!");
//显示消息
}
JTextField
文本框
只能进行单行输入
如果要多行输入需使用JTextArea
JLabel lName = new JLabel("账号:");
// 输入框
JTextField tfName = new JTextField("");
tfName.setText("请输入账号");
tfName.setPreferredSize(new Dimension(80, 30));
JLabel lPassword = new JLabel("密码:");
// 输入框
JTextField tfPassword = new JTextField("");
tfPassword.setText("请输入密码");
//设置文本
tfPassword.setPreferredSize(new Dimension(80, 30));
f.add(lName);
f.add(tfName);
f.add(lPassword);
f.add(tfPassword);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tfPassword.grabFocus();
f.setVisible(true);
JPasswordField
密码框
与文本框不同,获取密码框里的内容,推荐使用getPassword,该方法会返回一个字符数组,而非字符串
JLabel l = new JLabel("密码:");
// 密码框
JPasswordField pf = new JPasswordField("");
pf.setText("&48kdh4@#");
pf.setPreferredSize(new Dimension(80, 30));
// 与文本框不同,获取密码框里的内容,推荐使用getPassword,该方法会返回一个字符数组,而非字符串
char[] password = pf.getPassword();
String p = String.valueOf(password);
System.out.println(p);
f.add(l);
f.add(pf);
JTextArea
文本域
可以输入多行数据
如果要给文本域初始文本,通过\n来实现换行效果
会用到append来进行数据追加
可以通过setLineWrap(true) 来做到自动换行
JLabel l = new JLabel("文本域:");
JTextArea ta = new JTextArea();
ta.setPreferredSize(new Dimension(200, 150));
//\n换行符
ta.setText("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh!\n");
//追加数据
ta.append("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww");
//设置自动换行
ta.setLineWrap(true);
f.add(l);
f.add(ta);
JProgressBar
进度条
JProgressBar pb = new JProgressBar();
//进度条最大100
pb.setMaximum(100);
//当前进度是50
pb.setValue(50);
//显示当前进度
pb.setStringPainted(true);
f.add(pb);
JFileChooser
文件选择器
平时我们打开、另存为文件时用到的就是文件选择器
fc.setFileFilter(new FileFilter() {
@Override
public String getDescription() {
// TODO Auto-generated method stub
return ".txt";
}
@Override
public boolean accept(File f) {
return f.getName().toLowerCase().endsWith(".txt");
}
});
面板
JPanel即为基本面板
面板和JFrame一样都是容器,但面板一般作为小容器,将组件放在小容器中,再将小容器放在大容器窗体中,这样较为方便整体界面的设计
JPanel p1 = new JPanel();
// 设置面板大小
p1.setBounds(50, 50, 300, 60);
// 设置面板背景颜色
p1.setBackground(Color.RED);
// 这一句可以没有,因为JPanel默认就是采用的FlowLayout
p1.setLayout(new FlowLayout());
JButton b1 = new JButton("英雄1");
JButton b2 = new JButton("英雄2");
JButton b3 = new JButton("英雄3");
// 把按钮加入面板
p1.add(b1);
p1.add(b2);
p1.add(b3);
JPanel p2 = new JPanel();
JButton b4 = new JButton("英雄4");
JButton b5 = new JButton("英雄5");
JButton b6 = new JButton("英雄6");
p2.add(b4);
p2.add(b5);
p2.add(b6);
p2.setBackground(Color.BLUE);
p2.setBounds(10, 150, 300, 60);
// 把面板加入窗口
f.add(p1);
f.add(p2);
JFrame上有一层面板,叫做ContentPane
平时通过f.add()向JFrame增加组件,其实是向JFrame上的 ContentPane加东西
SplitPanel 即分割条
// 创建一个水平JSplitPane,左边是p1,右边是p2
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, pLeft, pRight);
// 设置分割条的位置
sp.setDividerLocation(80);
// 把sp当作ContentPane
f.setContentPane(sp);
关于滚动条
使用带滚动条的面板有两种方式
- 在创建JScrollPane,把组件作为参数传进去
JScrollPane sp = new JScrollPane(ta);
- 希望带滚动条的面板显示其他组件的时候,调用setViewportView
sp.setViewportView(ta);
关于TabbedPanel
窗口分为两个界面(两个窗口?)类似于浏览器的多个小窗口
关于 CardLayerout
类似于TabbedPanel
练习
JFrame f = new JFrame("LoL");
f.setSize(400, 300);
f.setLocation(200, 200);
f.setLayout(null);
JPanel pLeft = new JPanel();
pLeft.setBounds(50, 50, 300, 60);
//pLeft.setBackground(Color.RED);
pLeft.setLayout(new FlowLayout());
JButton b1 = new JButton("盖伦");
JButton b2 = new JButton("提莫");
JButton b3 = new JButton("安妮");
pLeft.add(b1);
pLeft.add(b2);
pLeft.add(b3);
final JLabel l = new JLabel();
ImageIcon i = new ImageIcon("C:\\Users\\11712\\Desktop\\设计部\\易拉宝\\1.png");
l.setIcon(i);
l.setBounds(375, 275, i.getIconWidth(), i.getIconHeight());
/*JPanel pRight = new JPanel();
JButton b4 = new JButton("英雄4");
JButton b5 = new JButton("英雄5");
JButton b6 = new JButton("英雄6");
pRight.add(b4);
pRight.add(b5);
pRight.add(b6);*/
//pRight.setBackground(Color.BLUE);
l.setBounds(10, 150, 300, 60);
// 创建一个水平JSplitPane,左边是p1,右边是p2
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, pLeft, l);
// 设置分割条的位置
sp.setDividerLocation(80);
// 把sp当作ContentPane
f.setContentPane(sp);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
菜单
GUI的菜单分为 菜单栏,菜单和菜单项
菜单即如我们所用的eclipse软件上面一栏的诸如File、Edit、Source等
而菜单项即你点击其中一个菜单后下来出来的诸如“新建、导入”等选项
练习
package 菜单;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextArea;
public class practice {
public static void main(String[] args) {
JFrame f = new JFrame("LoL");
f.setSize(400, 400);
f.setLocation(200, 200);
JMenuBar mb = new JMenuBar();
JMenu mHero = new JMenu("文件");
JMenu mItem = new JMenu("编辑");
JMenu mWord = new JMenu("格式");
JMenu mSummon = new JMenu("查看");
JMenu mTalent = new JMenu("帮助");
// 菜单项
mHero.add(new JMenuItem("新建"));
mHero.add(new JMenuItem("打开"));
mHero.add(new JMenuItem("保存"));
mHero.add(new JMenuItem("另存为"));
// 分隔符
mHero.addSeparator();
mHero.add(new JMenuItem("页面设置"));
mHero.add(new JMenuItem("打印"));
// 分隔符
mHero.addSeparator();
mHero.add(new JMenuItem("退出"));
mb.add(mHero);
mb.add(mItem);
mb.add(mWord);
mb.add(mSummon);
mb.add(mTalent);
f.setJMenuBar(mb);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
工具栏
Swing如何使用工具栏JToolBar
工具栏用于存放常用的按钮
我们可以通过以下命令来添加工具栏
JFrame f = new JFrame("LoL");
f.setSize(400, 300);
f.setLocation(200, 200);
// 菜单
addMenu(f);
// 工具栏
JToolBar tb = new JToolBar();
// 为工具栏增加按钮
JButton b1 = new JButton(new ImageIcon("e:/project/j2se/1.jpg"));
tb.add(b1);
f.setLayout(new BorderLayout());
f.add(tb, BorderLayout.NORTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
同时,我们可以通过以下的命令来给其中的按钮设置提示信息
// 给按钮设置提示信息
b1.setToolTipText("这是一个ADC");
因为默认情况下 工具栏可以通过鼠标拖动,所以我们可以通过以下命令来禁用鼠标拖动功能
// 禁止工具栏拖动
tb.setFloatable(false);
表格
我们如果要表现出一个表格需要两个数据组
第一: 一个一维数组:columnNames 表示表格的标题
第二:一个二维数组: String[][] 来储存 表格中的内容
一般来说,第一个一维数组中储存的标题是默认不显示的,但是我们可以通过JScrollPane来将其显示
public static void main(String[] args) {
JFrame f = new JFrame("LoL");
f.setSize(400, 300);
f.setLocation(200, 200);
f.setLayout(new BorderLayout());
String[] columnNames = new String[] { "id", "name", "hp", "damage" };
String[][] heros = new String[][] { { "1", "盖伦", "616", "100" },
{ "2", "提莫", "512", "102" }, { "3", "奎因", "832", "200" } };
JTable t = new JTable(heros, columnNames);
// 根据t创建 JScrollPane
JScrollPane sp = new JScrollPane(t);
//或则创建一个空的JScrollPane,再通过setViewportView把table放在JScrollPane中
// JScrollPane sp = new JScrollPane(t);
// sp.setViewportView(t);
// 把sp而非JTable加入到JFrame上,
f.add(sp, BorderLayout.CENTER);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
同时,我们还可以通过以下命令来设置表格的列宽度
// 设置列宽度
t.getColumnModel().getColumn(0).setPreferredWidth(10);
TableModel
在Model这种思想的指导下,数据和显示分离开来了
我们可以创建一个 HeroTableModel 继承AbstractTableModel ,进而实现了接口TableModel
public class HeroTableModel extends AbstractTableModel {
String[] columnNames = new String[] { "id", "name", "hp", "damage" };
String[][] heros = new String[][] { { "1", "a", "168", "50" },
{ "2", "b", "172", "60" }, { "3", "c", "181", "70" } };
// 返回一共有多少行
public int getRowCount() {
// TODO Auto-generated method stub
return heros.length;
}
// 返回一共有多少列
public int getColumnCount() {
// TODO Auto-generated method stub
return columnNames.length;
}
// 获取每一列的名称
public String getColumnName(int columnIndex) {
// TODO Auto-generated method stub
return columnNames[columnIndex];
}
// 单元格是否可以修改
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
// 每一个单元格里的值
public Object getValueAt(int rowIndex, int columnIndex) {
// TODO Auto-generated method stub
return heros[rowIndex][columnIndex];
}
}
通过TableModel与DAO结合显示数据库中Hero信息。
DAO使用HeroDAO
在TableModel中,使用从DAO返回的List作为TableModel的数据
通过table可以获取一个 TableSelectionModel,专门用于监听jtable选中项的变化
日期控件
我们想要面板显示日期可以通过两种方式
1.使用 datepicker.jar 包
public static void main(String[] args) {
JFrame f = new JFrame("LoL");
f.setSize(400, 300);
f.setLocation(200, 200);
f.setLayout(null);
final DatePicker datepick;
datepick = getDatePicker();
f.add(datepick);
JButton b = new JButton("获取时间");
b.setBounds(137, 183, 100, 30);
f.add(b);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(f, "获取控件中的日期:" + datepick.getValue());
System.out.println(datepick.getValue());
}
});
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
private static DatePicker getDatePicker() {
final DatePicker datepick;
// 格式
String DefaultFormat = "yyyy-MM-dd HH:mm:ss";
// 当前时间
Date date = new Date();
// 字体
Font font = new Font("Times New Roman", Font.BOLD, 14);
Dimension dimension = new Dimension(177, 24);
int[] hilightDays = { 1, 3, 5, 7 };
int[] disabledDays = { 4, 6, 5, 9 };
datepick = new DatePicker(date, DefaultFormat, font, dimension);
datepick.setLocation(137, 83);
datepick.setBounds(137, 83, 177, 24);
// 设置一个月份中需要高亮显示的日子
datepick.setHightlightdays(hilightDays, Color.red);
// 设置一个月份中不需要的日子,呈灰色显示
datepick.setDisableddays(disabledDays);
// 设置国家
datepick.setLocale(Locale.CHINA);
// 设置时钟面板可见
datepick.setTimePanleVisible(true);
return datepick;
}
但这种方式有缺陷,它不能设置时间,只能在创建控件的时候传入指定日期。
2.JXDatePicker
public static void main(String[] args) {
JFrame f = new JFrame("LoL");
f.setSize(400, 300);
f.setLocation(200, 200);
f.setLayout(null);
Date date = new Date();
final JXDatePicker datepick = new JXDatePicker();
// 设置 date日期
datepick.setDate(date);
datepick.setBounds(137, 83, 177, 24);
f.add(datepick);
JButton b = new JButton("获取时间");
b.setBounds(137, 183, 100, 30);
f.add(b);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 获取 日期
Date d = datepick.getDate();
JOptionPane.showMessageDialog(f, "获取控件中的日期 :" + d);
}
});
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}