Java 學習筆記(進階篇3)

1. 美化界面

關鍵邏輯 1:

// 相對路徑:直接從項目的 src 目錄開始寫,不包含 D:\ 和個人名字
ImageIcon bg = new ImageIcon("src/image/background.png");
JLabel background = new JLabel(bg);

這兩行代碼是 Swing 中加載并顯示圖片的經典組合,核心是通過兩個類的協作完成 “讀取圖片→展示圖片” 的過程。

第一行:ImageIcon bg = new ImageIcon("src/image/background.png");

(1) ImageIcon?類
它是 Swing 專門用于處理圖像的工具類,主要功能是加載圖像文件(支持 png、jpg、gif 等格式)并存儲圖像數據。你可以把它理解為 “圖像的容器”—— 它會幫你完成讀取文件、解析圖像數據的底層工作,最終提供一個可供 Swing 組件直接使用的圖像對象。

(2) new ImageIcon(路徑)
這是調用?ImageIcon?的構造方法,參數是圖片的路徑(這里用的是相對路徑?src/image/background.png)。執行這行代碼時:

  • 程序會根據路徑找到?background.png?圖片文件;
  • 讀取圖片的像素、色彩等數據;
  • 創建一個?ImageIcon?對象?bg,這個對象內部就 “裝著” 這張圖片的所有數據。
第二行:JLabel background = new JLabel(bg);

作用:創建一個標簽組件,將前面加載好的圖片設置為標簽的內容,讓圖片能在界面上顯示。

(1) JLabel?類
它是 Swing 中的 “標簽” 組件,本質是一個 “小型容器”,可以用來顯示文本圖像(或兩者同時顯示)。它的作用類似網頁中的?<img>?標簽 —— 本身不存儲圖像數據,而是作為 “展示載體”。

(2) new JLabel(bg)
這是調用?JLabel?的構造方法,參數是前面創建的?ImageIcon?對象?bg(裝著圖片數據)。執行這行代碼時:

  • 創建一個?JLabel?對象?background
  • 告訴這個標簽:“你的顯示內容是?bg?里的圖片”;
  • 此時標簽已經 “綁定” 了圖片,但還不會直接顯示在窗口上(需要后續步驟)。

關鍵邏輯 2:

  this.getContentPane().add(background);  

(1) this:指當前的?JFrame?對象(假設這句代碼寫在繼承自?JFrame?的類中,比如之前的?MyJFrame3)。

(2) this.getContentPane()

  • getContentPane()?是?JFrame?類的一個方法,作用是獲取當前窗口的 “內容面板”(ContentPane?對象)
  • 這個方法返回的?ContentPane?才是真正能存放組件的容器。

(3) .add(background)

  • 調用?ContentPane?的?add()?方法,將組件(這里是?background?標簽,也就是包含圖片的標簽)添加到內容面板中。
  • 只有添加到內容面板后,background?標簽(以及它包含的圖片)才能在窗口中顯示出來。

關鍵邏輯 3:

jLabel.setBorder(new BevelBorder(1));

這句話的作用是給?JLabel?組件添加一個 “凹陷” 效果的立體邊框,讓組件(比如顯示圖片的標簽)看起來有 “凹下去” 的視覺層次感。

  • jLabel:要添加邊框的目標組件(比如顯示圖片的標簽、文本標簽等)。
  • setBorder(...)JLabel?繼承的方法(來自父類?JComponent),作用是給組件設置邊框(參數是一個邊框對象)。
  • new BevelBorder(1):創建一個 “斜面邊框” 對象,參數?1?對應?BevelBorder.LOWERED,即凹陷效果

2. 移動圖片

關鍵邏輯 1:為什么需要 else ?

for (int i = 0; i < tempArr.length; i++) {  // 遍歷一維數組tempArr的每個元素if (tempArr[i] == 0) {  // 如果當前元素是0(特殊值)x = i / 4;          // 計算0在二維數組中的行索引xy = i % 4;          // 計算0在二維數組中的列索引y} else {  // 如果當前元素不是0(普通值)data[i / 4][i % 4] = tempArr[i];  // 將值存入二維數組的對應位置}
}

(1) 在拼圖游戲中,0?通常代表?“空白塊”(沒有數字的空位),它的作用和其他帶數字的拼圖塊完全不同 —— 其他數字塊需要被顯示在界面上,而空白塊的核心作用是作為 “可移動的空位”,讓周圍的數字塊可以移動到這里。因此,0?不需要像普通數字那樣被 “記錄到數據數組?data?中”,而是需要單獨記錄它的位置x,y),這是由拼圖游戲的核心邏輯決定的。

(2) 功能定位:0?是 “空位”,而非 “拼圖塊”

拼圖游戲的本質是:通過移動數字塊填補空白,最終讓所有數字塊回到正確位置。

  • 普通數字(如?1,2,3...)是 “需要被顯示和移動的拼圖塊”,它們的位置需要被?data?數組記錄(data[x][y] = 數字),用于在界面上顯示對應的數字圖片。
  • 0?代表 “空白區域”(沒有拼圖塊的位置),它不需要被顯示(界面上這里是空的),因此不需要存入?data?數組
關鍵邏輯 2:關于 x-- 的理解、關于 initImage( ); 的理解
System.out.println("向下移動");
data[x][y] = data[x - 1][y];
data[x - 1][y] = 0;
x--;  //更新元素當前位置的行索引,記錄移動后的新位置
initImage();  //根據修改后的數據重新繪制界面,刷新顯示效果

(1) 這里的 x、y 表示空白方塊,假設?data?數組中,0?代表空白方塊,其他數字代表有內容的方塊。現在有一個空白方塊在?(x=2, y=1)?位置,它上方(x-1=1, y=1)有一個值為?5?的方塊,我們要讓?5?向下移動到空白位置。

(2) 代碼邏輯就變成了:

① System.out.println("向下移動");
提示:有元素要移動到下方的空白位置。

② data[x][y] = data[x - 1][y];
這里?x=2, y=1?是空白位置,x-1=1, y=1?是上方的有值元素(5)。
意思是:把上方的?5?放到空白位置?(2,1)?上。
執行后,空白位置被?5?填充,原來的?5?位置還沒清空。

③ data[x - 1][y] = 0;
把原來?5?所在的位置?(1,1)?設為?0(變成新的空白位置)。
現在,5?成功移動到了下方的空白位置,而原來的位置變成了新的空白。

④ x--;
空白位置原本在?x=2,現在移動到了上方的?x=1(原來?5?的位置)。
用?x--?更新空白位置的坐標(從 2 變成 1),這樣如果還要繼續移動(比如?5?還能再往下移),程序就知道 “現在的空白位置在?x=1”,可以繼續判斷下方是否還有空白。

⑤ initImage();
刷新界面,讓你看到 “5?移動到了下方,原來的位置變成了空白” 的效果。

3. 查看完整圖片、作弊碼和判斷勝利

關鍵邏輯 1:整體邏輯鋪墊
int code = e.getKeyCode();
  • e?是一個鍵盤事件對象(比如KeyEvent),當用戶按下鍵盤時會觸發這個事件。
  • getKeyCode()?是事件對象的方法,用于獲取用戶按下的按鍵對應的 “鍵碼”(每個按鍵有唯一的數字編碼,比如 65 對應字母 A,40 對應下箭頭等)。
  • 這行代碼的作用是:把用戶按下的按鍵編碼存到變量code中,方便后續判斷按的是哪個鍵。
關鍵邏輯 2:二維數組的 “靜態初始化”
else if (code == 87) {data = new int[][]{{1, 2, 3, 4},    // 拼圖第1行(數組索引0行):對應1、2、3、4號拼圖塊{5, 6, 7, 8},    // 拼圖第2行(數組索引1行):對應5、6、7、8號拼圖塊{9, 10, 11, 12}, // 拼圖第3行(數組索引2行):對應9、10、11、12號拼圖塊{13, 14, 15, 0}  // 拼圖第4行(數組索引3行):13、14、15號塊 + 0(空白塊)};initImage(); // 重新繪制界面,讓正確的拼圖布局和勝利圖片顯示出來
}

① 首先,這段代碼的本質是?創建一個 4 行 4 列的 int 類型二維數組,并直接給每個位置賦值,然后把這個 “正確排列的數組” 賦值給data變量(覆蓋原來打亂的拼圖數據)。

②?二維數組的 “行” 和 “列”

  • 里面的每一組{}代表 “一行”,比如{1,2,3,4}是第 1 行;每行里的數字(1、2、3、4)是 “列”,分別對應第 1 列、第 2 列、第 3 列、第 4 列。
  • 整個數組是 4 行 4 列,正好對應你游戲里的 “4x4 拼圖格子”。

4. 計步和菜單業務實現

關鍵邏輯 1:應用場景和定位事件源頭

Object obj = e.getSource();

①?先鋪墊:這行代碼的 “上下文”—— 事件處理:

  • 當用戶做了某個交互操作(比如點擊按鈕、選擇菜單、輸入文本),程序會生成一個 “事件對象”(通常用變量e表示,比如ActionEvent eMouseEvent e),這個e里包含了 “這個事件的所有信息”—— 而?e.getSource()?就是從這些信息里,找到 “觸發這個事件的源頭組件”
  • 你的拼圖游戲有 “重新游戲”“關閉游戲” 兩個菜單按鈕(JMenuItem),如果給這兩個按鈕共用一個事件處理器(比如都綁定到同一個 ActionListener),當用戶點擊其中一個時,程序需要知道 “到底點的是哪個按鈕”—— 這時候就需要?e.getSource()?來定位 “點擊的源頭”。

②?Object obj:用 Object 類型接收源頭,因為 “事件的觸發源頭” 可能是任何組件(比如 JButton 按鈕、JTextField 文本框、JMenuItem 菜單、JLabel 標簽等),這些組件都是不同的類,但它們有一個共同的父類 ——Object

假設沒有多態,我們要接收?e.getSource()?的返回值會面臨什么問題?

  • 如果源頭是?JMenuItem,就需要寫?JMenuItem obj = e.getSource();
  • 如果源頭是?JButton,又需要寫?JButton obj = e.getSource();
  • 如果有 10 種不同的組件觸發事件,就要寫 10 種不同類型的接收代碼 —— 這會導致代碼極度冗余,無法兼容多種場景。

關鍵邏輯 2:模態窗口(Modal Window)

jDialog.setModal(true); 

它是 Swing 界面開發中控制 “用戶操作流程” 的關鍵設置,尤其適合像 “登錄彈窗”“確認提示框” 這類需要用戶 “先處理完當前窗口,才能操作其他窗口” 的場景。反之,如果設置為?setModal(false)(非模態),彈窗彈出后,用戶可以隨意切換到其他窗口操作,不用管這個彈窗。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96153.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96153.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96153.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

BFD 概述

BFD簡介1.BFD:Bidirectional Forwarding Detection,雙向轉發檢查概述&#xff1a;毫秒級鏈路故障檢查&#xff0c;通常結合三層協議&#xff08;如靜態路由、vrrp、 ospf、 BGP等&#xff09;實現鏈路故障快速切換。作用&#xff1a;① 檢測二層非直連故障② 加快三層協議收斂底…

【嵌入式DIY實例-ESP32篇】-Flappy Bird游戲

Flappy Bird游戲 文章目錄 Flappy Bird游戲 1、游戲介紹 2、硬件準備與接線 3、代碼實現 《Flappy Bird》游戲以其引人入勝的玩法和簡約的設計風靡全球。本文將探討如何使用 OLED SSD1306 顯示屏和 ESP32 微控制器重現這款經典游戲。這個 DIY 項目不僅充滿樂趣,也是學習編程和…

[數據結構——lesson2.順序表]

目錄 學習目標 引言 1.什么是線性表&#xff1f; 2.什么是順序表&#xff1f; 2.1概念及結構 2.2 接口實現 2.2.1順序表的功能 1.順序表的初始化 2.打印數據 3.尾插數據 (1)檢查空間 (2)插入數據 4.尾刪數據 5.頭插數據 6.頭刪數據 7.數據查找 8.指定位置數據…

ChatGPT大模型訓練指南:如何借助動態代理IP提高訓練效率

隨著人工智能技術的飛速發展&#xff0c;ChatGPT等大型語言模型&#xff08;LLM&#xff09;已成為科技界和產業界關注的焦點。模型的訓練過程耗時、耗資源且對網絡環境要求極高。尤其是在需要模擬真實用戶行為、進行大規模數據爬取或分布式訓練的場景下&#xff0c;單一IP地址…

Docker 學習筆記(六):多容器管理與集群部署實踐

Docker Docker-compose 單個 Dockerfile 可定義單容器應用&#xff0c;但日常工作中&#xff0c;Web 項目等常需 Web 服務、數據庫、負載均衡等多容器配合&#xff0c;手動按序啟停容器會導致維護量大、效率低。 Docker Compose 是高效的多容器管理工具&#xff0c;通過單個 do…

C++類和對象初識

面向過程 1.1 面向過程特點 1.2 通俗解釋&#xff1a;煮方便面 1.3 面向過程實現代碼 1.4 特點總結面向對象 2.1 面向對象特點 2.2 通俗解釋&#xff1a;對象協作思維 2.3 面向對象實現代碼 2.4 特點總結面向對象和面向過程總結C 面向對象介紹 4.1 面向對象三大基本特征封裝&am…

C++ Int128 —— 128位有符號整數類實現剖析

&#x1f9e0; C Int128 —— 128位有符號整數類實現剖析 引用&#xff1a;openppp2/ppp/Int128.h &#x1f3d7;? 1. 存儲結構設計 #mermaid-svg-2JDFsdz6MTbX253D {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-sv…

【C 語言生成指定范圍隨機數(整數 + 小數):原理、實現與避坑指南】

概述 在 C 語言開發中&#xff0c;生成指定范圍的隨機數是高頻需求&#xff08;如游戲隨機道具、數據模擬、測試用例生成等&#xff09;。但很多新手會卡在 “范圍控制”“隨機數重復”“小數生成” 等問題上。本文結合實戰場景&#xff0c;從原理到代碼詳細講解如何生成 1100、…

一個簡單的langgraph agent系統

本文基于langgraph的預制件 Agent Chat UI和《搭建一個本地langgraph服務》中的本地服務構建一個簡單的agent系統。 說明&#xff1a;Agent Chat UI需要nodejs版本18及以上&#xff0c;而nodejs18需要的glibc版本為2.28&#xff0c;本人使用操作系統為ubuntu18.04&#xff0c;g…

通過SSH來推送本地文件夾到Github

配置SSH git使用SSH配置&#xff0c; 初始需要以下三個步驟 使用秘鑰生成工具生成rsa秘鑰和公鑰 將rsa公鑰添加到代碼托管平臺 將rsa秘鑰添加到ssh-agent中&#xff0c;為ssh client指定使用的秘鑰文件 具體操作如下&#xff1a; 第一步&#xff1a;檢查本地主機是否已經存在…

視頻轉webp批量處理工具哪個好?這里有答案

你是不是也遇到過這樣的困擾&#xff1a;手機里存滿了精彩的短視頻&#xff0c;想做成動圖分享到社交媒體&#xff0c;卻發現轉換后的GIF文件巨大無比&#xff0c;畫質還慘不忍睹&#xff1f;要怎么把手機視頻轉webp&#xff0c;才能既保持高清畫質&#xff0c;又能大幅減小文件…

【Fastjson】Fastjson2 在不同 Modules 模塊包下,@JSONField name映射無法反序列化的 BUG 及解決

問題&#xff1a;在使用 alibaba fastjson2 做 JSONField 字段名映射時&#xff0c;在同模塊包下 Flink Jar 任務正常映射&#xff0c;本地測試正常映射&#xff0c;但是將兩個模塊包上傳至 Flink Cluster 之后&#xff0c;出現反序列化異常&#xff0c;子模塊無法反序列化父模…

Go語言基礎---數據類型間的故事

Go語言基礎—數據類型間的故事 目錄 前言基本數據類型 整形字節特殊整形unsafe.Sizeof數字字面量語法浮點型布爾值字符串byte和rune類型 運算符 算術運算符關系運算符邏輯運算符位運算符賦值運算符 前言 Go語言是Google開發的一種靜態強類型、編譯型語言。Go語言語法與C相近…

dedecms軟件等級★號改成圖片圖標顯示的辦法

我們在用到dedecms織夢的軟件模型&#xff0c;在調用軟件星級的時候&#xff0c;要把默認的星號改為圖片&#xff0c;這個要怎么操作呢&#xff1f;1、軟件模型管理里面-字段管理-字段配置softrankislink一行改為&#xff1a;<field:softrank itemname軟件等級 typeint isnu…

windows下安裝claude code+國產大模型glm4.5接入(無需科學上網)

下載安裝node.js https://nodejs.org/en/download 安裝版.msi 直接下載安裝即可 免安裝版.zip 1.解壓下載的壓縮包 2.創建數據緩存存儲目錄cache和全局安裝工具目錄global 3.配置環境變量 【我的電腦】右鍵選中【屬性】-> 找到【高級系統設置】-> 右下角【環境變量…

嵌入式 - ARM4

裸機實現LED閃爍一、啟動代碼1. 異常向量表配置1. .global匯編器指令&#xff0c;全局定義標簽_start&#xff0c;作為匯編程序的默認起點2. 配置標簽配置標簽時可以前置加_ &#xff0c;以便和普通標簽或系統標簽做區分3. 異常向量表ARM架構規定異常向量表位置固定&#xff0c…

《C++ 108好庫》之2 多線程庫thread,mutex,condition_variable,this_thread

《C 108好庫》之之2 多線程庫thread&#xff0c;mutex&#xff0c;condition_variable&#xff0c;this_thread《C 108好庫》之2 多線程庫thread&#xff0c;mutex&#xff0c;condition_variable&#xff0c;this_threadstd::thread類??互斥量&#xff08;Mutex&#xff09;…

Android系統框架知識系列(二十):專題延伸:JVM vs ART/Dalvik - Android運行時演進深度解析

?關鍵詞?&#xff1a;運行時優化、AOT編譯、JIT編譯、內存管理、電池效率、性能分析一、Android運行時演進背景1. 移動環境的特殊挑戰Android運行時環境的演進源于移動設備的獨特限制&#xff1a;?移動設備約束條件?&#xff1a;?有限的內存資源?&#xff1a;早期設備僅1…

ubuntu 22 安裝輕量級桌面Xfce并使用xrdp遠程桌面連接

1.安裝Xfce:sudo apt install xubuntu-desktop -y2.安裝xrdp:sudo apt install xrdp -y3.配置xrdp&#xff0c;nano /etc/xrdp/xrdp.ini:[Globals] ... port3389 ; 遠程連接端口&#xff0c;默認是3389&#xff0c;可以改成自己喜歡的端口... ; ; Session types ;; Some sess…

【Flask】測試平臺開發,數據看板開發-第二十一篇

概述&#xff1a;在前面我們已經實現了我們的產品創建管理&#xff0c;應用管理管理&#xff0c;需求提測管理但是每周提測了多少需求&#xff0c;創建了哪些產品&#xff0c;我們是不是看著不是很直觀&#xff0c;接下來我們就需要開發一個數據看板功能&#xff0c;實現能夠看…