概述
1、员工管理系统(使用JOptionPane)
使用集合写
员工类:
package com.p04.homework; public class Employee { /** * 用户名 */ private final String user = "admin"; /** * 密码 */ private final String passWord = "123456"; /** * 员工姓名 */ private String name; /** * 员工工号 */ private String id; /** * 工资 */ private int salary; public Employee() { } public Employee(String name, String id, int salary) { this.name = name; this.id = id; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public double getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } public String getUser() { return user; } public String getPassWord() { return passWord; } @Override public String toString() { return id + " " + name + " " + salary +"n"; } }
员工管理系统:
package com.p04.homework; import javax.swing.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; /** * 使用Arraylist集合实现员工管理系统 */ public class EmployeeSystem { public static void main(String[] args) { /* 登录界面 */ /** * 系统里本来就有的三名员工 */ ArrayList<Employee> employees = new ArrayList<>(); employees.add(new Employee("张三","001",5000)); employees.add(new Employee("李四","002",7000)); employees.add(new Employee("王五","003",4000)); JOptionPane.showMessageDialog(null,"欢迎来到员工工资管理系统:"); //调用登录方法 login(employees); } /** * 登录 * @param employees * @return */ private static void login(ArrayList<Employee>employees){ //判断输入的用户名和密码是否正确(只有三次机会) for (int i = 0; i < 3; i++) { Employee employee = new Employee(); //输入用户名 String id = JOptionPane.showInputDialog(null,"请输入您的员工工号:"); //输入密码 String passWord = JOptionPane.showInputDialog(null,"请输入您的密码:"); if (id.equals(employee.getUser()) && passWord.equals(employee.getPassWord())){ JOptionPane.showMessageDialog(null,"恭喜您,登陆成功"); operationInterface(employees); break; }else { JOptionPane.showMessageDialog(null,"用户名或密码错误,请重新输入!您还有" + (2-i) + "次机会"); } } JOptionPane.showMessageDialog(null, "非法用户"); } /** * 主界面显示 * @param employees 全部的员工集合 */ private static void operationInterface(ArrayList<Employee>employees) { String str = "请选择: n 1、添加员工 n 2、显示员工信息 n 3、删除员工 n 4、查询员工信息 n 5、修改员工工资 n 6、按工资排序显示工资单 n 7、退出 n"; while (true){ String choice = JOptionPane.showInputDialog(null,str); switch (choice) { //1、添加员工 case "1": addEmployee(employees); break; //2、显示员工信息 case "2": queryEmployee(employees); break; //3、删除员工 case "3": deleteEmployee(employees); break; //4、查询员工信息 case "4": seekEmployee(employees); break; //5、修改员工工资 case "5": revampEmployeesalary(employees); break; //6、按工资排序显示工资单 case "6": sortEmployee(employees); break; //7、退出 case "7": JOptionPane.showMessageDialog(null,"已退出员工工资管理系统"); System.exit(0);//退出系统 default: JOptionPane.showMessageDialog(null,"对不起,您输入的选项有误,请重新输入"); } } } /** * 6、按工资排序显示工资单 * @param employees */ private static void sortEmployee(ArrayList<Employee>employees) { Collections.sort(employees, new Comparator<Employee>() { @Override public int compare(Employee o1, Employee o2) { return (int) (o1.getSalary() - o2.getSalary()); } }); queryEmployee(employees); } /** * 5、修改员工工资的方法 * @param employees */ private static void revampEmployeesalary(ArrayList<Employee>employees) { String name = JOptionPane.showInputDialog(null, "请输入员工的姓名:"); /** * 判断这个姓名存不存在 */ int index = checkName(employees,name); if (index != -1){ String salary = JOptionPane.showInputDialog(null, "请重新输入工资:"); employees.get(index).setSalary(Integer.parseInt(salary)); String str = "工号 姓名 工资" + "n"; str += employees.get(index); JOptionPane.showMessageDialog(null,str); } } /** * 4、查询员工信息方法 * @param employees */ private static void seekEmployee(ArrayList<Employee>employees) { String name = JOptionPane.showInputDialog(null, "请输入员工的姓名:"); /** * 判断这个姓名存不存在 */ int index = checkName(employees,name); if (index != -1){ String str = "工号 姓名 工资" + "n"; str += employees.get(index); JOptionPane.showMessageDialog(null,str); } } /** * 3、删除员工方法 * @param employees */ private static void deleteEmployee(ArrayList<Employee>employees) { String name = JOptionPane.showInputDialog(null, "请输入删除员工的姓名:"); /** * 判断这个姓名存不存在,调用方法 */ int index = checkName(employees,name); if (index != -1){ Employee employee = employees.get(index); employees.remove(employee); queryEmployee(employees); } } /** * 2、显示员工信息 * @param employees */ private static void queryEmployee(ArrayList<Employee>employees) { String str = "工号 姓名 工资" + "n"; for (int i = 0; i < employees.size(); i++) { str += employees.get(i); } JOptionPane.showMessageDialog(null,str); } /** * 1、添加员工的方法 * @param employees */ private static void addEmployee(ArrayList<Employee>employees) { String id = JOptionPane.showInputDialog(null, "请输入添加新员工工号:"); /** * 判断这个工号存不存在,如果存在,则重新输入,如果不存在则输入姓名和工资 */ if (checkId(employees,id) == true) { JOptionPane.showMessageDialog(null, "该工号已经存在,请重新输入"); return;//退出这个方法 } //新建一个员工对象 String name = JOptionPane.showInputDialog(null,"请输入姓名:"); String salary = JOptionPane.showInputDialog(null,"请输入工资:"); employees.add(new Employee(name,id,Integer.parseInt(salary))); JOptionPane.showMessageDialog(null, "添加员工成功。"); } /** * 验证工号是否存在 * @param employees 员工数组 * @param id 员工的工号 * @return 工号是否存在 */ private static boolean checkId (ArrayList<Employee>employees,String id){ for (int i = 0; i < employees.size(); i++) { if (employees.get(i).getId().equals(id)){ return true; } } return false; } /** * 验证姓名是否存在 * @param employees 员工数组 * @param name 员工的名字 * @return 工号是否存在 */ private static int checkName (ArrayList<Employee>employees,String name){ for (int i = 0; i < employees.size(); i++) { if (employees.get(i).getName().equals(name)){ return i; } } JOptionPane.showMessageDialog(null, "查无此人"); return -1; } }
使用超级数组的思想完成员工管理系统
员工类:
package com.p04.homework; /** * 员工类 */ public class Employee { /** * 用户名 */ private final String user = "admin"; /** * 密码 */ private final String passWord = "123456"; /** * 员工工号 */ private String id; /** * 员工姓名 */ private String name; /** * 员工工资 */ private int salary; public Employee() { } public Employee(String id, String name, int salary) { this.id = id; this.name = name; this.salary = salary; } public String getUser() { return user; } public String getPassWord() { return passWord; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } @Override public String toString() { return id + " " + name + " " + salary + "n"; } }
员工管理系统:
package com.p04.homework; import javax.swing.*; /** * 使用超级数组的思想完成员工管理系统 */ public class EmployeeSystem { //初始化一个长度为20的员工类的数组 private static Employee [] employees = new Employee[20]; //给定一个数组的已有元素个数变量 private static int size = 3; public static void main(String[] args) { //给系统中存放三个初始的员工 employees[0] = new Employee("001","张三",8000); employees[1] = new Employee("002","李四",4000); employees[2] = new Employee("003","王五",5500); JOptionPane.showMessageDialog(null,"欢迎使用员工管理系统"); //登录 loginIn(); } /** * 登录 */ private static void loginIn() { Employee employee = new Employee(); //如果用户三次以上没有输入正确信息,提示非法用户 for (int i = 0; i < 3; i++) { String user= JOptionPane.showInputDialog(null,"请输入用户名"); String pwd = JOptionPane.showInputDialog(null,"请输入密码"); if (employee.getUser().equals(user) && employee.getPassWord().equals(pwd)){ JOptionPane.showMessageDialog(null,"恭喜您,登陆成功"); operationInterface(); break; }else { JOptionPane.showMessageDialog(null,"用户名或密码错误,请重新输入,您还有"+ (2-i) +"次机会。"); } } JOptionPane.showMessageDialog(null,"非法用户"); } /** * 主界面 */ private static void operationInterface() { while (true){ String choose =JOptionPane.showInputDialog(null, "请选择: n 1、添加员工 n 2、显示员工信息 n 3、删除员工" + " n 4、查询员工信息 n 5、修改员工工资 n 6、按工资排序显示工资单" + " n 7、退出 n"); switch (choose){ //1、添加员工 case "1": addEmployee(); break; //2、显示员工信息 case "2": showEmployee(); break; //3、删除员工 case "3": deleteEmployee(); break; //4、查询员工信息 case "4": queryEmployee(); break; //5、修改员工工资 case "5": revampEmployeesalary(); break; //6、按工资排序显示工资单 case "6": sortEmployee(); break; //7、退出 case "7": JOptionPane.showMessageDialog(null,"已退出员工工资管理系统"); System.exit(0);//退出整个系统 default: JOptionPane.showMessageDialog(null,"对不起,您输入的选项有误,请重新输入"); } } } /** * 添加员工 */ private static void addEmployee() { String id = JOptionPane.showInputDialog(null,"请输入新员工的工号"); if (checkId(id) == true) { JOptionPane.showMessageDialog(null,"该工号已经存在,请重新输入"); return;//退出这个方法,回到主界面 } String name = JOptionPane.showInputDialog(null,"请输入新员工的姓名"); String salary = JOptionPane.showInputDialog(null,"请输入新员工的工资"); employees[size ++] = new Employee(id,name,Integer.parseInt(salary)); //判断数组存放满没,如果存放满了,则将数组长度+10 扩容 if (size == employees.length){ //新建一个数组,长度为原来数组长度加10 Employee [] newSmployees = new Employee[size + 10]; //复制原数组到新数组 System.arraycopy(employees,0,newSmployees,0,size); //将旧数组引用新数组 employees = newSmployees; } } /** * 判断员工工号是否存在 * @param id 员工工号 * @return 存在返回true,不存在返回false */ private static boolean checkId (String id){ for (int i = 0; i < size; i++) { if (employees[i].getId().equals(id)){ return true; } } return false; } /** * 显示员工信息 */ private static void showEmployee() { String string = "工号 姓名 工资" + "n"; for (int i = 0; i < size; i++) { string += employees[i]; } JOptionPane.showMessageDialog(null,string); } /** * 判断员工名字是否存在 * @return 存在返回这个人的数组下标,不存在返回-1. */ private static int checkName(){ String name = JOptionPane.showInputDialog(null,"请输入姓名"); for (int i = 0; i < size; i++) { if (name.equals(employees[i].getName())){ return i; } } JOptionPane.showMessageDialog(null,"查无此人"); return -1; } /** * 删除员工 */ private static void deleteEmployee() { int index = checkName(); if (index != -1){ for (int i = index; i < size-1; i++) { employees[i] = employees[i+1]; } JOptionPane.showMessageDialog(null, "删除员工成功"); size --; showEmployee(); } } /** * 查询员工信息 */ private static void queryEmployee() { int index = checkName(); if (index != -1){ String string = "工号 姓名 工资" + "n"; string += employees[index]; JOptionPane.showMessageDialog(null,string); } } /** * 修改员工工资 */ private static void revampEmployeesalary() { int index = checkName(); if (index != -1){ String salary = JOptionPane.showInputDialog(null,"请重新输入工资"); employees[index].setSalary(Integer.parseInt(salary)); showEmployee(); } } /** * 按工资排序显示工资单 */ private static void sortEmployee() { for (int i = 0; i < size; i++) { for (int j = i+1; j < size; j++) { if (employees[i].getSalary() > employees[j].getSalary()) { Employee employee = employees[i]; employees[i] = employees[j]; employees[j] = employee; } } } showEmployee(); } }
2、GUI的使用
GUI组件创建的方式:
1、设置布局管理器
2、设置GUI组件得位置和大小
3、将GUI组件加入容器
GUI——图像用户界面
JavaGUI发展三个阶段:
阶段1:awt——抽象窗体工具
第一代awt当中Java其实已经设计了比较完善的容器、组件、工具这些要用到GUI当中的类。
但是存在一个问题,awt当中带有外观的界面类,Java在设计的时候偷懒了。它采用的方式,当我们要显示这样的一个外观的时候,它不是自己去生成,而是首先到当前操作系统的图形库里面去找有没有现成的。如果有,就直接拿来用了。
但是这造成了一个问题,不同的操作系统的图形库对于同一个控件设计是有差异的。这种差异可能会导致JavaGUI程序的跨平台效果受到影响,所以这些awt种的控件类全部被重新设计了。
阶段2:swing——
这个阶段就把上面所说的可能有问题的控件类全部重新设计了。
它采用的方式是首先到当前操作系统的图像库里去匹配有没有现成控件,如果有它会检查这些控件的定义是否和Java自己的保持一致,如果一致就拿出来使用,否则就自己生成。
所以,我们讲的GUI开发,即使用了awt里面的工具类(颜色、字体),又使用了swing当中的控件类,所以也被称为awt+swing,即SWT开发。不管使用AWT还是SWT,它的特点都是纯Java语言开发。
阶段3:JavaFx
这个东西是一个独立的第三方GUI库,是由Googgle设计的,并且一直处在不断的完善当中。
它的功能很强大,设计种类很丰富,唯一问题就是在使用过程除了Java之外,还要用到别的技术,比如:XML。
容器和组件
在Swing里,提供了许多带外观的控件。所有的这些控件分为两类:
1、容器
首层容器:
整个应用程序最外层的容器,所有的中间容器和组件都包含在它的内部。
GUI当中有四个首层容器:
JFrame——要用到的;
JWindow;
JDialog——要用到的;
JApplet
中间容器:
是不能存在的,必须放在别的容器当中,然后它内部又可以放入中间容器或组件。
JPanel——要用
JLabel——要用
2、组件
JLabel——标签
JButton——按钮
JTestField——文本框
JPasswordField——密码框
JComboBox——下拉框
JRadioButton——单选框
JCheckBox——复选框
JTextArea——文本域
public class MyFrame extends JFrame { private Container contentP;//内容面板 private JLabel nameLabel; private JLabel imgLab; private JButton clearBtn; private JPasswordField pwdTxt; private JRadioButton maleBtn; private JRadioButton femaleBtn; private JTextArea msgArea; public MyFrame(){ this.setSize(400,400);//设置尺寸 //this.setLocation(0,0);//设置位置 this.setLocationRelativeTo(null);//设置窗体自动居中、 this.setTitle("我的第一个窗体");//标题 Toolkit tk = Toolkit.getDefaultToolkit();//获取owt专用的工具类 this.setIconImage(tk.createImage("img/pic1.jpg"));//设置图标 this.setResizable(false);//设置窗体大小是否能被改变 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭 this.addContent(); this.setVisible(true);//把窗体绘制到界面上,一定写在最后 } //自定义addContent方法,里面实现给窗体添加内容 private void addContent(){ //1、首先获取到内容面板 this.contentP = this.getContentPane();//获取内容面板 this.contentP.setBackground(Color.WHITE);//内容面板背景色 //设置窗体得布局管理器为null,布局管理器决定了窗体中组件的排列方式 //null空布局,称为绝对布局,利用组件得位置和大小定位组件 //使用绝对定位和定大小的方式放置组件 this.contentP.setLayout(null); //2、标签 this.nameLabel = new JLabel("用户名:"); this.nameLabel.setBounds(20,50,80,30);//设置位置和大小 this.nameLabel.setForeground(Color.GREEN);//设置前景色,也就是字体颜色 this.nameLabel.setFont(new Font("宋体",Font.PLAIN,10));//Font.BOLD:加粗;Font.ITALIC:斜体;Font.PLAIN:普通 this.nameLabel.setBorder(BorderFactory.createLineBorder(Color.RED));//设置边框 this.contentP.add(this.nameLabel); //3、图片 this.imgLab = new JLabel(); ImageIcon img = new ImageIcon("img/pic2.jpg"); img.setImage(img.getImage().getScaledInstance(100,100,Image.SCALE_DEFAULT)); this.imgLab.setIcon(img); this.imgLab.setBounds(120,50,100,100); this.contentP.add(this.imgLab); //4、按钮 this.clearBtn = new JButton(); /* this.clearBtn.setIcon(new ImageIcon("img/pic6.png")); this.clearBtn.setBounds(200,50,20,23); this.contentP.add(this.clearBtn);*/ this.clearBtn.setText("清除"); this.clearBtn.setIcon(new ImageIcon("img/pic5.png")); // this.clearBtn.setPressedIcon(new ImageIcon("img/pic7.png")); this.clearBtn.setRolloverIcon(new ImageIcon("img/pic7.png")); this.clearBtn.setBounds(200,50,140,50); this.contentP.add(this.clearBtn); //5、密码框 pwdTxt = new JPasswordField(); pwdTxt.setEchoChar('*'); pwdTxt.setBounds(50,200,120,30); this.contentP.add(pwdTxt); //6、单选框 this.maleBtn = new JRadioButton("男"); this.femaleBtn = new JRadioButton("女"); this.maleBtn.setSelected(true);//默认设置为被选中 this.maleBtn.setBounds(200,200,50,25); this.femaleBtn.setBounds(270,200,50,25); this.contentP.add(this.maleBtn); this.contentP.add(this.femaleBtn); //对单选框进行逻辑分组 ButtonGroup genderGroup = new ButtonGroup(); genderGroup.add(this.maleBtn); genderGroup.add(this.femaleBtn); //7、文本域 this.msgArea = new JTextArea(); ScrollPane scrollPane = new ScrollPane();//滚动条 scrollPane.add(this.msgArea); scrollPane.setBounds(50,250,300,150); this.contentP.add(scrollPane); } }
窗体
public class MyJFrame extends JFrame{ /*使用继承创建窗体更好一些,因为如果再main方法里面创建的话, 如果需要创建一个一摸一样的窗体,需要ctrl c + v 许多行代码, 而使用继承,直接再main方法里调用这个窗体方法就行了 */ public MyJFrame(int width ,int height){ //设置窗体得布局管理器,布局管理器决定了窗体中组件的排列方式 //null空布局,称为绝对布局,利用组件得位置和大小定位组件 this.setLayout(null); //创建GUI组件对象(按钮组件) JButton button = new JButton("确定"); JButton button1 = new JButton("ok"); //设置组件得位置和大小 button.setBounds(20,50,100,20); button1.setBounds(150,50,100,20); button.setBackground(Color.blue); button1.setBackground(Color.cyan); //将组件加入窗体 this.add(button); this.add(button1); //标签组件 JLabel jLabel = new JLabel("用户名"); //设置前景色,也就是字体颜色 jLabel.setForeground(Color.RED); //设置标签字体,第一个参数为字体类型,第二个参数为字体样式,第三个参数为字体大小 jLabel.setFont(new Font("黑体",Font.BOLD,20)); JLabel jLabel1 = new JLabel("密码"); jLabel1.setForeground(Color.blue); jLabel.setBounds(20,0,100,60); jLabel1.setBounds(200,20,50,20); this.add(jLabel); this.add(jLabel1); //文本框组件 JTextField textField = new JTextField(); JTextField textField1 = new JTextField(); textField.setBounds(90,20,100,20); textField1.setBounds(250,20,100,20); this.add(textField); this.add(textField1); //下拉框组件 JComboBox jComboBox = new JComboBox(new String [] {"学历","高中","大专","本科"}); jComboBox.setBounds(200,100,70,20); this.add(jComboBox); //复选框 JCheckBox checkBox = new JCheckBox("是否确定"); checkBox.setBounds(200,140,80,20); this.add(checkBox); //GUI组件遵循先进先出,后进后出的原则,越先添加的组件在越上层(背景图片最后加) //图片标签 //图片相对路径是相对于工程的路径 //创建图像对象 Image img = new ImageIcon("img/pic1.jpg").getImage(); //将图片压缩为指定大小 img = img.getScaledInstance(500,500,1); JLabel imgLabel = new JLabel(new ImageIcon("img/pic4.png")); imgLabel.setBounds(20,100,145,125); this.add(imgLabel); JLabel imgLabel1 = new JLabel(new ImageIcon(img)); imgLabel1.setBounds(0,0,500,500);//(背景图片最后加) this.add(imgLabel1); //这段代码放在窗体的最后。否则有些gui组件可能看不见 this.setSize(width,height); this.setVisible(true); this.setDefaultCloseOperation(3); this.setLocationRelativeTo(null); this.getContentPane().setBackground(Color.PINK); } public static void main(String[] args) { /*//创建窗体对象 JFrame jFrame = new JFrame(); //设置窗体大小 jFrame.setSize(500,500); //显示窗体 jFrame.setVisible(true); //设置窗体关闭,程序结束 jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//也可以写三 //窗体相对于屏幕居中 jFrame.setLocationRelativeTo(null);*/ new MyJFrame(500,500); // new MyJFrame(400,200); } }
布局管理器-Layout
布局管理器的任务是负责在容器上针对放入到其中的组件,进行大小和位置的控制。
在之前的GUI代码里,我们都使用的绝对布局的方式,即使用控件 .setBounds(x,y,width,height);
要让这句代码生效,我们都做了一句前置代码:容器.setLayout(null); 这句代码说明,在GUI设计里,容器其实是自带布局方案的,如果我们不把用null重新赋值取消掉,它不会按我们规范的大小和位置处理,而是用它自己自带的布局方案。
流布局——FlowLayout
JPanel的默认布局就是流布局。
特点:
1、自带根据add组件的顺序从上往下,从左往右,从中间开始的方式,自动排列他们。
2、组件大小,由该组件的内容进行自动调整适配。
3、容器大小的改变会改变组件的位置。
根据特点,发现FlowLayout是用来放各种组件的,但是最好不要放大范围的容器,最好是单行容器的使用。流布局适合于小范围的。
public class FlowFrame extends JFrame { private Container contentP; private JButton jb1; private JButton jb2; private JButton jb3; private JButton jb4; private JButton jb5; private JTextField nameTex; public FlowFrame(){ this.setSize(400,400);//设置尺寸 this.setLocationRelativeTo(null);//设置窗体自动居中 Toolkit tk = Toolkit.getDefaultToolkit();//获取owt专用的工具类 this.setResizable(false);//设置窗体大小是否能被改变 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭 this.addContent(); this.setVisible(true);//把窗体绘制到界面上,一定写在最后 } private void addContent() { //1、首先获取到内容面板 this.contentP = this.getContentPane();//获取内容面板 this.contentP.setBackground(Color.WHITE);//内容面板背景色 this.contentP.setLayout(new FlowLayout());//设置布局管理器为流布局 this.jb1 = new JButton("按钮1按钮1按钮1按钮1按钮1"); this.jb2 = new JButton("按钮2"); this.jb3 = new JButton("按钮3"); this.jb4 = new JButton("按钮4"); this.jb5 = new JButton("按钮5"); this.contentP.add(jb1); this.contentP.add(jb2); this.contentP.add(jb3); this.contentP.add(jb4); this.contentP.add(jb5); this.nameTex = new JTextField();//文本框 this.nameTex.setColumns(20);//设置列数 this.contentP.add(nameTex); } }
边界布局——BorderLayout
JFrame的内容面板默认使用
特点:
1、把整个容器按“东西南北中”划分为五个部分;南北要贯通。
2、“中间最大”!这里的最大指的是中间默认的区域最大;东西南北的大小依赖于内容控制;另外,还指代中间的权力最大:当周边不存在的时候,中间会去占领周边;但中间不存在的时候,周边是不能占领中间的。
根据特点:BorderLayout的作用主要是用来在上层容器中规划区域,然后放入中间容器。
public class BorderFrame extends JFrame { private Container contentP; private JButton jb1; private JButton jb2; private JButton jb3; private JButton jb4; private JButton jb5; private JTextField nameTex; public BorderFrame(){ this.setSize(400,400);//设置尺寸 this.setLocationRelativeTo(null);//设置窗体自动居中 Toolkit tk = Toolkit.getDefaultToolkit();//获取owt专用的工具类 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭 this.addContent(); this.setVisible(true);//把窗体绘制到界面上,一定写在最后 } private void addContent() { //1、首先获取到内容面板 this.contentP = this.getContentPane();//获取内容面板 this.contentP.setBackground(Color.WHITE);//内容面板背景色 this.contentP.setLayout(new BorderLayout());//设置布局管理器为流布局 this.jb1 = new JButton("按钮1"); this.jb2 = new JButton("按钮2"); this.jb3 = new JButton("按钮3"); this.jb4 = new JButton("按钮4"); this.jb5 = new JButton("按钮5"); this.contentP.add(jb1,BorderLayout.NORTH);//北 this.contentP.add(jb2,BorderLayout.SOUTH);//南 this.contentP.add(jb3,BorderLayout.WEST);//西 this.contentP.add(jb4,BorderLayout.EAST);//东 this.contentP.add(jb5,BorderLayout.CENTER);//中,如果不写也是默认为中 } }
网格布局——GridLayout
特点:
1、把容器划分为N行M列等大的区域
2、按照add的顺序一行一行依次放入内容。
3、当划分区域的数目与放入内容的数目不相符的时候,优先保证行不变,有可能会去改变列。
根据特点:GridLayout的作用仍然是用于在容器上划分区域放置中间容器为主的。
public class GridFrame extends JFrame { private Container contentP; private JButton jb1; private JButton jb2; private JButton jb3; private JButton jb4; private JButton jb5; private JButton jb6; private JTextField nameTex; public GridFrame(){ this.setSize(400,400);//设置尺寸 this.setLocationRelativeTo(null);//设置窗体自动居中 Toolkit tk = Toolkit.getDefaultToolkit();//获取owt专用的工具类 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭 this.addContent(); this.setVisible(true);//把窗体绘制到界面上,一定写在最后 } private void addContent() { //1、首先获取到内容面板 this.contentP = this.getContentPane();//获取内容面板 this.contentP.setBackground(Color.WHITE);//内容面板背景色 this.contentP.setLayout(new GridLayout(3,2));//设置布局管理器为流布局 this.jb1 = new JButton("按钮1"); this.jb2 = new JButton("按钮2"); this.jb3 = new JButton("按钮3"); this.jb4 = new JButton("按钮4"); this.jb5 = new JButton("按钮5"); this.jb6 = new JButton("按钮6"); this.contentP.add(jb1); this.contentP.add(jb2); this.contentP.add(jb3); this.contentP.add(jb4); this.contentP.add(jb5); this.contentP.add(jb6); } }
卡片布局——CardLayout
它的作用:就像川剧变脸,给一个容器贴上几个面板,每次显示一个。
null布局
既可以 放组件,也可以放中间容器。、
设置窗体得布局管理器,布局管理器决定了窗体中组件的排列方式
null空布局,称为绝对布局,利用组件得位置和大小定位组件
this.setLayout(null);this.setVisible(true);//把窗体绘制到界面上,一定写在最后
复杂界面的面板嵌套开发
要做面板嵌套,首先要有中间容器。
中间容器主要有两种:JPanel,JLabel
JPanel是没有背景图片的情况下使用;
JLabel是需要设置背景图片的情况下使用。
事件处理模型
在掌握了足够的容器类、组件类、以及布局管理方式的基础上,我们就已经能够把一个界面完成了。
接下来,我们需要学习的是界面和操作者之间的人机交互。——这在所有的编程语言的GUI开发当中都称为"事件处理"。
Java当中的事件处理模型有一个特有的设计被称之为”委托事件模型“。
委托事件模型:
代表了在整个事件中代码部分有两种对象:
1、事件源对象(Event Source):——只负责界面的外观。
2、监听器对象(Event Listener):——负责事件处理。
两种对象的关系:
1、事件源对象必须要和监听器对象进行绑定。
2、监听器对象是有响应的事件的范围的。不是万能的;在GUI当中提供了各种的监听器,不同的监听器响应不同的事件;
3、一个监听器对象,可以监听多个事件源对象。一个事件源对象,可以同时被多个监听器监听。不同监听器处理发生在它身上的不同事件。
监听器
在Java当中,所有的监听器都设计了相应的接口类型,我们只需要通过实现接口,重写接口里的方法,然后绑定事件源就可以了。
这些接口都被放在java.awt.event包当中,取名字叫做Listener;
ActionListener——专用于处理按钮点击事件;
KeyListener——键盘事件
MouseListener——鼠标事件
WindowListener——窗体事件
监听器的用法
步骤:
1、选择合适的监听器接口。
2、实现这个接口,在对应的事件方法当中,书写上我们需要做出的响应代码;
3、产生监听器对象。
4、在对应的事件源对象身上绑定该监听器对象。
监听器接口的三种实现方式
方式一:书写一个单独的监听器实现类
优点:1、比较熟悉这种实现方式;2、这种书写方式可以根据单一职责,为不同的世事件源对象单独设计各自的监听器;
缺点:1、由于监听器类是单独的类,所以在复杂程序会导致程序的Java类文件数量加大,不利于文件管理。2、由于监听器是独立的类,所以要在监听器中操作除事件源之外的容器或组件都需要传参。
方式二:让容器类同时充当监听器
优点:1、容器类充当了监听器的实现类,不会增加多余的Java文件,便于管理;2、监听器如果要操作当前容器的组件,那么不需要传参。
缺点:1、不满足单一职责,每一个容器实现一种监听器只能实现一次,所以必须在同一事件触发方法中处理各种事件源的事件。
方式三:匿名内部类(最常用的)
优点:1、没有增加额外的Java文件;2、操作当前容器的组件无需传参;3、满足单一职责,每个事件源拥有各自独立的监听器对象。
public class ColorFrame extends JFrame{ private Container contentP; private JButton redBtn; private JButton greenBtn; public ColorFrame(){ this.setSize(400,400);//设置尺寸 this.setLocationRelativeTo(null);//设置窗体自动居中 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.addContent(); this.setVisible(true); } private void addContent() { this.contentP = this.getContentPane(); this.contentP.setLayout(new FlowLayout()); this.redBtn = new JButton("红色"); this.greenBtn = new JButton("绿色"); this.contentP.add(this.redBtn); this.contentP.add(this.greenBtn); //方式三--匿名内部类 this.redBtn.addActionListener( new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { ColorFrame.this.contentP.setBackground(Color.RED); ColorFrame.this.redBtn.setEnabled(false); ColorFrame.this.greenBtn.setEnabled(true); } } ); this.greenBtn.addActionListener( new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { ColorFrame.this.contentP.setBackground(Color.GREEN); ColorFrame.this.redBtn.setEnabled(true); ColorFrame.this.greenBtn.setEnabled(false); } } ); } public Container getContentP() { return contentP; } public void setContentP(Container contentP) { this.contentP = contentP; } public JButton getRedBtn() { return redBtn; } public void setRedBtn(JButton redBtn) { this.redBtn = redBtn; } public JButton getGreenBtn() { return greenBtn; } public void setGreenBtn(JButton greenBtn) { this.greenBtn = greenBtn; } }
卡片布局管理器——CardLayout
所谓的卡片布局管理器,与其他的布局管理不一样。其它的布局管理器都是在一个面板上进行区域的划分,只是不同的管理器划分的方式不一样而已。
null布局是指定大小位置进行划分;BorderLayout是东西南北中;
GridLayout是按照行列划分等大的区域。
卡片布局管理器是贴层的方式,在一个面板上进行贴层,每一层的大小都是一样的,每次显示一层,就像川剧“变脸”一样。
代码:按按钮实现简易的翻页的功能
/** * 按按钮实现简易的翻页的功能 */ public class CardFrame extends JFrame { private Container contentP; private SeasonPanel seasonP = new SeasonPanel(); private ButtonPanel buttonP = new ButtonPanel(this); public CardFrame(){ this.setSize(400,250); this.setLocationRelativeTo(null); this.setTitle("演示卡片布局"); this.setResizable(false); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.addContent(); this.setVisible(true); } private void addContent() { this.contentP = this.getContentPane();//获取内容面板 this.contentP.setLayout(new BorderLayout()); this.contentP.add(seasonP); this.contentP.add(buttonP,BorderLayout.SOUTH); } public Container getContentP() { return contentP; } public void setContentP(Container contentP) { this.contentP = contentP; } public SeasonPanel getSeasonP() { return seasonP; } public void setSeasonP(SeasonPanel seasonP) { this.seasonP = seasonP; } public ButtonPanel getButtonP() { return buttonP; } public void setButtonP(ButtonPanel buttonP) { this.buttonP = buttonP; } }
public class SeasonPanel extends JPanel { private SpringPanel springP; private SummerPanel summerP; private AutumnPanel autumnP; private WinterPanel winterP; public SeasonPanel(){ this.setBackground(Color.blue); this.setLayout(new CardLayout());//把面板的布局设置为卡片布局 this.springP = new SpringPanel(); this.summerP = new SummerPanel(); this.autumnP = new AutumnPanel(); this.winterP = new WinterPanel(); /* 放的顺序决定了贴层的顺序; 队列。第一个就是第一层; */ this.add("spring",this.springP);//卡片布局要求必须给卡片取别名,且不能重复 this.add("summer",this.summerP); this.add("autumn",this.autumnP); this.add("winter",this.winterP); } }
public class ButtonPanel extends JPanel { private JButton firstBtn = new JButton("|<"); private JButton preBtn = new JButton("<<"); private JButton nextBtn = new JButton(">>"); private JButton lastBtn = new JButton("|>"); private JButton autumnBtn = new JButton("秋"); public ButtonPanel(CardFrame cardF){ this.setBackground(Color.PINK); this.setLayout(new FlowLayout()); this.add(this.firstBtn); this.add(this.preBtn); this.add(this.nextBtn); this.add(this.lastBtn); this.add(this.autumnBtn); this.firstBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SeasonPanel seasonP = cardF.getSeasonP(); CardLayout cardLayout = (CardLayout) seasonP.getLayout(); cardLayout.first(seasonP); } }); this.preBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SeasonPanel seasonP = cardF.getSeasonP(); CardLayout cardLayout = (CardLayout) seasonP.getLayout(); cardLayout.previous(seasonP); } }); this.nextBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { /* 要想完成卡片布局的翻页,首先需要获取到被设置为 卡片布局管理器容器的容器类。在本例中就是SeasonPanel */ SeasonPanel seasonP = cardF.getSeasonP(); /* 不是由我们通过get方法取获取seasonP身上的卡片; 而是通过seasonP的布局管理器去获取。 */ CardLayout cardLayout = (CardLayout) seasonP.getLayout(); /* 利用cardLayout的方法完成翻页 */ cardLayout.next(seasonP); } }); this.lastBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SeasonPanel seasonP = cardF.getSeasonP(); CardLayout cardLayout = (CardLayout) seasonP.getLayout(); cardLayout.last(seasonP); } }); this.autumnBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SeasonPanel seasonP = cardF.getSeasonP(); CardLayout cardLayout = (CardLayout) seasonP.getLayout(); cardLayout.show(seasonP,"autumn"); } }); } }
public class SpringPanel extends JPanel { public SpringPanel(){ this.setBackground(Color.GREEN); } } public class SummerPanel extends JPanel { public SummerPanel(){ this.setBackground(Color.red); } } public class AutumnPanel extends JPanel { public AutumnPanel(){ this.setBackground(Color.orange); } } public class WinterPanel extends JPanel { public WinterPanel (){ this.setBackground(Color.white); } }
代码:轮播五张照片
/** * 轮播五张照片 */ public class CardJframe extends JFrame { private Container contentP; private JButton leftbottonP = new JButton("<<"); private JButton rightbottonP = new JButton(">>"); private ImgPanel imgL = new ImgPanel(); public CardJframe (){ this.setSize(400,250); this.setLocationRelativeTo(null); this.setTitle("轮播五张图片~"); this.setResizable(false); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.addContent(); this.setVisible(true); this.leftbottonP.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { CardLayout cardLayout = (CardLayout) imgL.getLayout(); cardLayout.previous(imgL); } }); this.rightbottonP.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { CardLayout cardLayout = (CardLayout) imgL.getLayout(); cardLayout.next(imgL); } }); } private void addContent() { this.contentP = this.getContentPane(); this.contentP.setLayout(new BorderLayout()); this.leftbottonP.setBackground(Color.green); this.rightbottonP.setBackground(Color.CYAN); this.add(imgL); this.contentP.add(leftbottonP,BorderLayout.WEST); this.contentP.add(rightbottonP,BorderLayout.EAST); } }
public class ImgPanel extends JPanel { private JLabel img1 = new JLabel(); private JLabel img2 = new JLabel(); private JLabel img3 = new JLabel(); private JLabel img4 = new JLabel(); private JLabel img5 = new JLabel(); public ImgPanel(){ this.setLayout(new CardLayout());//把面板的布局设置为卡片布局 // this.setBackground(Color.cyan); this.addImg(); } private void addImg() { ImageIcon img1 = new ImageIcon("img/pic1.jpg"); img1.setImage(img1.getImage().getScaledInstance(300,250,Image.SCALE_DEFAULT)); this.img1.setIcon(img1); ImageIcon img2 = new ImageIcon("img/pic2.jpg"); img2.setImage(img2.getImage().getScaledInstance(300,250,Image.SCALE_DEFAULT)); this.img2.setIcon(img2); ImageIcon img3 = new ImageIcon("img/pic3.jpg"); img3.setImage(img3.getImage().getScaledInstance(300,250,Image.SCALE_DEFAULT)); this.img3.setIcon(img3); ImageIcon img4 = new ImageIcon("img/pic4.JPG"); img4.setImage(img4.getImage().getScaledInstance(300,250,Image.SCALE_DEFAULT)); this.img4.setIcon(img4); ImageIcon img5 = new ImageIcon("img/pic5.JPG"); img5.setImage(img5.getImage().getScaledInstance(300,250,Image.SCALE_DEFAULT)); this.img5.setIcon(img5); this.add("pic1",this.img1); this.add("pic2",this.img2); this.add("pic3",this.img3); this.add("pic4",this.img4); this.add("pic5",this.img5); } }
总结注意点:
1、如果一个容器被设置为卡片布局管理器,这个容器本身设置的任何显示内容都不会显示出来,只会显示贴在它身上的卡片。
2、往卡片布局管理器里添加卡片的时候,第一个参数是给该卡片起的别名,同一个卡片布局管理器里的每张卡片别名不能重复。
3、在事件触发需要翻页的时候,是通过先获取到之前设置的卡片布局管理器,调用管理器的first/previous/next/last/show等方法完成翻页。其中show方法用的最多,因为在大部分业务场景里都是跳指定页面;另外四个方法主要是在轮播页面的时候才会使用。
监听器和适配器
我们在之前事件处理练习当中,目前只使用了ActionListener,但是其他的监听器,在使用方法上是和ActionListener保持一致的。
由于ActionListener里面只有一个抽象方法,所以我们重写的时候没有感到特别麻烦。但是其他的Listener有可能提供多个方法,而实际使用的时候我们只会用到其中的某一个或某几个,那么这个时候在我们代码里为了满足接口里所有的方法都被重写,就会有大量的空方法的实现。
JDK在设计时,对这种具有多个方法的接口,它采用了适配器的设计模式,它预先设计了一个抽象类,让它去实现接口,然后把接口里的方法都给空实现了。
public class MyFrame extends JFrame { public MyFrame(){ this.setSize(400,250); this.setLocationRelativeTo(null); this.setTitle("演示卡片布局"); this.setResizable(false); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.addContent(); this.setVisible(true); } private void addContent() { /** * KeyAdapter、MouseAdapter都是一个抽象类,并且实现了KeyListener、MouseListener接口里的所有方法,函数体全部为空。 * 想要使用哪个方法,就用哪个方法就可以了。 */ this.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent e) { System.out.println(e.getKeyChar()); } }); this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { System.out.println(e.getX() + "," + e.getY()); } @Override public void mouseWheelMoved(MouseWheelEvent e) { System.out.println(e.getWhen()); } }); } }
JOptionPane.shouMessageDialog里面的第一个参parentCompon代表的是父组件,它的作用是:如果填入null,则窗体显示在整个电脑屏幕的正中央,如果填入的是某一个对象,则显示在这个对象的正中央。
JOptionPane.showMessageDialog(null, "请猜测50——99之间的数字!");
3、自己写的一个超级数组
实现任意对象数组的增加元素,删除元素,查找元素,任何规则的排序这个数组
SuperArray
package com.J190.superarray;
import java.util.Arrays;
public class SuperArray {
private Object [] arrays = new Object[20];
private int size = 0;
public SuperArray() {
}
public int getSize() {
return size;
}
/**
* 添加元素
* @param object
*/
public void add (Object object){
this.arrays[this.size++] = object;
if (this.size >= this.arrays.length){
Object[] newArrays = new Object[this.arrays.length+10];
System.arraycopy(this.arrays,0,newArrays,0,size);
this.arrays = newArrays;
}
}
/**
* 删除数组元素
* @param index
*/
public void remove(int index) {
Object object = this.get(index);
if (object != null) {
System.arraycopy(this.arrays, index + 1, this.arrays, index, this.arrays.length - index - 1);
--this.size;
}
}
/**
* 查找数组元素
* @param index
* @return
*/
public Object get(int index) {
if (index >= 0 && index <= this.arrays.length - 1) {
return this.arrays[index];
} else {
System.out.println("该数组里没有这个索引。");
return null;
}
}
/**
* 按照任意数组对象属性排序
* 设计一个对象数组排序方法,要求可以实现任何对象数组、任何规则的排序。
* @param iCompator
*/
public void SortArray(ICompator iCompator){
if (this.size != 0) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
//调用比较接口方法,传递两个数组的元素,如果结果大于0,则交换元素
if (iCompator.compare(arrays[i],arrays[j])>1){
Object obj = arrays[i];
arrays[i] = arrays[j];
arrays[j] = obj;
}
}
}
}
}
//重写toString方法
@Override
public String toString() {
Object[] objects = new Object[size];
for (int i = 0; i < size; i++) {
objects[i] = arrays[i];
}
return "当前数组是"+ "n" + Arrays.toString(objects);
}
}
接口ICompator,里面的campare负责的是比较两个数组里的元素,我们可以通过实现这个接口,重写这个compare方法,制定不同的比较规则。
package com.J190.superarray;
public interface ICompator {
public int compare(Object o1,Object o2);
}
我们写一个学生类来测试一下
package com.J190.superarray;
public class Student{
private String id;
private String name;
private int grade;
public Student() {
}
public Student(String id, String name, int grade) {
this.id = id;
this.name = name;
this.grade = grade;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + ''' +
", name='" + name + ''' +
", grade=" + grade +
'}' + "n";
}
}
package com.J190.superarray;
public class Test {
public static void main(String[] args) {
SuperArray superArray = new SuperArray();
//添加元素
superArray.add(new Student("001","张三",90));
superArray.add(new Student("002","李四",20));
superArray.add(new Student("003","王五",40));
superArray.add(new Student("004","赵六",60));
System.out.println(superArray.get(2));//删除元素
superArray.SortArray(new ICompator() {
/**
* 按照学生类的成绩排序
*/
@Override
public int compare(Object o1, Object o2) {
Student
student1 = (Student) o1;
Student
student2 = (Student) o2;
return student1.getGrade()- student2.getGrade();//降序
//
return student1.getGrade()- student2.getGrade();//升序
}
});
System.out.println(superArray);
}
}
最后
以上就是文静时光为你收集整理的JavaSE基础笔记——JOptionPane编写员工管理系统;GUI使用;写一个超级数组1、员工管理系统(使用JOptionPane)2、GUI的使用GUI——图像用户界面布局管理器-Layout复杂界面的面板嵌套开发事件处理模型 3、自己写的一个超级数组的全部内容,希望文章能够帮你解决JavaSE基础笔记——JOptionPane编写员工管理系统;GUI使用;写一个超级数组1、员工管理系统(使用JOptionPane)2、GUI的使用GUI——图像用户界面布局管理器-Layout复杂界面的面板嵌套开发事件处理模型 3、自己写的一个超级数组所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复