目录
一、效果图:
二、代码实现:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
/**
* 测试买票程序
* @author 石原酒酒
* @date 2020年11月9日
* @fileName Test.java
*
*/
public class Test {
public static void main(String[] args) {
new BuyCinemaTicket();
}
}
class BuyCinemaTicket extends JFrame{
private static final long serialVersionUID = 1L;//io序列化标志
//所有的票号信息
private List<String> totalTicket = new ArrayList<>();
//用户即将购买的票号信息
private List<String> userBuyTicket = new ArrayList<>();
//已经卖出去的票号信息
private List<String> userBuyAllTicket = new ArrayList<>();
//没有卖出去的票号信息
private List<String> noBuyTicket = new ArrayList<>();
//用户点击时选中的票号
private List<String> clickBuyTicket = new ArrayList<>();
private PanelDown panelDown;
//二、初始化窗体,构造方法
public BuyCinemaTicket() {
//1、指定窗体的位置,单位是像素px
setLocation(500, 200);
//2、指定窗体的大小,单位是像素px
setSize(600,500);
//3、点击窗体右上角关闭的时候结束程序
setDefaultCloseOperation(3);
//4、设置窗体是否可以被改变大小
setResizable(false);
//5、设置窗体的标题
setTitle("终极购票神器");
//6、布局
startLayout();
//7、窗体默认是隐藏的,需要手动显示窗体
setVisible(true);
setBackground(new Color(240 ,255 ,255));
//8、初始化20张票
for (int i = 1; i <= 20; i++) {
totalTicket.add("" + i);
noBuyTicket.add("" + i);
}
}
private void startLayout() {
//窗体使用边界布局,默认就是使用边界布局
setLayout(new BorderLayout());
//创建小黑板
PanelUp panelUp = new PanelUp();
//把panelDown局部变量提升为成员变量,目的是方便重画座位
//选中变量名,Ctrl + 1,convert local varible to field
panelDown = new PanelDown();
//添加小黑板
add(panelUp,BorderLayout.NORTH);
add(panelDown); //不写位置表示添加到中间位置。
}
//上面的小黑板(可以容纳其他组件的容器)
class PanelUp extends JPanel{
private static final long serialVersionUID = 1L;
//用户即将购买的票号
private JLabel ticketNumLabel;
public PanelUp() {
//窗体使用边界布局,默认就是使用边界布局
setLayout(new BorderLayout());
//JLabel:标签(透明胶布)
JLabel label1 = new JLabel("票号:"); //票号中文提示
ticketNumLabel = new JLabel("");//选择好的票号
JButton btn1 = new JButton("选号"); //选号按钮
btn1.setBackground(new Color(245,222,179));
/**
* 选号功能
* 1、动作监听:ActionListener
* 2、鼠标监听:MouseListener
* 3、键盘监听(2048小游戏)
*/
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//键盘录入,获取用户即将购买的票号
//JOptionPane.showInputDialog:
// 第一个参数表示输入对话框要显示在哪个组件上
// null默认显示在屏幕的最上方。
// 第二个参数表示对话框的提示信息
String userInput = JOptionPane.showInputDialog(PanelUp.this,
"请选择您要购买的票号,中间用逗号分隔!");
//设置JLabel标签的内容,把用户输入的票号显示在ticketNumLabel上
ticketNumLabel.setText(userInput);
}
});
/*//鼠标监听
btn1.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
//鼠标松开
System.out.println("鼠标松开");
}
@Override
public void mousePressed(MouseEvent e) {
//鼠标按下
System.out.println("鼠标按下");
}
@Override
public void mouseExited(MouseEvent e) {
//鼠标离开
System.out.println("鼠标离开");
}
@Override
public void mouseEntered(MouseEvent e) {
//鼠标进入
System.out.println("鼠标进入");
}
@Override
public void mouseClicked(MouseEvent e) {
//鼠标单击
System.out.println("鼠标单击");
}
});*/
JButton btn2 = new JButton("购票"); //购票按钮
/**
* 购票功能
*/
btn2.setBackground(new Color(255,250,240));
btn2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//1、获取用户即将购买的票号信息
String content = ticketNumLabel.getText();
//2、把票号信息添加到用户即将购买票号信息的集合中
if(content != null && content.length() != 0) {
String[] split = content.split(","); //使用逗号切割
for (int i = 0; i < split.length; i++) {
userBuyTicket.add(split[i]);
}
}
//3、判断用户即将购买的票号是否能够购买
// 规则:如果用户有手动点击需要购买的票号,就优先选择手动点击的票号
if(!clickBuyTicket.isEmpty()) {
//有手动点击需要购买的票号
boolean contains = noBuyTicket.containsAll(clickBuyTicket);
if(contains) {
//可以卖
//把用户即将购买的票号添加到所有卖出去票号的集合中
userBuyAllTicket.addAll(clickBuyTicket);
//没有卖出去票集合中移除用户即将购买的票号
noBuyTicket.removeAll(clickBuyTicket);
//清空用户即将购买的票号
clickBuyTicket.clear();
//重画座位
panelDown.repaint();
//提示信息
JOptionPane.showMessageDialog(PanelUp.this,
"恭喜购票成功");
}else {
//不能卖
JOptionPane.showMessageDialog(PanelUp.this,
"票号有误,请重新购买!");
}
}else {
//没有手动点击需要购买的票号
//1、判断是否可以购买,看没有卖出的票中是否包含用户即将购买的票号
boolean contains = noBuyTicket.containsAll(userBuyTicket);
if(contains && !userBuyTicket.isEmpty()) {
//可以卖
//把用户即将购买的票号添加到所有卖出去票号的集合中
userBuyAllTicket.addAll(userBuyTicket);
//没有卖出去票集合中移除用户即将购买的票号
noBuyTicket.removeAll(userBuyTicket);
//重画座位
panelDown.repaint();
//提示信息
JOptionPane.showMessageDialog(PanelUp.this,
"恭喜购票成功");
}else {
//不能卖
JOptionPane.showMessageDialog(PanelUp.this,
"票号有误,请重新购买!");
}
//清空用户即将购买的票号
userBuyTicket.clear();
}
}
});
//修改字体
label1.setFont(new Font("楷体", Font.BOLD, 30));
label1.setForeground(new Color(75,175 ,242));
ticketNumLabel.setFont(new Font("楷体", Font.BOLD, 30));
btn1.setFont(new Font("楷体", Font.BOLD, 30));
btn2.setFont(new Font("楷体", Font.BOLD, 30));
//将以上四个组件添加到小黑板中
add(label1,BorderLayout.WEST); //左边
add(ticketNumLabel); //中间
add(btn1,BorderLayout.EAST); //右边
add(btn2,BorderLayout.SOUTH); //下边
}
}
//下面的小黑板(可以容纳其他组件的容器)
class PanelDown extends JPanel{
private static final long serialVersionUID = 1L;
//构造方法
public PanelDown() {
//给下面的黑板添加一个鼠标监听
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
/**
* 1、获取鼠标点击位置的坐标
* 2、判断点击的位置是几号座位
* 3、判断当前票号是否已卖
* 已卖:提示当前票号已卖
* 未卖:选中
* 如果已经选中,不做任何操作
* 4、购票
*/
//1、获取鼠标点击位置的坐标
int xx = e.getX();
int yy = e.getY();
//2、判断点击的位置是几号座位
int i1 = -1;
int j1 = -1;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 4; j++) {
if(xx >= (20 + 143 *j) && xx <= (20 + 143 *j + 123)) {
j1 = j;
}
if(yy >= (20 + 70 *i) && yy <= (20 + 70 *i + 50)) {
i1 = i;
}
}
}
//点击的不是过道
if(i1 != -1 && j1 != -1) {
//获取座位号
int ticket = i1 * 4 + j1 + 1;
//3、判断当前票号是否已卖
boolean contains = userBuyAllTicket.contains("" + ticket);
if(contains) {
//这张票已卖,给个提示信息
JOptionPane.showMessageDialog(PanelDown.this,
"此票已售!");
}else {
//没有卖,把选中的票添加到用户点击时选中的票号集合中
boolean contains2 = clickBuyTicket.contains("" + ticket);
if(!contains2) {
clickBuyTicket.add("" + ticket);
//重画座位
repaint();
}
}
}
}
});
}
//画座位
public void paint(Graphics g) {
super.paint(g);
//所有的票都没有卖掉,画空座位
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 4; j++) {
g.drawRect(20 + 143 *j, 20 + 70 *i,
123, 50);
g.setFont(new Font("楷体", Font.BOLD, 25));
g.drawString("" + (i*4 + j+1),
10 + 143 *j + 123/2,
25 + 70 *i + 50/2);
}
}
//把卖出去的票画到相对应的座位上,把对应的座位填充颜色
//所有卖出去的票存放在userBuyAllTicket集合中
//遍历userBuyAllTicket集合,找出卖出去的票并在对应的座位上填充颜色
//迭代遍历userBuyAllTicket集合
Iterator<String> it = userBuyAllTicket.iterator();
while(it.hasNext()) {
//获取已经卖出去的票号
String ticket = it.next();
//填充颜色(如何获取票号在窗体中对应的坐标)
int i = getI(ticket);
int j = getJ(ticket);
//设置颜色(蓝色)
g.setColor(Color.PINK);
g.fillRect(20 + 143 *j, 20 + 70 *i,
123, 50);
//设置颜色
g.setColor(Color.black);
g.setFont(new Font("楷体", Font.BOLD, 25));
g.drawString("" + (i*4 + j+1),
10 + 143 *j + 123/2,
25 + 70 *i + 50/2);
}
//画用户点击时选中的号码
it = clickBuyTicket.iterator();
while(it.hasNext()) {
//获取已经卖出去的票号
String ticket = it.next();
//填充颜色(如何获取票号在窗体中对应的坐标)
int i = getI(ticket);
int j = getJ(ticket);
//设置颜色(绿色)
g.setColor(new Color(144 ,238, 144));
g.fillRect(20 + 143 *j, 20 + 70 *i,123, 50);
//设置颜色
g.setColor(Color.black);
g.setFont(new Font("楷体", Font.BOLD, 25));
g.drawString("" + (i*4 + j+1),10 + 143 *j + 123/2, 25 + 70 *i + 50/2);
}
}
//获取座位对应的行号,从0开始
public int getI(String ticket) {
//把字符串类型的数字转换成int类型的数字
int tic = Integer.parseInt(ticket);
return (tic-1)/4;
}
//获取座位对应的行号,从0开始
public int getJ(String ticket) {
switch (ticket) {
case "1":
case "5":
case "9":
case "13":
case "17":
return 0;
case "2":
case "6":
case "10":
case "14":
case "18":
return 1;
case "3":
case "7":
case "11":
case "15":
case "19":
return 2;
case "4":
case "8":
case "12":
case "16":
case "20":
return 3;
default:
return -1;
}
}
}
}