製作更酷的JList介面 )

來源:互聯網
上載者:User

製作更酷的JList介面 (轉)

內容:

1。繪製器的工作原理。
2。用自訂的繪製器更換JList和JComboBox的外觀。
3。讓新的外觀響應滑鼠事件。

藉助swing
體系的mvc設計理念,為組件
更換不同的外觀成為輕而易舉事情。本文主要以JList和JComboBox為例講解ListCellRenderer的原理與用法.

一、繪製器的工作原理

不管是JList還是JComboBox,它們都用到了ListCellRenderer,因為JComboBox本身就是由一個下拉式的JList和TextField組成的. 在這裡,它們使用了callback的機制。

callback的一是種常見的方式是在A類中調用
B類中的方法,在A類中先要登記一個(也可以是多個)B類的執行個體引用,在需要調用時再通過該執行個體來調用它的內部方法.這樣的機制在很多的設計模式
中都有用到,如Observer等.還有AWT的事件機制也用到了callback.

要實現callback,通常將B類設計成一個能被callback的介面.在JList的繪製器中,swing提供了一個ListCellRenderer介面,
public interface ListCellRenderer {
  Component getListCellRendererComponent(
  JList list,
  object
value,
  int index,
  boolean isselect
ed,
  boolean cellHasf
ocus);
}
這個介面只提供一個方法,我們只要實現了這個介面,並將它的執行個體引用傳給JList,就可以將JList替換成不同的樣式了.看一下ListCellRenderer是如何工作的,

.NET/turbochen/images/renderer1.gif">
在繪製JList的每個Cell之前,它會去調用getListCellComponent( ),得到一個Component,並
將這個Component繪製在正確的位置.因為getListCellComponent( )返回的是Component,所以我們幾乎可以擴充任意一個Component,來改變JList,JComboBox等的外觀.

二、製作自已的繪製器

我們現在要想讓JList中顯示一組學生名單,同時每個名單前顯示該學生的表徵圖.如所示

我們先來想一想,Swing中有什麼組件既可以顯示表徵圖也可以顯示文字? JLabel.對了。我們就用JLabel作為JList的繪製器, 看看我擴充的JLabel類,它實現了ListCellRenderer介面:
  /* 可以顯示表徵圖的ListCell繪製器 */
  public class IconListItemRenderer extends JLabel implements ListCellRenderer
  {
  private Border
  selectedb
order = BorderFactory.createLineBorder(Color.blue,1),
  emptyBorder = BorderFactory.createEmptyBorder(1,1,1,1);

  public Component getListCellRendererComponent(
  JList list,
  Object value,
  int index,
  boolean isSelected,
  boolean cellHasFocus)
  {

  IconListItem item = (IconListItem)value;
  this.setIcon(item.getIcon());
  this.setText(item.getText());

  if ( isSelected ) setBorder (selectedBorder);
  else setBorder(emptyBorder);
  return this;
  }
  }
大家看到,getListCellRendererComponent方法會傳入幾個參數,我們就用它傳入的幾個參數設定JLabel的外觀:表徵圖與文字。在這個類中,我們用一個IconListItem接收調用者傳過來的value,
  IconListItem item = (IconListItem) value;
IconListItem是我另外定義好的一個類,它用來存放每一個List Item的值,
  import Java
x.swing.*;
  public class IconListItem
  {
  Icon icon;
  String text;
  public IconListItem(Icon icon, String text)
  {
  this.icon = icon;
  this.text = text;
  }
  public Icon getIcon() { return icon;}
  public String getText() { return text;}
  public void setIcon(Icon icon){ this.icon = icon;}
  public void setText(String text){ this.text = text; }
  }
這樣的話,我就可以用getIcon()和getText()方法取得每個List Item的值了,
  IconListItem item = (IconListItem) value;
  this.setIcon(item.getIcon());
  this.setText(item.getText());

至此,我們就可以用以下方法方便的更換JList的外觀了,
  JList list = new JList();
  list.setCellRenderer(new IconListItemRenderer());  file://安
裝我們自訂的cellRenderer
  DefaultListModel listModel = new DefaultListModel();
  list.setModel(listModel);
  IconListItem item = new IconListItem(new ImageIcon(...),"John");
  listModel.addElement(item);  // 為List增加Item
  ...
由於JComboBox也有一個下拉式清單,所以它的清單也是用ListCellRenderer來繪製的,所以我們也可以將這個IconListItemRenderer給它用:
  JComboBox list = new JComboBox();
  list.setRenderer(new IconListItemRenderer());  //
裝我們自訂的cellRenderer
  DefaultComboBoxModel comboModel = new DefaultComboBoxModel();
  list.setModel(comboModel);
  IconListItem item = new IconListItem(new ImageIcon(...),"John");
  comboModel.addElement(item);  // 為List增加Item
  ...
注意,JComboBox安裝
繪製器時是用setRenderer()方法,JList是用setCellRenderer()方法,名字稍有不同.

以上大家看到的是可顯示一個表徵圖的List, 下面我們再看一個可顯示CheckBox的List是如何?的,以下是例圖:

代碼實現:
  import javax.swing.*;
  import java.awt.*;
  import javax.swing.border.*;
  import java.awt.event.*;
  /* 可以顯示CheckBox的ListCell繪製器 */
  public class CheckListItemRenderer extends JCheckBox implements ListCellRenderer
  {
  public Component getListCellRendererComponent(
  JList list,
  Object value,
  int index,
  boolean isSelected,
  boolean cellHasFocus)
  {
  CheckListItem item = (CheckListItem)value;
  this.setSelected(item.getCheck());
  this.setText(item.getText());
  this.setFont(list.getFont());
  this.setEnabled(list.isEnabled());
  return this;
  }
  }
同樣這個繪製器中用一個CheckListItem存放每個List Item的值:
  public class CheckListItem
  {
  boolean check;
  String text;
  public CheckListItem(boolean check, String text)
  {
  this.check = check;
  this.text = text;
  }
  public boolean getCheck() { return check; }
  public void setCheck(boolean _check) { check = _check; }
  public String getText() { return text; }
  public void setText(String _text) { text = _text; }
  }
這個繪製器的用法同IconListItemRenderer一樣,不多講了.

三、讓自訂的繪製器響就滑鼠事件

使用以上的CheckListItemRenderer時,大家會發現,雖然List中可以顯示CheckBox了,但是用滑鼠點擊時,沒有反應! 現在我就來解決這個問題.要澄清的是,ListCellRenderer本身是只返回一個組件用來繪製一個儲存格,不能對使用者
動作作出反應。為些我們必須在JList上下功夫.JList有一個addMouseListener()方法可以為自身安裝一個滑鼠監聽
器,在這裡,我實現了一個MouseAdapter,並讓它對mousePressed作出響應:
  class CheckListMouseListener extends MouseAdapter
  {
  public void mousePressed(MouseEvent e) {
  JList list = (JList) e.getsource
();
  int index = list.locationToIndex(e.getPoint());
  CheckListItem item = (CheckListItem)list.getModel().getElementAt(index);
  item.setCheck(! item.getCheck());
  Rectangle rect = list.getCellBounds(index, index);
  list.repaint(rect);
  }
  }
使用時, 用addMouseListener(new CheckListMouseListener())就行了.

除了包含CheckBox的JList外,許多情況下,我們需要為自製的繪製器加上動作響應,如我們要實現一個可編輯的JList, 除了要擴充
JTextField及實現ListCellRenderer之外,還要寫一個滑鼠監聽器和鍵盤監聽器,當雙擊時,JList變成可編輯狀態,當斷行符號時,
還原成不可編輯狀態.具體的實現過程,我就不詳敘了,留給大家作練習.

上面內容,我寫了一個示範程式
,下面是它的示範畫面,

你可以從這裡DOWNLOAD
/CellRenderer.rar">下載
完整的示範程式.

 

以上文章為Turbo Chen原作,著作權。如需轉載,請註明來源.

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.