12.8Java Swing 中的MVC

在 Java Swing 中,MVC 模式被廣泛應用。例如,JTable、JList 等組件都采用了這種模式。通常:

  • 模型:實現特定的 Swing 模型接口(如 TableModel、ListModel)。
  • 視圖:是 Swing 組件本身(如 JTable、JList)。
  • 控制器:通常隱含在組件內部,或由開發者實現為事件監聽器。

JTableModel 是 Java Swing 中用于管理表格數據的核心接口,它是 MVC(Model-View-Controller)模式在表格組件中的具體實現。JTable 作為視圖,負責顯示數據;而 JTableModel 作為模型,負責存儲和管理數據,并提供數據訪問接口。

JTableModel 接口方法

JTableModel 接口定義了以下核心方法:

  1. 基本結構方法

    • int getRowCount():返回表格的行數
    • int getColumnCount():返回表格的列數
    • String getColumnName(int columnIndex):返回指定列的名稱
    • Class<?> getColumnClass(int columnIndex):返回指定列的數據類型
  2. 數據訪問方法

    • Object getValueAt(int rowIndex, int columnIndex):獲取指定單元格的數據
    • void setValueAt(Object aValue, int rowIndex, int columnIndex):設置指定單元格的數據
  3. 可選方法

    • boolean isCellEditable(int rowIndex, int columnIndex):指定單元格是否可編輯

實現方式

JTableModel 有三種主要實現方式:

  1. DefaultTableModel

    • 最簡單的實現,使用 Vector 存儲數據和列名
    • 缺點:所有單元格數據類型被視為 Object,不支持類型安全
  2. AbstractTableModel

    • 抽象基類,提供了事件通知機制
    • 通常繼承此類并實現必要的方法
  3. 自定義 TableModel

    • 完全自定義實現,適用于復雜數據結構和特殊需求

案例:自定義 TableModel 實現

下面通過一個案例展示如何實現自定義 TableModel:

Main.java

import javax.swing.*;
import java.awt.*;public class Main {public static void main(String[] args) {SwingUtilities.invokeLater(() -> {// 創建主窗口JFrame frame = new JFrame("人員信息管理");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(500, 300);frame.setLocationRelativeTo(null);// 創建自定義TableModelPersonTableModel model = new PersonTableModel();// 添加示例數據model.addPerson(new Person("張三", 25, false));model.addPerson(new Person("李四", 30, true));model.addPerson(new Person("王五", 22, false));// 創建表格并關聯TableModelJTable table = new JTable(model);// 添加表格到滾動面板JScrollPane scrollPane = new JScrollPane(table);// 添加按鈕面板JPanel buttonPanel = new JPanel();JButton addButton = new JButton("添加");JButton deleteButton = new JButton("刪除");// 添加按鈕事件處理addButton.addActionListener(e -> {String name = JOptionPane.showInputDialog(frame, "請輸入姓名:");if (name != null && !name.isEmpty()) {String ageStr = JOptionPane.showInputDialog(frame, "請輸入年齡:");if (ageStr != null && !ageStr.isEmpty()) {try {int age = Integer.parseInt(ageStr);String marriedStr = JOptionPane.showInputDialog(frame, "是否已婚(true/false):");boolean married = Boolean.parseBoolean(marriedStr);model.addPerson(new Person(name, age, married));} catch (NumberFormatException ex) {JOptionPane.showMessageDialog(frame, "年齡必須是數字!");}}}});deleteButton.addActionListener(e -> {int selectedRow = table.getSelectedRow();if (selectedRow != -1) {model.deletePerson(selectedRow);} else {JOptionPane.showMessageDialog(frame, "請先選擇一行!");}});buttonPanel.add(addButton);buttonPanel.add(deleteButton);// 添加組件到窗口frame.getContentPane().add(scrollPane, BorderLayout.CENTER);frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);// 顯示窗口frame.setVisible(true);});}
}    

PersonTableModel.java?

import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.List;// 人員類,存儲表格中的一行數據
class Person {private String name;private int age;private boolean married;public Person(String name, int age, boolean married) {this.name = name;this.age = age;this.married = married;}public String getName() { return name; }public int getAge() { return age; }public boolean isMarried() { return married; }public void setName(String name) { this.name = name; }public void setAge(int age) { this.age = age; }public void setMarried(boolean married) { this.married = married; }
}// 自定義TableModel實現
public class PersonTableModel extends AbstractTableModel {private static final long serialVersionUID = 1L;// 列名數組private final String[] columnNames = {"姓名", "年齡", "已婚"};// 列數據類型數組private final Class<?>[] columnTypes = {String.class, Integer.class, Boolean.class};// 數據列表private final List<Person> data = new ArrayList<>();// 添加人員數據public void addPerson(Person person) {data.add(person);// 通知表格數據已插入fireTableRowsInserted(data.size() - 1, data.size() - 1);}// 更新人員數據public void updatePerson(int row, Person person) {data.set(row, person);// 通知表格數據已更新fireTableRowsUpdated(row, row);}// 刪除人員數據public void deletePerson(int row) {data.remove(row);// 通知表格數據已刪除fireTableRowsDeleted(row, row);}// 獲取指定行的人員數據public Person getPerson(int row) {return data.get(row);}// 返回表格行數@Overridepublic int getRowCount() {return data.size();}// 返回表格列數@Overridepublic int getColumnCount() {return columnNames.length;}// 返回列名@Overridepublic String getColumnName(int column) {return columnNames[column];}// 返回列數據類型@Overridepublic Class<?> getColumnClass(int columnIndex) {return columnTypes[columnIndex];}// 返回單元格數據@Overridepublic Object getValueAt(int rowIndex, int columnIndex) {Person person = data.get(rowIndex);switch (columnIndex) {case 0: return person.getName();case 1: return person.getAge();case 2: return person.isMarried();default: return null;}}// 設置單元格數據并使單元格可編輯@Overridepublic void setValueAt(Object value, int rowIndex, int columnIndex) {Person person = data.get(rowIndex);switch (columnIndex) {case 0: person.setName((String) value);break;case 1: person.setAge((Integer) value);break;case 2: person.setMarried((Boolean) value);break;}// 通知表格單元格數據已更新fireTableCellUpdated(rowIndex, columnIndex);}// 設置單元格是否可編輯@Overridepublic boolean isCellEditable(int rowIndex, int columnIndex) {return true; // 所有單元格都可編輯}
}    

JTableModel 關鍵特性

  1. 事件通知機制

    • AbstractTableModel 提供了事件通知方法:
      • fireTableDataChanged():整個表格數據已更改
      • fireTableStructureChanged():表格結構已更改
      • fireTableRowsInserted/Updated/Deleted():行數據更改
      • fireTableCellUpdated():單元格數據更改
  2. 列類型支持

    • 通過getColumnClass()方法返回列的數據類型
    • JTable 會根據列類型自動提供合適的渲染器和編輯器
  3. 單元格編輯

    • 通過isCellEditable()方法控制單元格是否可編輯
    • 通過setValueAt()方法處理編輯后的數據

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

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

相關文章

DDS(Data Distribution Service)

DDS&#xff08;Data Distribution Service&#xff09;是一種以數據為中心的發布/訂閱&#xff08;DCPS&#xff09;通信中間件協議棧標準&#xff08;由OMG組織維護&#xff09;。它專為高性能、可預測、實時、可靠的分布式系統設計&#xff0c;廣泛應用于國防、航空航天、工…

python爬蟲關于多進程,多線程,協程的使用

簡介&#xff1a; python其實沒有真正意義的多線程&#xff0c;因為有GIL鎖存在&#xff0c;但是python3.13去掉GIL鎖&#xff0c;有兩個版本&#xff0c;python3.13t和python3.13&#xff0c;python3.13去掉GIL鎖相當于python底層大規模改變&#xff0c;肯定會影響一些庫的使…

java 設計模式_行為型_23狀態模式

23.狀態模式 Java中的狀態設計模式是一種軟件設計模式&#xff0c;當對象的內部狀態更改時&#xff0c;該模式允許對象更改其行為。狀態設計模式通常用于以下情況&#xff1a;對象取決于其狀態&#xff0c;并且在運行期間必須根據其內部狀態更改其行為。狀態設計模式是許多行為…

Flink CDC MySQL 時區相差 8 小時問題優雅解決方式

Flink CDC MySQL 時區相差 8 小時問題解析 代碼運行環境 Flink 1.15 + FlinkCDC 2.4.0 + jdk1.8 +springboot 2.31、原因分析 Flink CDC 底層使用 Debezium 連接器來捕獲 MySQL 的數據變更,而 Debezium 在解析 MySQL 的 binlog 日志時,默認使用 UTC 時區來處理時間字段。若…

如何在 MX Linux 上安裝 Blender CAD 軟件

Blender 是一款免費且開源的 CAD 軟件,可用于 3D 動畫、建模、動態圖形、紋理處理、電腦游戲、UV 展開等。同時它也是一款專業的開源程序,是商業軟件(如 Maya 或 Cinema 4D)的替代品,支持導入或導出標準格式,如 OBJ、FBX、3DS、PLY 和 STL。Blender 還可以作為視頻編輯軟…

電腦上的.ssh目錄只做什么的

.ssh 目錄的作用和來源 系統自動創建 這個目錄是在你第一次使用SSH相關功能時自動創建的比如第一次執行 ssh 命令連接服務器時或者使用Git通過SSH協議克隆代碼時 主要用途 SSH密鑰存儲 - 存放公鑰/私鑰對已知主機記錄 - known_hosts 文件記錄你連接過的服務器指紋SSH客戶端…

Excel大廠自動化報表實戰(互聯網金融-數據分析周報制作下)

這是Excel大廠自動化報表實戰第四期--互聯網金融-數據分析周報制作下 數據資源已經與這篇博客捆綁&#xff0c;有需要者可以下載通過網盤分享的文件&#xff1a;2.4自動化報表-8月成交數據.xlsx&#xff0c;2.4自動化報表-8月獲客數據.csv等2個文件 鏈接: https://pan.baidu.c…

界面組件DevExpress WPF中文教程:Grid - 節點(Nodes)概述

DevExpress WPF擁有120個控件和庫&#xff0c;將幫助您交付滿足甚至超出企業需求的高性能業務應用程序。通過DevExpress WPF能創建有著強大互動功能的XAML基礎應用程序&#xff0c;這些應用程序專注于當代客戶的需求和構建未來新一代支持觸摸的解決方案。 無論是Office辦公軟件…

開源統一數據庫管理平臺完全指南:私有化部署方案與技術解析

摘要:面對MySQL、Oracle、Redis等混合數據庫環境,如何實現統一管控?本文深度評測5大開源平臺,附私有化部署方案和性能對比。 一、核心需求場景與技術選型 典型痛點: #mermaid-svg-LuCYYyJjBakpzzFH {font-family:"trebuchet ms",verdana,arial,sans-serif;font…

hot100 -- 14.貪心算法

1.買賣股票的最佳時機 方法&#xff1a; def MaxProfit(prices):max_pro, min_num 0, float(inf)for num in prices:if num < min_num:min_num nummax_pro max(max_pro, num - min_num)return max_pro 2.跳躍游戲 問題&#xff1a; 給你一個非負整數數組 nums &#…

Celery+fastAPI/Flask實現高性能應用

本文在創作過程中借助 AI 工具輔助資料整理與內容優化。圖片來源網絡。 引言 大家好&#xff0c;我是沛哥兒。 在當今的軟件開發領域&#xff0c;異步任務處理和高效的 Web 開發框架是提升應用性能和可擴展性的關鍵因素。Celery 作為一個強大的分布式任務隊列系統&#xff0c;…

【音視頻】PJSIP庫——pjsua命令使用詳解

1、源碼編譯 1)安裝依賴庫 sudo apt install libsrtp2-dev sudo apt install libopus-dev alsa-tools libalsaplayer-dev ffmpeg libalsa* pulseaudio-module-jack sudo apt install jackd libjack-jackd2-dev libjack-dev libsdl2-dev libv4l-dev libavcodec-dev libavde…

Python實例題:圖片批量處理工具

目錄 Python實例題 題目 問題描述 解題思路 關鍵代碼框架 難點分析 Python實例題 題目 圖片批量處理工具 問題描述 開發一個 Python 工具&#xff0c;實現以下功能&#xff1a; 遍歷指定文件夾下的所有圖片文件&#xff08;支持常見格式如 jpg、png、webp&#xff0…

超圖superMap iObjects for Java的Jar使用中遇到的問題

一、 cannot open shared object file: No such file or directory 1. 問題 2. 解決方法 &#xff08;1&#xff09;檢查有沒有配置環境變量 PATH &#xff08;2&#xff09;創建軟連接 ln -s &#xff08;3&#xff09;將主機 /usr/lib64 目錄中的libgomp.so.1 復制到 /pla…

常見的藍牙5.0抗干擾技術和算法

常見的藍牙5.0抗干擾技術和算法&#xff1a; 跳頻擴頻&#xff08;Frequency Hopping Spread Spectrum, FHSS&#xff09; 通過在不同的頻率通道上快速切換數據傳輸&#xff0c;減少與固定頻率干擾源的沖突。 直接序列擴頻&#xff08;Direct Sequence Spread Spectrum, DSSS&…

牛客與Moka深化合作,升級AI面試對接,引領招聘變革

近日&#xff0c;AI 招聘平臺牛客與國內領先的人力資源全模塊平臺 Moka 宣布完成 AI 面試產品的全新對接升級。此次升級實現了從 Moka 到牛客的一鍵互綁&#xff0c;并打通了簡歷出題、風險點提問、優勢技能挖掘等核心功能&#xff0c;為企業提供更加高效智能的面試體驗。 這一…

Vue 3 路由跳轉全面指南(Composition API + <script setup>)

一、前言&#xff1a;為什么要學習 Vue Router&#xff1f; 在單頁面應用(SPA)開發中&#xff0c;路由管理是核心功能之一。Vue Router 作為 Vue.js 官方推薦的路由解決方案&#xff0c;與 Vue.js 深度集成&#xff0c;提供了以下重要功能&#xff1a; 頁面無刷新跳轉&#x…

JavaScript基礎-常用的鍵盤事件

一、前言 在網頁開發中&#xff0c;用戶交互 是非常重要的一環。除了鼠標操作之外&#xff0c;鍵盤事件也是前端開發中最常見的交互方式之一。 JavaScript 提供了多個用于監聽和處理鍵盤輸入的事件&#xff0c;例如 keydown、keyup 和 keypress。掌握這些事件可以幫助我們實現…

解決 Android 項目下載依賴缺失導致的問題

解決 Android 項目下載依賴缺失導致的問題 在項目根目錄下的 build.gradle 文件中增加下面的代碼&#xff1a; buildscript {repositories {...maven {url "https://maven.aliyun.com/repository/jcenter"}maven {url "https://maven.aliyun.com/repository/c…

Clang Code Model: Error: The clangbackend executable “D:\Soft\Qt5.12.12\Tool

Qt Creator->菜單->幫助->關于插件->C>去掉ClangCodeModel勾選->重啟Qt Creator 參考&#xff1a;【問題解決】Qt Creator 報錯&#xff1a;Clang Code Model: Error: The clangbackend executable_qt clang code model-CSDN博客