1. 程式人生 > >Java:"JOJO, 我不用控制檯啦", 網友:誰去拿外賣?

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太麻煩。