当前位置: 首页 > 编程日记 > 正文

开发Eclipse自定义控件

摘自:http://www.ibm.com/developerworks/cn/opensource/os-eclipcntl/

我们在开发自定义控件时主要考虑以下问题:

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坐标}

控件开发最重要的就是控件的绘制了。控件的绘制可以通过添加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;}};});

很多时候,我们需要有滚动条的支持。对于滚动条,我们只要在上面加上selectionListener,处理它的widgetSelected事件就可以。

bar = getVerticalBar();if (bar != null) {bar.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent event) {scrollVertical((ScrollBar) event.widget);}});}

下面是函数scrollVertical的代码。一旦用户对滚动条操作,我们就可以计算出要滚动的区域,然后调用scroll函数。对函数scroll函数的调用会导致相应区域的重绘。

void scrollVertical(ScrollBar scrollBar) {Rectangle bounds = getClientArea();int y = -scrollBar.getSelection();if (y + maxY < bounds.height) {y = bounds.height - maxY;}if( y%lineHeight !=0 )y = y - y % lineHeight - lineHeight;scroll(cx, y, cx, cy, maxX, maxY, false);cy = y;}

现在我们的程序已经基本成形了,我们来进一步完善它。由于我们开发的控件是提供给程序员的,我们需要提供接口,让外部知道控件中发生的事件。其中最重要的是列表项的选中事件。我们需要提供接口让程序员能够添加事件监控器(listener)来监控发生的事件,并且一旦发生事件,我们需要通知监控器。

首先,我们添加一个成员来保存添加的事件监控器:

Vector selectionListeners = new Vector();

我们再增加一个函数addSelectionListener,让程序员可以添加监控器

public void addSelectionListener(SelectionListener listener) {selectionListeners.addElement(listener);}

在我们前面的代码中,我们注意到每次选择项改变,我们都会调用selectionChanged函数。下面是selectionChanged函数代码。这里,我们会生成一个SelectionEvent事件,并且逐个调用事件监控器的widgetSelected方法。这样别人就可以监听到我们的事件了。

public void selectionChanged() {Event event = new Event();event.widget = this;SelectionEvent e = new SelectionEvent(event);for (int i = 0; i < selectionListeners.size(); i++) {SelectionListener listener = (SelectionListener) selectionListeners.elementAt(i);listener.widgetSelected(e);}}

现在辅助功能(Accessibility)也日益成为软件重要的部分,它是的残疾人也能够方便的使用我们的软件。美国已经立法,不符合Accessibility规范的软件不能够在政府部门销售。我们开发的控件也需要支持Accessibility.下面的代码使我们的控件有Accessibility支持。其中最重要的是getRole和getValue函数。我们的控件是从Canvas继承,我们在getRole函数中返回ACC.ROLE_LIST,这样我们的控件才能让屏幕阅读软件将我们的控件作为列表控件对待。

Accessible accessible = getAccessible();accessible.addAccessibleControlListener(new AccessibleControlAdapter() {public void getRole(AccessibleControlEvent e) {int role = 0;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {role = ACC.ROLE_LIST;} else if (childID >= 0 && childID < colors.size()) {role = ACC.ROLE_LISTITEM;}e.detail = role;}public void getValue(AccessibleControlEvent e){int childID = e.childID;if (childID == ACC.CHILDID_SELF) {e.result = getText();} else if (childID >= 0 && childID < colors.size()) {e.result = (String)colorNames.get(childID);}}public void getChildAtPoint(AccessibleControlEvent e) {Point testPoint = toControl(new Point(e.x, e.y));int childID = ACC.CHILDID_NONE;childID = (testPoint.y - cy)/lineHeight; if (childID == ACC.CHILDID_NONE) {Rectangle location = getBounds();location.height = location.height - getClientArea().height;if (location.contains(testPoint)) {childID = ACC.CHILDID_SELF;}}e.childID = childID;}public void getLocation(AccessibleControlEvent e) {Rectangle location = null;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {location = getBounds();}if (childID >= 0 && childID < colors.size()) {location = new Rectangle(cx,childID*lineHeight+cy,maxX,lineHeight);}if (location != null) {Point pt = toDisplay(new Point(location.x, location.y));e.x = pt.x;e.y = pt.y;e.width = location.width;e.height = location.height;}}public void getChildCount(AccessibleControlEvent e) {e.detail = colors.size();}public void getState(AccessibleControlEvent e) {int state = 0;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {state = ACC.STATE_NORMAL;} else if (childID >= 0 && childID < colors.size()) {state = ACC.STATE_SELECTABLE;if (isFocusControl()) {state |= ACC.STATE_FOCUSABLE;}if (rowSel == childID) {state |= ACC.STATE_SELECTED;if (isFocusControl()) {state |= ACC.STATE_FOCUSED;}}}e.detail = state;}});

最后,我们需要提供一些方法方便程序员使用我们的控件。

 public void setSelection(int index) {if (index >= getItemCount() || index < 0)return;oldRowSel = rowSel;rowSel = index;selectionChanged();}public int getSelectionIndex() {return rowSel;}public int getItemHeight() {return lineHeight;}public void setItemHeight(int height) {lineHeight = height;}public int getItemCount() {return colors.size();}public void add(int colorIndex, String colorName) {colorNames.add(colorName);colors.add(new Integer(colorIndex));}

我们开发的控件的使用也是非常简单的。

CustomList customlist = new CustomList( parent, SWT.V_SCROLL | SWT.H_SCROLL );customlist.add(SWT.COLOR_BLACK,"BLACK");customlist.add(SWT.COLOR_BLUE,"BLUE");customlist.setSelection(1);customlist.setSize(400,400);customlist.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

注意:添加addTraverseListener时也得添加addListener(SWT.KeyDown)监听,不然的话,Tab键的Focus会不支持;

整个程序完整的代码请参考如下:

/** Created on 2005-8-27**/
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.Accessible;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;/*** @author lq* */
public class ColorList extends Canvas {static int COLORS[] = { SWT.COLOR_RED, SWT.COLOR_GREEN, SWT.COLOR_BLUE,SWT.COLOR_MAGENTA, SWT.COLOR_YELLOW, SWT.COLOR_CYAN,SWT.COLOR_DARK_RED, SWT.COLOR_DARK_GREEN, SWT.COLOR_DARK_BLUE,SWT.COLOR_DARK_MAGENTA, SWT.COLOR_DARK_YELLOW, SWT.COLOR_DARK_CYAN };static String COLORSNAME[] = { "红色", "绿色", "蓝色", "紫色", "黄色","青色", "暗红色", "暗绿色", "暗蓝色", "暗紫色","暗黄色", "暗青色" };Vector colors = new Vector();Vector colorNames = new Vector();int rowSel = -1;int oldRowSel = -1;int cx, cy;int maxX = 200, maxY;int lineHeight = 18;Vector selectionListeners = new Vector();public ColorList(Composite parent, int style) {super(parent, style);init();}void init() {cx = 0;cy = 0;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);}}});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) {}});addListener(SWT.KeyDown, new Listener() {public void handleEvent(Event event) {switch (event.keyCode) {case SWT.ARROW_UP: // up arrow keyif (rowSel != 0) {oldRowSel = rowSel;rowSel--;if (oldRowSel != rowSel) {((Canvas) event.widget).redraw(cx, rowSel*lineHeight + cy, maxX, lineHeight*2, false);}if (rowSel < -cy / lineHeight) {ScrollBar bar = ((Canvas) event.widget).getVerticalBar();bar.setSelection(bar.getSelection() - lineHeight);scrollVertical(bar);}selectionChanged();}break;case SWT.ARROW_DOWN: // down arror keyif (rowSel < colors.size() - 1) {oldRowSel = rowSel;rowSel++;if (oldRowSel != rowSel) {((Canvas) event.widget).redraw(cx, (rowSel + cy/ lineHeight)* lineHeight, maxX, lineHeight, false);((Canvas) event.widget).redraw(cx, (oldRowSel + cy/ lineHeight)* lineHeight, maxX, lineHeight, false);}if (rowSel >= (((Canvas) event.widget).getClientArea().height - cy)/ lineHeight) {ScrollBar bar = ((Canvas) event.widget).getVerticalBar();if (bar != null) {bar.setSelection(bar.getSelection()+ lineHeight);scrollVertical(bar);}}selectionChanged();}break;}}});addControlListener(new ControlAdapter() {public void controlResized(ControlEvent event) {Point size = getSize();maxX = size.x * 3 / 2;maxY = colors.size() * lineHeight;resizeScrollBars();}});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);}});addTraverseListener(new TraverseListener() {public void keyTraversed(TraverseEvent e) {if (e.detail == SWT.TRAVERSE_TAB_NEXT|| e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {e.doit = true;}};});ScrollBar bar = getHorizontalBar();if (bar != null) {bar.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent event) {scrollHorizontal((ScrollBar) event.widget);}});}bar = getVerticalBar();if (bar != null) {bar.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent event) {scrollVertical((ScrollBar) event.widget);}});}resizeScrollBars();addAccessibility();}private void addAccessibility(){Accessible accessible = getAccessible();accessible.addAccessibleControlListener(new AccessibleControlAdapter() {public void getRole(AccessibleControlEvent e) {int role = 0;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {role = ACC.ROLE_LIST;} else if (childID >= 0 && childID < colors.size()) {role = ACC.ROLE_LISTITEM;}e.detail = role;}public void getValue(AccessibleControlEvent e){int childID = e.childID;if (childID == ACC.CHILDID_SELF) {e.result = getText();} else if (childID >= 0 && childID < colors.size()) {e.result = (String)colorNames.get(childID);}}public void getChildAtPoint(AccessibleControlEvent e) {Point testPoint = toControl(new Point(e.x, e.y));int childID = ACC.CHILDID_NONE;childID = (testPoint.y - cy)/lineHeight; if (childID == ACC.CHILDID_NONE) {Rectangle location = getBounds();location.height = location.height - getClientArea().height;if (location.contains(testPoint)) {childID = ACC.CHILDID_SELF;}}e.childID = childID;}public void getLocation(AccessibleControlEvent e) {Rectangle location = null;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {location = getBounds();}if (childID >= 0 && childID < colors.size()) {location = new Rectangle(cx,childID*lineHeight+cy,maxX,lineHeight);}if (location != null) {Point pt = toDisplay(new Point(location.x, location.y));e.x = pt.x;e.y = pt.y;e.width = location.width;e.height = location.height;}}public void getChildCount(AccessibleControlEvent e) {e.detail = colors.size();}public void getState(AccessibleControlEvent e) {int state = 0;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {state = ACC.STATE_NORMAL;} else if (childID >= 0 && childID < colors.size()) {state = ACC.STATE_SELECTABLE;if (isFocusControl()) {state |= ACC.STATE_FOCUSABLE;}if (rowSel == childID) {state |= ACC.STATE_SELECTED;if (isFocusControl()) {state |= ACC.STATE_FOCUSED;}}}e.detail = state;}});}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 + 40, beginy);Color color = Display.getCurrent().getSystemColor(((Integer) colors.get(row)).intValue());gc.setBackground(color);gc.fillRectangle(beginx + 2, beginy + 2, 30, lineHeight - 4);gc.setBackground(initColor);gc.setForeground(initForeColor);if (isFocusControl() && isSelected)gc.drawFocus(cx, beginy, maxX, lineHeight);}void resizeScrollBars() {Rectangle clientArea = getClientArea();ScrollBar hbar = getHorizontalBar();if (hbar != null) {hbar.setMaximum(maxX);hbar.setThumb(clientArea.width);hbar.setPageIncrement(clientArea.width);}ScrollBar vbar = getVerticalBar();if (vbar != null) {vbar.setMaximum(maxY);vbar.setThumb(clientArea.height);vbar.setPageIncrement(clientArea.height);vbar.setIncrement(lineHeight);if (clientArea.height >= lineHeight * getItemCount() + 2)vbar.setVisible(false);elsevbar.setVisible(true);}}void scrollHorizontal(ScrollBar scrollBar) {Rectangle bounds = getClientArea();int x = -scrollBar.getSelection();if (x + maxX < bounds.width) {x = bounds.width - maxX;}scroll(x, cy, cx, cy, maxX, maxY, false);cx = x;}void scrollVertical(ScrollBar scrollBar) {Rectangle bounds = getClientArea();int y = -scrollBar.getSelection();if (y + maxY < bounds.height) {y = bounds.height - maxY;}if( y%lineHeight !=0 )y = y - y % lineHeight - lineHeight;scroll(cx, y, cx, cy, maxX, maxY, false);cy = y;}public Point computeSize(int wHint, int hHint, boolean changed) {int width = 300, height = lineHeight * (getItemCount())+50;if (wHint != SWT.DEFAULT)width = wHint;if (hHint != SWT.DEFAULT)height = hHint;return new Point(width + 2, height + 2);}public void setSelection(int index) {if (index >= getItemCount() || index < 0)return;oldRowSel = rowSel;rowSel = index;selectionChanged();}public int getSelectionIndex() {return rowSel;}public int getItemHeight() {return lineHeight;}public void setItemHeight(int height) {lineHeight = height;}public int getItemCount() {return colors.size();}public void add(int colorIndex, String colorName) {colorNames.add(colorName);colors.add(new Integer(colorIndex));}public void setDefault() {for (int i = 0; i < COLORS.length; i++) {colors.add(new Integer(COLORS[i]));colorNames.add(COLORSNAME[i]);}}public void addSelectionListener(SelectionListener listener) {selectionListeners.addElement(listener);}public void removeImageClickedListener(SelectionListener listener) {selectionListeners.removeElement(listener);}public void selectionChanged() {Event event = new Event();event.widget = this;SelectionEvent e = new SelectionEvent(event);for (int i = 0; i < selectionListeners.size(); i++) {SelectionListener listener = (SelectionListener) selectionListeners.elementAt(i);listener.widgetSelected(e);}}public String getText(){if(rowSel>=0)return (String)colorNames.get(rowSel);else return null;}
}

转载于:https://www.cnblogs.com/huadoumi/p/5160300.html

相关文章:

小米手机无法连接eclipse调试案例

按照参考博客2的方法 小米2S手机在Eclipse真机调试时&#xff0c;设备选择列表无法显示手机&#xff0c;DDMS也连接不上设备&#xff0c;解决步骤&#xff1a; 1.打开手机设置中开发者选项 - USB调试开启&#xff1b; 2.保证小米2S手机Windows下设备驱动已安装&#xff0c;可…

手机号码格式验证和 FASTDFS 工具类

常见大陆和香港号码格式验证 import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException;public class PhoneFormatCheckUtils {// 大陆号码或香港号码均可public static boolean isPhoneLegal(String str) throws Patt…

Maya摄像机动画技能学习教程

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:4h 38m |大小解压后:1.65 GB 含课程文件 Maya的相机工具是所有3D包中最好的。在本课程中&#x…

前端解决跨域问题的8种方案(最新最全)

.同源策略如下&#xff1a; URL说明是否允许通信http://www.a.com/a.jshttp://www.a.com/b.js同一域名下允许http://www.a.com/lab/a.jshttp://www.a.com/script/b.js同一域名下不同文件夹允许http://www.a.com:8000/a.jshttp://www.a.com/b.js同一域名&#xff0c;不同端口不允…

IDEA中修改文件的默认创建方式

今天很手欠地在创建application-dev.yml文件的时候将application-dev这个名字的文件成功变成了一个我不认识的文件打开方式了&#xff0c;如下图&#xff1a; 可以看到&#xff0c;这个application-dev.yml文件从原来的SpringBoot的配置文件变成一个我们不认识的文件格式… 补…

ArcEngine 直连连接SDE

关键代码IPropertySet pPropertySet new PropertySetClass();pPropertySet.SetProperty("SERVER", sde.IpAdress);pPropertySet.SetProperty("INSTANCE", "sde:oracle11g$//" sde.IpAdress "/" sde.Instance); pPrope…

Dubbo和Spring Cloud微服务架构对比

一、为什么要使用微服务&#xff1f; 微服务提倡将单一应用程序划分成一组小的服务&#xff0c;服务之间互相协调、互相配合。 今天我们来了解下业内主要的微服务框架&#xff1a;Dubbo 和 Spring Cloud 微服务主要的优势 降低复杂度将原来耦合在一起的复杂业务拆分为单个服务,…

Unity 3D为策略游戏创建地图学习教程

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:30节课(7h 42m) |大小:5 GB 含项目文件 沿着曲线、高程图和数据结构移动对象 你会学到: Unity&…

Lambda表达式(简单解析)

Lambda表达式 Lambda表达式其实是JDK8的一个新特性。所谓Lambda表达式指的是应用在单一抽象方法接口环境下的一种简化定义形式&#xff0c;可以用于解决匿名内部类中定义复杂的问题。 我们先来看一段代码&#xff0c;如下&#xff1a; interface Customer{public void print(…

YTU 2899: D-险恶逃生 I

2899: D-险恶逃生 I 时间限制: 1 Sec 内存限制: 128 MB提交: 130 解决: 55题目描述 Koha被邪恶的巫师困在一个m*n的矩阵当中&#xff0c;他被放在了矩阵的最左上角坐标(0,0)处&#xff0c;而唯一的出口在矩阵最右下角坐标(m-1,n-1)处&#xff0c;他每次只能向右或者向下移动一…

2021-2027年中国托育服务行业市场研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国托育服务行业市场行业相关概述、中国托育服务行业市场行业运行环境、分析了中国托育服务行…

2021全国高校计算机能力挑战赛(初赛)Java试题一

从大于等于N 的正整数里找到一个最小的数M,使之满足:M和M的逆序数(如1230的逆序数为321)的和为一个[100000,200000]区间内的值。 import java.util.Scanner; public class Main {public static void main(String[] args){Scanner scanner new Scanner(System.in);int N scann…

Blender写实产品创作学习教程

Blender中的现实产品创作 Realistic Product Creation in Blender MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|时长:71节课(6小时30分钟)|大小解压…

试题 入门训练 Fibonacci数列(Java)

题目&#xff1a; 一开始我看到这题目其实觉得挺简单的&#xff0c;第一次简单写了一个循环就提交上去了&#xff0c;结果… 我意识到这是因为超过long类型的最大范围导致的&#xff0c;所以第二次换成BigInteger大整数类型&#xff0c;但最后一个测试点超时了… 通过百度…

翻译BonoboService官网的安装教程

This page covers simple Bonobo Git Server installation. Be sure to check prerequisites page before installation and for other sections visit the documentation page. 此页包括简单的Bonobo Git 服务安装。在安装和查看文档页之前要先查看系统要求页。 The following…

2021-2027年中国涂装行业市场需求预测与投资战略规划分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国涂装行业市场行业相关概述、中国涂装行业市场行业运行环境、分析了中国涂装行业市场行业的…

【SICP练习】84 练习2.56

这道题的代码略长啊。不过我也是因此而知道Edwin上的代码居然可以复制到word上&#xff0c;以前还想当然的以为不能复制的&#xff0c;毕竟在Edwin上粘贴用的CtrlY&#xff0c;而不是CtrlV。在这里我就只将书上没有的代码贴出来了。 (define (deriv exp var)(cond ((number? e…

2021全国高校计算机能力挑战赛(初赛)Java试题二

某地大数据防疫平台记录了往来的所有防疫相关信息&#xff0c;包括本地或外地人员、健康码颜色、接种疫苗情况、最近一次核酸结果等 import java.util.ArrayList; import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new …

Zbrush2021写实人物肖像雕刻学习教程

Zbrush 2021写实人物肖像雕刻学习教程 Zbrush 2021 Character Likeness Sculpting Tutorial 大小解压后&#xff1a;24G 持续时间32h 1280X720 MP4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 标题:Udemy–Zbrush 2021人物肖像雕刻教程…

监听指定端口数据交互(HttpListenerContext )

很怀念以前做机票的日子&#xff0c;&#xff0c;&#xff0c;&#xff0c;可惜回不去 以前的项目中的&#xff0c;拿来贴贴 场景&#xff1a;同步第三方数据&#xff0c;监听指定地址&#xff08;指定时间间隔&#xff0c;否则不满足&#xff0c;因为需要处理粘包问题&#xf…

OpenCV-Java版学习(1.在IDEA中使用OpenCV)

前言 因为最近要做一个关于计算机视觉的应用程序&#xff0c;所以便来学一下OpenCV的使用&#xff0c;上网找了许久也没找到OpenCV关于Java的教程&#xff0c;无奈之下只能照着官方的Python版的文档学习&#xff0c;所幸里面的函数的使用方法基本都一样。 IDEA中使用OpenCV …

ElasticSearch Groovy脚本远程代码执行漏洞

什么是ElasticSearch&#xff1f;它是一种分布式的、实时性的、由JAVA开发的搜索和分析引擎。2014年&#xff0c;曾经被曝出过一个远程代码执行漏洞&#xff08;CVE-2014-3120&#xff09;&#xff0c;漏洞出现在脚本查询模块&#xff0c;由于搜索引擎支持使用脚本代码&#xf…

2021全国高校计算机能力挑战赛(初赛)Java试题三

二维空间中给定的一组点的坐标&#xff0c;以任意两个点为直径绘制一个圆。求可以绘制的最大圆&#xff0c;满足该圆不包含其他点&#xff0c;输出直径 import java.util.*;import java.util.Scanner; public class Main {private static double res -1;public static void ma…

在Blender中制作火箭发射烟雾和火焰模拟的动画

大小&#xff1a;1.25G 时长1h 30m 1280X720 MP4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 在Blender中制作火箭发射烟雾和火焰模拟的动画 Animate a Rocket Launch Smoke & Fire Simulation in Blender 信息: 制作火箭发射的短片…

OpenCV-Java版学习(2.图像入门)

前言 上一篇博客我们讲了如何在IDEA中使用OpenCV来进行一些简单的图像操作&#xff0c;这节我们来学习图像的一些基本的入门级操作。 图像入门 一.在Java中使用OpenCV注意事项 1.解决awt报错问题 先给大家贴个错误&#xff0c;如下图&#xff1a; 我们在使用awt处理图像的…

两个数组找不同

<script> function subArr(a, b) { return a.filter(function(i) { return b.indexOf(i) -1 }) } console.log(subArr([1,2,3,4],[3,4,5])); </script>转载于:https://www.cnblogs.com/mouse2417/p/5165391.html

jQuery Mobile设置边距的宽度和颜色

border-top:10px solid #EFEFF4"

2021全国高校计算机能力挑战赛(初赛)Java试题四

某游戏公司设计了一个奖励活动&#xff0c;给N个用户&#xff08;1<N<10^7&#xff09;连续编号为1到N&#xff0c;依据用户的编号S发放奖励。 import java.util.ArrayList; import java.util.Scanner;public class Main {public static void main(String[] args) {Scann…

Blender与UE5完美结合全流程创作游戏资产视频教程

Blender到虚幻引擎5 Blender to Unreal Engine 5 MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44100 Hz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |大小:18.4 GB |时长:20h 55m 只有视频课程 无素材文件 你想学习如何…

OpenCV-Java版学习(3.对视频的基本操作)

前言 上一节我们学习了使用OpenCV对图像进行一些基础操作&#xff0c;现在我们学习对视频进行一些基础的操作。 对视频的基本操作 从相机中读取视频 我们从电脑自带的摄像头捕捉一段视频并在屏幕上显示出来&#xff0c;代码如下&#xff1a; import org.junit.jupiter.api…