亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

技術分享——開發Eclipse自定義控件

2019-11-18 13:01:50
字體:
來源:轉載
供稿:網友

  現在基于 Eclipse 的應用越來越多,很多桌面應用都是用Eclipse開發的。Eclipse提供了一套 SWT/JFACE 的控件庫,使得人們開發界面應用極大的方便。但是,SWT/JFACE的控件庫究竟有限,在應用開發是我們不可避免地要自己開發一些自定義的控件。本文通過開發一個顏色列表控件的實例介紹了Eclipse自定義控件開發中所要用到的技術。
  
  目標讀者必須熟悉java開發,并且有一定的Eclipse開發經驗。
  
  在Eclipse網站上有一篇相關的文章"Creating Your Own Widgets using SWT",該文介紹了開發自己控件的很多基本概念、方法,并且通過實例進行了介紹,非常好。但是其所用的實例比較簡單,還有很多控件開發中所要涉及到的內容,例如鍵盤、鼠標事件的處理,滾動條、焦點的處理等等沒有提及。本文通過開發一個自定義的顏色列表控件的實例,全面地介紹了自定義控件所涉及的技術。同時,讀者也可以對該實例進行擴展,實現自己的列表控件。
  
  SWT中提供的標準列表控件非常簡單,只能提供字符串的選擇。我們經常需要提供一些圖形列表供用戶選擇,這就需要自己開發自定義的列表控件。顏色選擇列表是我們常用的一種圖形列表,我們就以此為例進行介紹。以下是我們將要開發的顏色列表。
  
  我們在開發自定義控件時主要考慮以下問題:
  
  1、 自定義控件的繪制:通常我們需要自己對控件的外形或圖案進行繪制;
  
  2、 控件對鍵盤事件的響應:當焦點進入控件,用戶進行鍵盤操作,通過鍵盤對控件進行控制時,我們需要讓控件對用戶的操作進行響應。例如在列表中,用戶會通過上下箭頭改變列表的選擇項;
  
  3、 控件對鼠標事件的響應:當用戶用鼠標選中控件,進行操作時,控件必須作出相應的反應;
  
  4、 控件對焦點事件的響應:當界面焦點進入或移出控件,通常我們需要將控件繪制成得到或失去焦點的外形。例如,當焦點進入列表時,一般被選中的列表項會有虛框表示選中。
  
  5、 響應TAB鍵:對于一個可操縱的控件,用戶可以用TAB鍵將焦點移入或移出。
  
  6、 響應滾動條事件:當控件有滾動條時,我們需要響應用戶對滾動條的操作,完成對控件的繪制工作。
  
  7、 提供事件監聽機制:程序員使用你的控件時通常需要監聽控件中發生的一些事件,這樣當事件發生時,他們能夠進行相應處理。
  
  8、 提供輔助功能(accessibility):輔助功能是方便殘障人士使用時必須的,標準控件都會提供相應的支持,我們自定義的控件也不例外。
  
  9、 提供功能接口方便程序員訪問:通常為方便程序員使用時獲取控件中的信息或進行設置,我們需要提供一些接口。
  
  首先我們要開發的列表控件是一個基本控件,所以我們選擇Canvas作為我們開發的基類。
  
  public class ColorList extends Canvas {
  Vector colors = new Vector(); // 用于保存我們顏色控件中的顏色值
  Vector colorNames = new Vector(); // 用于保存顏色控件中的顏色名字
  
  int rowSel = -1; // 用于保存當前選中的行號
  int oldRowSel = -1; // 用于保存上一次選中的行號
  
  int maxX, maxY; // 用于保存列表的寬度和高度
  int lineHeight; // 用于設置行高
  
  int cx = 0; // 滾動條滾動后,控件的圖形相對于控件可見區域左上角的x坐標
  int cy = 0; // 滾動條滾動后,控件的圖形相對于控件可見區域左上角的y坐標
  }
  
  控件開發最重要的就是控件的繪制了??丶睦L制可以通過添加PaintListener,在它的paintControl方法中進行。
  
  addPaintListener(new PaintListener() {
  public void paintControl(PaintEvent e) {
  GC gc = e.gc;
  Point size = getSize();
  int beginx = e.x;
  int beginy = (e.y / lineHeight) * lineHeight;
  int beginLine = (e.y - cy) / lineHeight;
  int endLine = beginLine + e.height / lineHeight + 1;
  if (endLine > getItemCount())
  endLine = getItemCount();
  for (int i = beginLine; i < endLine; i++) {
  boolean selected = false;
  if (i == rowSel)
  selected = true;
  onPaint(gc, i, cx, beginy + (i - beginLine) * lineHeight,
  selected);
  }
  }
  });
  
  這里要注重的是從PaintEvent中獲取的x,y,height,width是需要重繪的區域,x,y是以控件的左上角為原點的坐標。在我們的程序中,為了性能起見,我們先根據需要重繪的區域計算出需要重繪的行數,只重繪相應的行,而不是將整個控件重繪。我們程序中用到的onPaint用于繪制一行。
  
  接下來,我們要讓我們的控件響應鍵盤上下鍵對列表項進行選擇。我們已對向上鍵的處理為例,首先當用戶按了向上鍵時,我們需要改變選擇,并且重繪舊的和新的選擇項。假如選擇項已經到了列表的頂部,我們還需要同時滾動滾動條。
  
  addListener(SWT.KeyDown, new Listener() {
  public void handleEvent(Event event) {
  switch (event.keyCode) {
  case SWT.ARROW_UP: // 處理向上鍵
  if (rowSel != 0) {
  oldRowSel = rowSel;
  rowSel--;
  if (oldRowSel != rowSel) { //發送消息讓控件重繪
  ((Canvas) event.widget).redraw(cx, (rowSel + cy
  / lineHeight)
  * lineHeight, maxX, lineHeight*2, false);
  }
  if (rowSel < -cy / lineHeight) { //假如需要,滾動滾動條
  ScrollBar bar = ((Canvas) event.widget)
  .getVerticalBar();
  bar.setSelection(bar.getSelection() - lineHeight);
  scrollVertical(bar);
  }
  selectionChanged(); // 發送selectionChanged事件
  }
  break;
  case SWT.ARROW_DOWN: // down arror key
  …
  break;
  }
  }
  });
  
  接下來,我們要讓我們的控件響應鼠標對列表項進行選擇。首先我們要計算出鼠標選中的行號,注重MouseEvent中的y值只是相對于控件左上角的坐標,我們需要加上滾動出了控件的部分。
  
  addMouseListener(new MouseListener() {
  public void mouseDoubleClick(MouseEvent e) {
  }
  public void mouseDown(MouseEvent e) {
  int row = (e.y - cy) / lineHeight; //計算選中的行
  if (row >= 0) {
  oldRowSel = rowSel;
  rowSel = row;
  }
  if (oldRowSel != rowSel) { // 重畫舊的和新的選擇項
  ((Canvas) e.getSource()).redraw(cx, (e.y / lineHeight)
  * lineHeight, maxX, lineHeight, false);
  ((Canvas) e.getSource()).redraw(cx, (oldRowSel + cy
  / lineHeight)
  * lineHeight, maxX, lineHeight, false);
  }
  selectionChanged();
  }
  public void mouseUp(MouseEvent e) {
  }
  });
  
  當我們的控件獲得焦點時,選中的列表項需要有虛框表示控件得到焦點。當獲得或失去焦點是,我們這里只需要簡單的通知選中的項重畫。
  
  addFocusListener(new FocusListener() {
  public void focusGained(FocusEvent e) {
  ((Canvas) e.getSource()).redraw(cx, rowSel * lineHeight, maxX,
  lineHeight, true);
  }
  public void focusLost(FocusEvent e) {
  ((Canvas) e.getSource()).redraw(cx, rowSel * lineHeight, maxX,
  lineHeight, true);
  }
  });
  
  我們在繪制每一個列表項時可以加入判定當前控件是否得到焦點,假如控件得到了焦點,我們就在選中的項目上畫一個虛框。下面是我們繪制一個列表項的代碼,注重在代碼的最后繪制焦點的虛框。
  
  void onPaint(GC gc, int row, int beginx, int beginy, boolean isSelected) {
  Color initColor = gc.getBackground();
  Color initForeColor = gc.getForeground();
  if (isSelected) {
  gc.setBackground(Display.getCurrent().getSystemColor(
  SWT.COLOR_LIST_SELECTION));
  gc.fillRectangle(beginx, beginy, maxX, lineHeight);
  gc.setForeground(Display.getCurrent().getSystemColor(
  SWT.COLOR_LIST_SELECTION_TEXT));
  } else {
  gc.setBackground(initColor);
  }
  gc.drawString((String) colorNames.get(row), beginx + 24, beginy);
  Color color = Display.getCurrent().getSystemColor(
  ((Integer) colors.get(row)).intValue());
  gc.setBackground(color);
  gc.fillRectangle(beginx + 2, beginy + 2, 20, lineHeight - 4);
  gc.setBackground(initColor);
  gc.setForeground(initForeColor);
  if (isFocusControl() && isSelected)
  gc.drawFocus(cx, beginy, maxX, lineHeight);
  }
  
  作為一個可操作的控件,TAB鍵的支持也是很重要的。由于我們的控件是從Canvas繼續過來的,不支持TAB鍵。下面的代碼使我們的控件有TAB鍵的支持:
  
  addTraverseListener(new TraverseListener() {
  public void keyTraversed(TraverseEvent e) {
  if (e.detail == SWT.TRAVERSE_TAB_NEXT
   e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
  e.doit = true;
  }
  };
  });

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美中在线观看| 精品一区二区三区三区| 91精品国产色综合久久不卡98| 青青久久av北条麻妃海外网| 亚洲精品久久久久| 欧美怡春院一区二区三区| 久久久国产精彩视频美女艺术照福利| 中文在线资源观看视频网站免费不卡| 日韩a**站在线观看| 国产欧美一区二区白浆黑人| 伊人久久男人天堂| 国产成人涩涩涩视频在线观看| 久久99久久99精品中文字幕| 国产专区欧美专区| 日韩成人高清在线| 欧美xxxx做受欧美| 亚洲欧美中文日韩在线v日本| 亚洲国产小视频| 91啪国产在线| 正在播放亚洲1区| 亚洲天堂久久av| 欧美成人黑人xx视频免费观看| 欧美视频不卡中文| 日韩欧美在线免费观看| 国产午夜精品麻豆| 欧美激情喷水视频| 亚洲国产精品va在看黑人| 成人久久一区二区| 欧美在线性视频| 一本一道久久a久久精品逆3p| 91精品久久久久久| 欧美黑人性视频| 欧美在线激情视频| 欧美性猛交xxxx黑人猛交| 久久69精品久久久久久国产越南| 91九色蝌蚪国产| 国产精品女主播| 国产亚洲精品久久久久久| 国内精品视频久久| 伊人伊人伊人久久| 国产一区二区三区在线观看视频| 亚洲国产成人在线视频| 亚洲a成v人在线观看| 国产精品一区二区电影| 欧美wwwwww| 国产精品高清网站| 韩国视频理论视频久久| 欧美性精品220| 久久成人免费视频| 亚洲老司机av| 精品呦交小u女在线| 亚洲第一免费播放区| 精品色蜜蜜精品视频在线观看| 精品亚洲一区二区三区四区五区| 亚洲欧美激情在线视频| 一区二区三区在线播放欧美| 亚洲欧洲午夜一线一品| 最好看的2019年中文视频| 国产98色在线| 国产精品久久久久久搜索| 97欧美精品一区二区三区| 亚洲第一级黄色片| 一区二区三区 在线观看视| 久久精品国产清自在天天线| 91九色综合久久| xvideos亚洲| 久久综合色88| 欧美视频专区一二在线观看| 亚洲精品www久久久久久广东| 亚洲成avwww人| 亚洲综合中文字幕在线| 国产成人精品久久二区二区91| 国产精品极品尤物在线观看| 国产在线视频欧美| 欧美日韩在线视频一区二区| 欧美日韩国产区| 国产精品免费在线免费| 91麻豆国产精品| 亚洲欧美国产精品va在线观看| 中文字幕亚洲二区| 一本一道久久a久久精品逆3p| 亚洲激情小视频| 日韩中文字幕在线精品| 美女扒开尿口让男人操亚洲视频网站| 欧美国产亚洲视频| 亚洲色图欧美制服丝袜另类第一页| 国产一区二区三区毛片| 91在线视频精品| 日本19禁啪啪免费观看www| 亚洲色图25p| 欧美日韩国产色| 日韩成人av在线| 精品美女国产在线| 国模精品视频一区二区三区| 青草青草久热精品视频在线观看| 国产91网红主播在线观看| 亚洲欧美日韩久久久久久| 影音先锋欧美在线资源| 成人精品久久一区二区三区| 中文字幕日本欧美| 91国内在线视频| 成人av.网址在线网站| 动漫精品一区二区| 久久久999精品免费| 成人免费午夜电影| 久久深夜福利免费观看| 福利一区福利二区微拍刺激| 一本大道亚洲视频| 国产亚洲美女久久| 欧美在线不卡区| 国产精品日韩一区| 日本亚洲精品在线观看| 国产精品成人免费视频| 欧美激情aaaa| 青青草原一区二区| 欧美精品亚州精品| 亚洲美女www午夜| 亚洲国产中文字幕在线观看| 欧美裸体xxxxx| 亚洲欧洲一区二区三区在线观看| 中文字幕久热精品视频在线| 国产91精品最新在线播放| 国产精品成人观看视频国产奇米| 69**夜色精品国产69乱| 色综合老司机第九色激情| 日韩精品极品视频免费观看| 精品中文视频在线| 国产日本欧美在线观看| 97人洗澡人人免费公开视频碰碰碰| 亚洲日韩第一页| 亚洲第一福利网站| 91天堂在线视频| 色综合久综合久久综合久鬼88| 国产精品色视频| 亚洲第一网中文字幕| 欧美区二区三区| 国产精品视频区| 在线视频中文亚洲| 亚洲综合大片69999| 91香蕉嫩草影院入口| 欧美日韩午夜激情| 亚洲xxx大片| 欧美一区二区三区精品电影| 久久影院在线观看| 亚洲第一色中文字幕| 欧美日韩免费看| 欧美一性一乱一交一视频| 亚洲第一区在线| 欧洲一区二区视频| 国产成人一区二区| 美女黄色丝袜一区| 精品久久久久久久久久久| 国产成人一区三区| 日韩av不卡电影| 91日韩在线视频| 成人欧美一区二区三区黑人| 欧美一级免费看| 91精品国产网站| 在线看国产精品| 亚洲最大福利网| 国产精品h在线观看| 久久久伊人欧美| 国产日韩欧美在线视频观看| 国产成人涩涩涩视频在线观看|