這是我參與更文挑戰的第5天,活動詳情查看: 更文挑戰java
本文正在參加「Java主題月 - Java 開發實戰」,詳情查看 活動連接web
最近利用空閒時間本身琢磨了一下java swing 編程,其實在從事javaweb以前我一直嚮往的就是java swing 開發,不知道爲何可能當時以爲Windows上的exe程序非常神奇,關於windows上製做exe我以前也有介紹編程
exe打包教程一windows
exe打包教程二數組
java swing開發都是本身琢磨的,有的地方寫的不規範,不過大多都是網上借鑑的,應該不算離譜的。markdown
今天看了看本身的java swing的程序,感受寫的還不錯,可是發現如今遇到一個瓶頸問題,就是jtable的使用,因爲一開始概念不理解如今jtable得從新寫,以前我吧數據放在jtable上了,可是真正開發的java swing數據都是放在TableModel上的。下面就Jtable的使用,好好整理了一番,途中參考的文章我都會放在下面列出,讀者能夠本身參考**mvc
JTable=TableHeader+TableColumnless
顧名思義咱們知道表格是由表頭和表列組成的,這兩個都是單獨的控件。可是JTable中若是想讓表頭顯示僅僅將JTable加入Jpanel或者Jframe中是不行的,我這裏提供兩種方式實現編輯器
一、分別將TableHeader和TableColumn加入控件中單獨的顯示,這種狀況不常見ide
二、先將JTable加入jscrollpane(滾動條)中,而後在將滾動條加入到對應的控件中(Jpanel或者是Jframe).java swing 開發中加入滾動條是很常見的操做,因此這種方式的加入表格仍是很推薦的。
table = new JTable(data, columnNames);
table.setBackground(Color.gray);
table.setPreferredScrollableViewportSize(new Dimension(800, 100));
table.setFillsViewportHeight(false);
pane = new JScrollPane(table);
this.add(pane);
複製代碼
setPreferredScrollableViewportSize
無關緊要的,無所謂,可是setFillsViewportHeight
是設置表格在縱向上的鋪展狀況,什麼意思呢,若是這裏設置爲true則表格就會在縱向上鋪滿jframe,若是是false,表格則會按照本身的實際佔地面積顯示,不會多佔的。衆多周知jtable中經常使用的兩種構造函數一個是數組另外一個是vector,這兩種構造函數中都是採用了匿名內部類實現tablemodel,前者用的是AbstractTableModel,後者是DefaultTableModel。而DefaultTableModel有事繼承了AbstractTableModel,因此咱們平時若是自定義model的話,都會去繼承AbstractTableModel的。咱們在去源碼裏能夠看見,咱們會發現AbstractTableModel有事繼承TableModel這個接口的。因此咱們的全部方法都是源於他。
咱們觀察AbstractTableModel源碼中註釋發現,咱們只須要繼承AbstractTableModel類後只須要實現三個必須的方法,其餘的方法根據須要實現
public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
複製代碼
//表格的列,須要用戶本身設定好
private int column;
//待加載的數據 數據每行的列數和上面要統一好
private List<Object> list;
public MyTableModel(List<Object> list,int column){
this.column=column;
this.list=list;
}
@Override
public int getRowCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public int getColumnCount() {
// TODO Auto-generated method stub
return this.column;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
// TODO Auto-generated method stub
return list.get(rowIndex).toString()+"_"+rowIndex+"_"+columnIndex;
}
複製代碼
在上面咱們繼承了AbstractTableModel,這裏面有對數據的CURD操做
if("增長".equals(command)){
List<Object> data = getData();
data.add("test5");
data.add("test6");
datamModel.setList(data);
// datamModel.fireTableStructureChanged();
datamModel.fireTableRowsInserted(5,6);
}else if("刪除".equals(command)){
List<Object> data = getData();
data.remove(2);
datamModel.setList(data);
datamModel.fireTableRowsDeleted(1, 1);
}else if("更新".equals(command)){
List<Object> data = getData();
data.set(0, "test0_1");
datamModel.setList(data);
datamModel.fireTableRowsUpdated(0, 5);
}
複製代碼
datamModel.fireTableRowsUpdated(0, 5);
的意思是通州JTable顯示模塊去刷新從1-6行的全部數據,因此說好比你更新了第一行的數據,而你用的兩個參數是1,4.那麼恭喜你,你的更新JTable沒法實現,由於他只更新從第二行開始到第五行的數據。其餘的方法參數和他同樣。經過上面就能夠輕鬆實現JTable的CURD操做。/**
* Returns <code>Object.class</code> regardless of <code>columnIndex</code>.
*
* @param columnIndex the column being queried
* @return the Object.class
*/
public Class<?> getColumnClass(int columnIndex) {
return Object.class;
}
複製代碼
protected void createDefaultRenderers() {
defaultRenderersByColumnClass = new UIDefaults(8, 0.75f);
// Objects
setLazyRenderer(Object.class, "javax.swing.table.DefaultTableCellRenderer$UIResource");
// Numbers
setLazyRenderer(Number.class, "javax.swing.JTable$NumberRenderer");
// Doubles and Floats
setLazyRenderer(Float.class, "javax.swing.JTable$DoubleRenderer");
setLazyRenderer(Double.class, "javax.swing.JTable$DoubleRenderer");
// Dates
setLazyRenderer(Date.class, "javax.swing.JTable$DateRenderer");
// Icons and ImageIcons
setLazyRenderer(Icon.class, "javax.swing.JTable$IconRenderer");
setLazyRenderer(ImageIcon.class, "javax.swing.JTable$IconRenderer");
// Booleans
setLazyRenderer(Boolean.class, "javax.swing.JTable$BooleanRenderer");
}
複製代碼
return getValueAt(0, c).getClass();
複製代碼
setCellEditor和setCellRenderer
複製代碼
你們能夠觀察源碼,在JTable的編輯器中AbstractCellEditor是基礎的抽象類,他繼承了CellEditor,怎麼樣熟悉嗎,這個不就是和AbstractTableModel 是同樣的嗎。可是這個類不能反回控件須要和TableCellEditor結合使用,或者咱們只是用另一個基礎類DefaultCellEditor,
DefaultCellEditor和AbstractTableModel 有設麼區別呢,他們都是同樣實現了CellEditor接口,可是前者構造中只能傳入控件,也就是說每日次實力只能經過不一樣構造函數構建不一樣的控件,可是後者是抽象類,繼承的類能夠自定義構造函數,這就方便咱們夠贊多個不一樣的控件了,因此這兩個你們看狀況使用。最後都是經過getTableCellEditorComponent
這個函數將控件返回出去。
設置完了編輯器,咱們最終要是隻渲染器,就是JTable最終如何顯示的問題。和上面的那個同樣。繼承TableCellRenderer類,經過getTableCellRendererComponent方法返回渲染成設麼控件,渲染的控件咱們能夠進行二次封裝。
調用以下 兩個參數就是經過上面兩個類構造的類
column.setCellEditor(editor);
column.setCellRenderer(renderer);
複製代碼