Java:"JOJO, 我不用控制台啦", 网友:谁去拿外卖?

背景:DIO想当吃播网红,嚷嚷着要JOJO去拿外卖,JOJO不服,让DIO写个投票小程序,在网友的见证下直播投票来决定谁去拿外卖。首先,JOJO仿照饿了么提出了需求。

需求:按空格生成0-99的随机整数,当前最小的数标记为“喂人民服务”。数字输出界面最多显示当前的10个数,且最小数总是显示在界面上的。

分析:主要是显示容器的选择,这里选择java.swing.JFrame来做界面容器,java.swing.Box来配置布局。添加JPanel监听键盘,JPanel内装配JTextArea显示抽奖结果,抽奖结果则存放在ArrayList中。抽奖时使用随机数算法直接调用java.lang.Math或java.util.Random中API

程序代码:

package com.oz.gacha;

import javax.swing.JFrame;
import javax.swing.Box;
import javax.swing.JLabel;
import java.awt.Font;
import com.oz.gacha.MyGachaJPanel;

/*
 * DIO用THE WORLD暂停时间后,极限速度下编写的抽奖用的窗口框架,
 * 这是一个顶层容器用于组合抽奖面板以实现抽奖的界面
 *
 * @Author OliverZang
 */
public class MyGachaJFrame extends JFrame{
  /*垂直盒容器,内嵌2个水平盒容器用于界面布局*/
  private Box parentBox;
  private Box nestedLabelBox;
  private Box nestedGachaBox;
  //组合放置于水平容器内的抽奖组件
  private MyGachaJPanel gachaPanel;
  //组合放置于水平容器内的抽奖标签
  private JLabel gachaLabel;

  /*
   * 抽奖窗口框架的默认构造器,使用后会生成一个置中,大小硬编码的,DIO不想改css的抽奖
   * 完整窗口界面
   */
  public MyGachaJFrame(){
    /* 创建3个Box容器 */
    nestedLabelBox = Box.createHorizontalBox();
    nestedGachaBox = Box.createHorizontalBox();
    parentBox = Box.createVerticalBox();
    /* 平平无奇的标签,装载入一个水平盒容器内 */
    gachaLabel = new JLabel("按空格投票,数字最小的去拿外卖");
    gachaLabel.setFont(new Font("宋体",Font.PLAIN,16));
    nestedLabelBox.add(gachaLabel);
    /* 将之前的抽奖面板装载入另一个水平盒容器 */
    gachaPanel = new MyGachaJPanel();
    nestedGachaBox.add(gachaPanel);
    /* 两个水平容器一次放入垂直容器,组成高达(误)*/
    parentBox.add(nestedLabelBox);
    parentBox.add(nestedGachaBox);

    /* 框架装配次级组件,添加面板键盘监听,设置窗口大小,
    设置程序关闭条件,设置窗口可视化 */
    setContentPane(parentBox);
    addKeyListener(gachaPanel);
    setSize(300,250);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

  }
}

package com.oz.gacha;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import java.awt.FlowLayout;
import java.awt.Font;
import java.util.ArrayList;
import java.util.regex.*;
/*
 * DIO用顶尖智慧编写的抽奖面板类,可以按空格键用来抽取0-99的随机整数,并显示在面板上
 *的文本显示框上,这个类可以组合到抽奖框架内完成窗口化。
 *
 * @Author OliverZang
 */
public class MyGachaJPanel extends JPanel implements KeyListener{

  private JTextArea gachaResults;   //抽奖结果的显示文本框
  private ArrayList<String> gachaList; //抽奖结果的存放表单
  private static final String TAG = " 喂人民服务"; //标签表示持有者去拿外卖
  /*
   * 默认的抽奖界面构造器,生成能够满足JOJO需求的界面配置
   */
  public MyGachaJPanel(){
    gachaList = new ArrayList<>();
    //awt界面布局流式,默认置中
    setLayout(new FlowLayout());
    /* 初始化文本框,10行1列,字体设置,设置不可编辑去除光标*/
    gachaResults = new JTextArea(10,1);
    gachaResults.setFont(new Font("黑体",Font.BOLD,14));
    gachaResults.setEnabled(false);
    //抽奖面板组件添加抽奖文本框
    add(gachaResults);
  }
  /*
   * 监听键盘按下事件,每次触发执行抽奖并显示结果
   * @Param e 触发按键事件
   */
  @Override
  public void keyPressed(KeyEvent e) {
      /*如果是空格,就抽一次奖,修改抽奖表,清空文本显示框,然后重新按列表填写文本框*/
      if (e.getKeyCode()==32){
        String result = gacha();
        modifyList(result);
        gachaResults.setText("");
        for(String s:gachaList){
          gachaResults.append(s + "\n");
        }
      }
  }
  /*
   *一次抽奖,返回一个0-99的随机整数
   */
  public String gacha(){
    int randomNum = (int)(Math.random()*100);
    String result = String.valueOf(randomNum);
    return result;
  }
  /*
   * 用于抽奖后,对于抽奖列表的修改。
   * 列表会对最小值附加TAG,表示此数的抽取者去拿外卖
   * 每次修改,列表会检查修减保持最多10行数据
   * @Param result
   * 一次抽奖后得到的数值字符串
   */
  public void modifyList(String result){
    //Pattern和Matcher组合,用于捕获字符串中的数字部分
    String pattern = "\\d+";
    Pattern ptn = Pattern.compile(pattern);
    Matcher mtr = null;
    //用于记录Tag在列表的位置
    int tagId = 0;

    //如果抽奖表空,第一数字总是最小的,添加Tag
    if(gachaList.size()==0){
      gachaList.add(result + TAG);
    }
    //如果抽奖表非空,需要找到带有Tag的最小数字符串
    else{
      for(int i=0;i<gachaList.size();i++){
        //利用正则取到长度>2的字符串中的数字部分
        if(gachaList.get(i).length()>2){
          tagId = i;
          mtr = ptn.matcher(gachaList.get(i));
          mtr.find();
          //将之前的最小值与当前抽取的值相比,如果后者更小则将Tag传递给后者
          if (Integer.parseInt(mtr.group())> Integer.parseInt(result)){
            gachaList.set(i,mtr.group());
            gachaList.add(result + TAG);
            //此时Tag位于表底部
            tagId = gachaList.size()-1;
            break;
          }else{
            gachaList.add(result);
            break;
          }
        }
      }
    }
    //添加完数据,还需要修减下列表显示内容,限定为10行
    if(gachaList.size()>10){
      //删除不持有Tag且最靠近头部的一行,即头部持有Tag就删第二行
      if(tagId != 0)
        gachaList.remove(0);
      else
        gachaList.remove(1);
    }

  }

  @Override
  public void keyReleased(KeyEvent e){}

  @Override
  public void keyTyped(KeyEvent e){}
}

测试

package com.oz;

import com.oz.gacha.*;

public class Test1{

  	public static void main(String[] args){
      MyGachaJFrame myFrame = new MyGachaJFrame();

    }

}

结果:
在这里插入图片描述

结论:java自带的古董swing体验了下,有点和以前写Android一样的感觉。模拟了个抽奖,高亮功能是这辈子不可能做的,要使用支持HTML的JTextPane太麻烦。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值