Java:"JOJO, 我不用控制檯啦", 網友:誰去拿外賣?
阿新 • • 發佈:2019-01-06
背景: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太麻煩。