📄 .#pcombo.java.1.11
字号:
package com.swtplus.widgets.combo;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
/**
* PCombo is an extensible custom combo. PCombo is driven by an IComboStrategy.
* <p>
* <code>
* TreeComboStrategy strategy = new TreeComboStrategy();<BR>
* PCombo pCombo = new PCombo(this,SWT.BORDER| PCombo.RESIZE,strategy);<BR>
* </code>
* <p>
* The actual drop down of the PCombo is managed by the strategy. Therefore
* population of the drop down is done through the strategy. This is
* typically enabled by simply allowing access to the underlying widget
* within the drop down. For example, the TreeComboStrategy has a getTree()
* method. For ex:
* <p>
* <code>
* Tree tree = strategy.getTree();<BR>
* TreeItem item = new TreeItem(tree,SWT.NONE);<BR>
* item.setText("First Tree Item");<BR>
* item.setImage(myImage);<BR>
* </code>
* <p>
* PCombo maintains an Object as its 'value' and not a String as seen with
* a base SWT Combo. The actual class of this value object is determined
* by the strategy. For example, with the TreeComboStrategy, the value
* object is the selected TreeItem. There is one exception. If the combo
* is editable (i.e. not READ_ONLY), and if a user types in a value, that
* value will be represented as a String. Therefore, when using an
* editable combo, you should prepare for either type of value object
* returned from getValue().
*/
public class PCombo extends Canvas {
// TODO: figure out tooltip idea mismatch
/**
* Makes the drop down shell resizable
*/
public static final int RESIZE = 1 << 1;
/**
* Prevents manual editing
*/
public static final int READ_ONLY = 1 << 2;
public static final int FLAT = 1 << 3;
public static final int BORDER = 1 << 4;
private IComboPaintingStrategy paintingStrategy;
private IComboLabelProvider labelProvider;
private Rectangle valueAreaBounds = new Rectangle(0, 0, 0, 0);
private Button arrow;
private Point arrowSize = new Point(0,0);
private Object value = null;
private Shell dropdownShell;
private IComboStrategy dropdownStrategy;
private IComboUpdater updater;
private String tooltip = "";
private boolean ignoreUpdates = false;
private boolean ignoreDeactivate = false;
protected boolean dropdownResized = false;
private boolean resizable = false;
private ControlListener parentShellControlListener;
private ShellListener parentShellShellListener;
private Listener mouseDownFilter;
private boolean readOnly = false;
private Text text;
//private boolean textModified = false;
private int textHeight;
private ArrayList modifyListeners = new ArrayList();
private ArrayList selectListeners = new ArrayList();
private Display display;
private boolean ignoreModification = false;
/**
* Contructs a PCombo with the given style and strategy.
*
* @param parent parent Composite
* @param style style
* @param strategy combo strategy
*/
public PCombo(Composite parent,int style,IComboStrategy strategy) {
super(parent, SWT.NO_BACKGROUND | ((style & BORDER) == BORDER?SWT.BORDER:SWT.NONE));
if ((style & RESIZE) == RESIZE){
resizable = true;
}
if ((style & READ_ONLY) == READ_ONLY){
readOnly = true;
}
display = getDisplay();
this.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
dispose2();
}
});
dropdownStrategy = strategy;
labelProvider = strategy.createLabelProvider();
paintingStrategy = new BaseComboPaintingStrategy(labelProvider);
paintingStrategy.setPCombo(this);
this.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
this.addPaintListener(new PaintListener(){
public void paintControl(PaintEvent e) {
PCombo.this.paintingStrategy.paint(e.gc,PCombo.this.isFocusControl() && (!dropdownShell.isDisposed() && !dropdownShell.isVisible()),valueAreaBounds);
}
});
int arrowStyle = SWT.ARROW | SWT.DOWN;
if ((style & FLAT) == FLAT)
arrowStyle = SWT.ARROW | SWT.DOWN | SWT.FLAT;
arrow = new Button(this,arrowStyle);
arrowSize = arrow.computeSize(SWT.DEFAULT,SWT.DEFAULT);
arrow.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
forceFocus();
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
arrow.addMouseListener(new MouseListener(){
public void mouseDoubleClick(MouseEvent e) {
}
public void mouseDown(MouseEvent e) {
showDropDown();
}
public void mouseUp(MouseEvent e) {
}
});
text = new Text(this,SWT.NONE);
text.setVisible(false);
text.addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {
focusOut();
}
public void focusGained(FocusEvent e) {
}
});
text.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
if (!ignoreModification){
setValue(text.getText(),true);
fireModifyListeners();
}
}
});
textHeight = text.computeSize(SWT.DEFAULT,SWT.DEFAULT).y;
this.addControlListener(new ControlListener(){
public void controlMoved(ControlEvent arg0) {}
public void controlResized(ControlEvent arg0) {
resize();
}
});
this.addListener (SWT.Traverse, new Listener () {
public void handleEvent (Event e) {
switch (e.detail) {
/* Do tab group traversal */
case SWT.TRAVERSE_ESCAPE:
case SWT.TRAVERSE_RETURN:
case SWT.TRAVERSE_TAB_NEXT:
case SWT.TRAVERSE_TAB_PREVIOUS:
case SWT.TRAVERSE_PAGE_NEXT:
case SWT.TRAVERSE_PAGE_PREVIOUS:
closeDropDown();
e.doit = true;
break;
}
}
});
this.addListener (SWT.FocusIn, new Listener () {
public void handleEvent (Event e) {
focusIn();
redraw();
}
});
this.addListener (SWT.FocusOut, new Listener () {
public void handleEvent (Event e) {
redraw();
}
});
this.addMouseListener(new MouseListener(){
public void mouseDoubleClick(MouseEvent e) {
}
public void mouseDown(MouseEvent e) {
if (readOnly)
showDropDown();
forceFocus();
}
public void mouseUp(MouseEvent e) {
}}
);
updater = new IComboUpdater(){
public void update(Object newValue,boolean close) {
getShell().setActive();
ignoreUpdates = true;
setValue(newValue,false);
ignoreUpdates = false;
PCombo.this.tooltip = tooltip;
redraw();
if (close){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
PCombo.this.closeDropDown();
redraw();
}
fireSelectListeners();
fireModifyListeners();
}
public void closeDropDown() {
PCombo.this.closeDropDown();
}
};
this.addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.ARROW_DOWN){
dropdownStrategy.keyDown(updater);
return;
}
if (e.keyCode == SWT.ARROW_UP){
dropdownStrategy.keyUp(updater);
return;
}
if (e.character == '\r' || e.keyCode == SWT.ESC){
closeDropDown();
return;
}
dropdownStrategy.jumpTo(e.character + "");
}
public void keyReleased(KeyEvent e) {
}}
);
this.addListener(SWT.MouseWheel,new Listener(){
public void handleEvent(Event arg0) {
if (isDropDownOpen()){
dropdownStrategy.mouseWheel(arg0.count);
} else {
if (!PCombo.this.isFocusControl())
return;
if (arg0.count > 0){
dropdownStrategy.keyUp(updater);
} else if (arg0.count < 0){
dropdownStrategy.keyDown(updater);
}
}
}}
);
createShell();
setValue(null,false);
dropdownStrategy.initialize(this);
dropdownStrategy.initializeEditor(text);
}
private void resize() {
ignoreModification = true;
Rectangle area = this.getClientArea();
arrow.setBounds(area.width - arrowSize.x,0,arrowSize.x,area.height);
valueAreaBounds = new Rectangle(0,0,area.width - arrowSize.x,area.height);
text.setBounds(paintingStrategy.getTextXStartPosition() -2,(area.height - textHeight)/2,area.width - arrowSize.x - paintingStrategy.getTextXStartPosition() +2,textHeight);
if (text.getText().length() > 0){
Point p = text.getSelection();
text.setText(text.getText());
text.setSelection(p);
}
ignoreModification = false;
}
/* (non-Javadoc)
* @see org.eclipse.swt.widgets.Control#computeSize(int, int, boolean)
*/
public Point computeSize(int wHint, int hHint, boolean changed) {
if (wHint != SWT.DEFAULT)
wHint = wHint = arrowSize.x;
Point p = paintingStrategy.computeSize(wHint,hHint,changed);
p.x += arrowSize.x;
p.y = Math.max(p.y,arrowSize.y);
p.x += 2 * getBorderWidth();
p.y += 2 * getBorderWidth();
return p;
}
private void showDropDown(){
getDisplay().asyncExec(new Runnable(){
public void run() {
if (!isDisposed()){
showDropDown2();
redraw();
}
}}
);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -