計算器3.0:實現用戶自定義組件

前言:

馬總給我提出計算器3.0新需求:可以在頁面上輸入一個組件,用戶的組件庫里面就多一個組件,用戶就可以使用

一、解決方法:

1. 新增成員變量和初始化

// 新增的輸入框
private InputBox newInputBox;
// 新增的組件面板
private JPanel newComponentsPanel;

newInputBox:用于用戶輸入自定義組件內容(數字或運算符)的輸入框。
newComponentsPanel:用于展示用戶通過輸入框添加的自定義組件按鈕。
2. 初始化界面組件方法,新增了以下部分:

 // 新增的輸入組件面板JPanel newInputPanel = new JPanel();newInputPanel.setLayout(new FlowLayout(FlowLayout.LEFT));// 新增的標簽JLabel newInputLabel = new JLabel("請添加組件:");newInputPanel.add(newInputLabel);// 新增的輸入框newInputBox = new InputBox(inputBoxes.size() + 1);newInputPanel.add(newInputBox.getPanel());// 新增的添加組件按鈕JButton addComponentButton = new JButton("添加組件");addComponentButton.addActionListener(e -> handleAddComponent());newInputPanel.add(addComponentButton);// 新增的組件標簽JLabel newComponentsLabel = new JLabel("用戶自定義組件:");newInputPanel.add(newComponentsLabel);// 新增的組件面板newComponentsPanel = new JPanel();newComponentsPanel.setLayout(new FlowLayout(FlowLayout.LEFT));// 為新增組件面板添加水平滾動條(當內容超出寬度時可滾動)JScrollPane scrollPane2 = new JScrollPane(newComponentsPanel);scrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);scrollPane2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);                                // 底部面板采用網格布局,4行1列,水平間距5,垂直間距2jp_below.setLayout(new GridLayout(4, 1,5,2));add(jp_below, BorderLayout.SOUTH);// 將按鈕面板添加到底部面板第2行jp_below.add(buttonPanel);// 將新增組件面板的滾動面板添加到底部面板第3行jp_below.add(newInputPanel);jp_below.add(scrollPane2);

創建了一個新的面板newInputPanel,用于容納所有新增組件。
添加了 “請添加組件:” 標簽和自定義輸入框newInputBox。
添加了 “添加組件” 按鈕,點擊后調用handleAddComponent()方法處理添加邏輯。
添加了 “新加的組件:” 標簽和newComponentsPanel面板,用于顯示用戶添加的自定義組件按鈕。并且為newComponentsPanel設置scrollPane2 滾動條。這樣當 newComponentsPanel 中的自定義組件過多時,用戶可以通過水平滾動條來查看所有組件。

新建了jp_below面板用于3行1列的布局,將按鈕面板,新增組件面板,滾動條添加進來。使得不會相互覆蓋,布局更美觀。


3. 處理添加組件邏輯(handleAddComponent方法)
?

/*** 處理"添加組件"按鈕的點擊事件* - 驗證用戶輸入是否為合法的數字或運算符* - 檢查組件是否已存在* - 若合法且不存在則創建新按鈕并添加到界面* - 若不合法或已存在則顯示錯誤提示*/private void handleAddComponent() {// 獲取用戶在輸入框中的內容并去除首尾空格String input = newInputBox.getText().trim();// 隱藏之前的錯誤提示newInputBox.hideError();// 驗證輸入是否為合法的數字或單個運算符if (!isNumber(input) && !isOperator(input)) {newInputBox.showError("輸入數字或單個運算符");return;}// 檢查組件是否已存在if (isComponentExists(input)) {newInputBox.showError("已經添加");return;}// 創建一個新按鈕,文本為用戶輸入內容JButton newButton = new JButton(input);// 為按鈕添加點擊事件監聽器newButton.addActionListener(e -> handleOperatorClick(input));// 設置按鈕的右鍵菜單(支持刪除功能)setupButtonContextMenu(newButton);// 將新按鈕添加到"新加的組件"面板newComponentsPanel.add(newButton);// 重新驗證面板布局并刷新顯示newComponentsPanel.revalidate();newComponentsPanel.repaint();// 清空輸入框并設置焦點newInputBox.setText("");newInputBox.requestFocus();}

獲取用戶在newInputBox中輸入的內容,檢查是否為數字或運算符。
如果是有效輸入,創建一個新按鈕,設置按鈕文本為輸入內容,并綁定點擊事件(調用原有的handleOperatorClick方法)。
為按鈕設置右鍵菜單(通過setupButtonContextMenu方法),支持刪除操作。
將按鈕添加到newComponentsPanel中并刷新界面。


4. 設置按鈕右鍵菜單(setupButtonContextMenu方法)
?

/*** 為按鈕設置右鍵菜單,支持刪除功能*/private void setupButtonContextMenu(JButton button) {// 創建右鍵彈出菜單JPopupMenu popupMenu = new JPopupMenu();// 創建"刪除"菜單項并添加點擊事件處理JMenuItem deleteItem = new JMenuItem("刪除");deleteItem.addActionListener(e -> {// 顯示確認對話框,防止誤操作int confirm = JOptionPane.showConfirmDialog(calculator3.this,"刪除按鈕 \"" + button.getText() + "\" 嗎?","確認刪除",JOptionPane.YES_NO_OPTION);// 用戶確認后執行刪除操作if (confirm == JOptionPane.YES_OPTION) {// 從面板移除按鈕組件newComponentsPanel.remove(button);// 重新計算布局并刷新UInewComponentsPanel.revalidate();newComponentsPanel.repaint();}});// 將菜單項添加到彈出菜單popupMenu.add(deleteItem);// 為按鈕添加鼠標監聽器,處理右鍵觸發邏輯button.addMouseListener(new MouseAdapter() {//鼠標按下事件處理:檢測是否為右鍵觸發條件@Overridepublic void mouseReleased(MouseEvent e) {if (e.isPopupTrigger()) {popupMenu.show(e.getComponent(), e.getX(), e.getY());}}});}

為自定義組件按鈕創建右鍵菜單,包含 “刪除” 選項。
點擊刪除時,檢查是否已完成計算(避免修改已計算的表達式),并通過確認對話框驗證是否刪除
確認后從newComponentsPanel中移除按鈕并刷新界面。

5、新增3.0版本按鈕

// 創建版本3.0切換按鈕JButton version3Button = new JButton("3.0");// 給版本2按鈕綁定點擊事件:顯示3.0版本信息version3Button.addActionListener(e -> showVersionInfo(3));// 將版本按鈕添加到版本面板versionPanel.add(version3Button);
//在showVersionInfo方法新增
else if (version == 3) {message = "3.0版本:\n增加用戶自定義組件,";}// 顯示信息對話框JOptionPane.showMessageDialog(this, message, "版本信息", JOptionPane.INFORMATION_MESSAGE);}

源碼在:java實現計算器3.0源碼-CSDN博客

二、小結

通過實現用戶自定義功能,對JFrame有了更深的理解,在BorderLayout將容器分為五個區域,將新增組件的面板放到South區域,會覆蓋原來的運算符組件面板。于是GridLayout布局管理器,可以將容器劃分為規則的網格(行 × 列),便于添加面板。并且當用戶自定義組件較多時,設置scrollPane?滾動條,用戶可以通過水平滾動條來查看所有組件。在用戶添加自定義組件時,會先檢驗是否為數字或者單個運算符和是否已經存在。校驗合理后綁定點擊事件(調用原有的handleOperatorClick方法)與原來的運算符組件有相同功能。

 

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

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

相關文章

PIG AI 全新升級:全新 MCP 能力加持,讓企業級 AI 開發效率翻倍!

你是否曾為 AI 應用的開發門檻而頭疼?調試代碼耗費數小時、集成外部工具需要復雜配置、想要快速構建智能系統卻不知從何下手…別擔心!PIG AI 最新版本帶來的 MCP(Model Context Protocol)能力,正為這些問題提供一站式解決方案。本文將帶你深入淺出地了解這一重磅升級,手把…

Springboot+vue超市管理系統的設計與實現

文章目錄前言詳細視頻演示具體實現截圖后端框架SpringBoot前端框架Vue持久層框架MyBaits成功系統案例:代碼參考數據庫源碼獲取前言 博主介紹:CSDN特邀作者、985高校計算機專業畢業、現任某互聯網大廠高級全棧開發工程師、Gitee/掘金/華為云/阿里云/GitHub等平臺持續…

一文快速了解Docker和命令詳解

本文讓你快速了解Docker是什么的東西,在我們程序開發的時候到底有什么作用,為什么需要去學習它。本文章只是做一個簡單的概述配套黑馬課程讓你快速了解、使用Docker。 一、什么是Docker? Docker是一個開源的容器化平臺,允許開發者…

【GaussDB】如何從GaussDB發布包中提取出內核二進制文件

【GaussDB】如何從GaussDB發布包中提取出內核二進制文件 背景 GaussDB 從505和506版本起(前面的版本不清楚),華為官方不再提供用腳本安裝GaussDB的方式(應該是基于運維交付標準化的角度考慮),僅支持使用T…

ETH 交易流程深度技術詳解

概述在前面對 PolkaVM 和 Revive 的文章中,我們介紹了很多技術細節,開發工具。還對比 EVM,知道了 PolkaVM 的優勢。很多同學還是對 Polkadot SDK 為什么可以運行 EVM 兼容的智能合約,以及交易處理的整個流程不太清楚。這篇文章將會…

【算法訓練營Day17】二叉樹part7

文章目錄二叉樹的最近公共祖先二叉搜索樹的最近公共祖先二叉搜索樹中的插入操作刪除二叉搜索樹中的節點二叉樹的最近公共祖先 題目鏈接:236. 二叉樹的最近公共祖先 解題邏輯: 最近公共祖先的定義為:對于有根樹 T 的兩個節點 p、q&#xff0c…

Vue插件與組件核心區別詳解

在 Vue 中,插件(Plugin) 和 組件(Component) 是兩種不同層次的概念,它們的主要區別如下:1. 組件 (Component) 定義: Vue 應用的基本構建單元,是可復用的 Vue 實例&#x…

基礎NLP | 02 深度學習基本原理

文章目錄 深度學習基本原理 數學基礎 線代 numpy 常用操作 導數, 梯度 梯度下降法 梯度下降代碼 GradientDescent.py 反向傳播 完整的反向傳播過程 權重更新方式 pytorch 網絡結構 全連接層 (線性層) 例子 - 手動實現模擬一個線性層 DNNforward.py 激活函數 激活函數-Sigmoid…

MySQL面試題及詳細答案 155道(001-020)

《前后端面試題》專欄集合了前后端各個知識模塊的面試題,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs&…

Ansible安裝與入門

目錄 Ansible ansible任務執行模式 ansible執行流程 ansible命令執行過程(背會) ansible的安裝方式 ansible的程序結構(yum安裝為例) ansible的配置文件查找順序(背會) 核心配置文件 ansible的配置…

【Spring】Spring Boot啟動過程源碼解析

目錄 一、啟動入口 二、SpringApplication的構造過程 2.1 設置應用類型 2.2 設置初始化器(Initializer) 2.2.1 獲取BootstrapRegistryInitializer對象 2.2.2 獲取ApplicationContextInitializer對象 2.3 設置監聽器(Listener&#xff…

CDN架構全景圖

CDN架構全景圖 CDN(內容分發網絡)是一種通過在全球范圍內部署邊緣節點服務器,將內容緩存至離用戶最近的位置,從而加速內容分發、降低延遲并減輕源站壓力的分布式網絡架構。其核心設計目標是優化互聯網內容傳輸效率,提升…

【pytest高階】源碼的走讀方法及插件hook

一、pytest源碼走讀方法 依賴庫認知篇 📦這是理解 pytest 源碼的 “前菜”,先認識 3 個超重要的小伙伴:iniconfig 📄:像個 “文件小管家”,專門負責讀取 ini 配置文件(比如 pytest 的配置&#…

算法訓練營day32 動態規劃理論基礎、509. 斐波那契數、70. 爬樓梯、746. 使用最小花費爬樓梯

今天開始動態規劃的部分! 其實說白了,動態規劃我感覺就是找類似遞歸的規律, 動態規劃理論基礎 動態規劃,英文:Dynamic Programming,簡稱DP,如果某一問題有很多重疊子問題,使用動態規…

基于神經網絡的手寫數字識別系統

基于神經網絡的手寫數字識別系統 結合模板匹配和神經網絡兩種方法進行手寫數字識別。這個系統包括圖像預處理、特征提取、神經網絡訓練和可視化分析。 %% 基于神經網絡的手寫數字識別系統%% 清理工作區 clear; clc; close all;%% 加載手寫數字數據集 % 使用MATLAB自帶的手寫數字…

機器學習?一文看懂這門熱門技術

🌟 什么是機器學習?一文看懂這門熱門技術在人工智能(AI)的大潮中,機器學習(Machine Learning, ML) 無疑是最耀眼的明星之一。它讓計算機具備了 “自我學習” 的能力,讓自動駕駛、智能…

Spring的初始化鉤子

1. PostConstruct JSR-250 標準注解(不是 Spring 獨有),用來標記 Bean 初始化完成后要執行的方法。會在 Bean 的構造方法執行完、依賴注入完成后執行。 使用實例: Component public class Demo {PostConstructpublic void init() …

【AI】Java生態對接大語言模型:主流框架深度解析

文章目錄1. Deep Java Library (DJL)2. LangChain4j(LLM)3. HuggingFace Inference API4. OpenAI Java Client技術對比矩陣架構設計建議在人工智能浪潮下,大語言模型(LLM)已成為技術核心。Java生態通過以下框架實現高效…

【06】C#入門到精通——C# 多個 .cs文件項目 同一項目下添加多個 .cs文件

文章目錄1 單個 .cs文件2 創建 多個 .cs文件2.1 添加Hero類2.1 添加ShowInfo類2.3 關于命名空間的引用2.4 所有.cs文件代碼3 test3項目文件下載1 單個 .cs文件 上一講中 描述游戲中英雄的角色 所有代碼在一個.cs文件中, 如果代碼很多,類很多&#xff0…

【MySQL基礎篇】:MySQL常用數據類型的選擇邏輯與正確使用

?感謝您閱讀本篇文章,文章內容是個人學習筆記的整理,如果哪里有誤的話還請您指正噢? ? 個人主頁:余輝zmh–CSDN博客 ? 文章所屬專欄:MySQL篇–CSDN博客 文章目錄數據類型1.數據類型分類2.數值類型int整形類型bit位類型float小…