具有可過濾功能的JList組件【Swing】

來源:互聯網
上載者:User

【情境】:在一個列表中,可以通過輸入某個字元,而動態過濾列表中項的顯示。當然,動態顯示的項都是包含使用者輸入的字元!在此,實現的功能非常簡單,沒有更
多的複雜邏輯。僅是為學習者提供一些案例。可以從中進行自己需要的擴充。
【關係圖】:


在Swing中,想構建自己的組件,最簡單的就是繼承現有的組件,再做可定製的功能擴充,也不需要做太多額外的工作,因為Swing為我們提供了良好的可
擴充性。,簡略的說明了待開發的可過濾的清單關聯類圖。以下做一些簡單的描述:
【FilteredList】:繼承了JList,其中類FilteredModel與FilteredTextField是他的內部類實現。在這裡使用
內部類是為了能夠方便的訪問到FilteredList外部資料,減少了與外部類的互動,在此不能確定的說這種方式是好是壞,其中的衡量就留給使用者了。
【FilteredModel】:繼承了AbstractListModel,FilteredList中的內部類,並作為其的一個屬性存在。作用是儲存
展現在列表中的資料,並且能做動態更新。
【FilteredTextField】:繼承了JTextFiled,很顯然的就是一個輸入框,只是實現了一個DocumentListener介面,
做到即時監聽使用者輸入的任何動作:插入、刪除、修改等。在使用者觸發這個監聽時,就需要和FilteredModel進行互動,動態變化
FilteredList中的資料顯示。

【編碼實現】
FilteredModel

在這個Model中主要的是設定一個filteredItems
屬性,用來儲存包含了使用者輸入字元的清單項目;另一個items屬性,儲存列表原始的所有項。關鍵的演算法是方法refilter():即時對使用者輸入進行過
濾,並把結果添加到filteredItems 中。
private class FilterModel extends AbstractListModel {
private List items;
private List filteredItems;
public FilterModel() {
items = new ArrayList();
filteredItems = new ArrayList();
}

public void addElement(Object o) {//添加一個項到列表中
items.add(o);
refilter();//每添加一個項就更新filterItems
}

private void refilter() {
filteredItems.clear();
String item = getFilterField().getText();
for (int i = 0; i < items.size(); i++) {
if (items.get(i).toString().toUpperCase().indexOf(item, 0) != -1
|| items.get(i).toString().toLowerCase().indexOf(item,
0) != -1) {
filteredItems.add(items.get(i));
}
}
fireContentsChanged(this, 0, filteredItems.size());
}

@Override
public Object getElementAt(int index) {
if (index < filteredItems.size()) {
return filteredItems.get(index);
}
return null;
}

@Override
public int getSize() {
return filteredItems.size();
}
}

【FilterField】
private class FilterField extends JTextField implements DocumentListener
{
public FilterField(int width) {
super(width);
getDocument().addDocumentListener(this);
}

@Override
public void changedUpdate(DocumentEvent e) {
model.refilter();//更新列表的顯示資料,下同
}

@Override
public void insertUpdate(DocumentEvent e) {
model.refilter();
}

@Override
public void removeUpdate(DocumentEvent e) {
model.refilter();
}
}

【FilteredList】
public class FilteredList extends JList {
private FilterModel model;

private FilterField filterField;

public FilteredList() {
model = new FilterModel();
setModel(model);
filterField = new FilterField(20);
}

public void addItem(Object o) {
model.addElement(o);
}

public FilterField getFilterField() {
return filterField;
}
}
可見,FilteredList
實現起來非常的簡單,只需定義前面已經建立出來的組件作為其屬性。並更換Model。
使用自己實現的具有可過濾功能的Model。
下面是一段測試代碼:
public static void main(String[] args) {
String[] listItems = { "Chris", "Joshua", "Daniel", "Michael", "Don",
"Kimi", "Kelly", "Keagan" };
JFrame frame = new JFrame("FilteredJList");
frame.getContentPane().setLayout(new BorderLayout());
// populate list
FilteredHistoryList list = new FilteredHistoryList();
for (int i = 0; i < listItems.length; i++)
list.addItem(listItems[i]);
// add to gui
JScrollPane pane = new JScrollPane(list,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.getContentPane().add(list.getFilterField(), BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

【小結】
在這裡實現的只是為一個JList附加了一層特定的功能,當然,我們不能停留在僅僅學會如何編寫這功能的代碼上,還要搞清楚內部如何?,最終是為什麼要
如此去做。
在這裡,使用繼承機制,介面實現等,都是利用類庫成熟的組件類,如此就能複用很多特性。我們需要的是JList上加一層額外的功能,那麼當然需要繼承自
JList,使他倆具有血緣關係啦,方便管理嗎!從這裡也可以感受到Swing編碼的一種感覺:資料與展示層劃分清晰,展示與資料沒有耦合在一塊。當然,
可以說,在這個例子中沒有做的很好,也沒有作出具體的層次最佳化,讀者可以自己試一試……

【參考資料】:《Swing Hacks》
By Chris Adamson
,
Joshua Marinacci

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.