独自等待
那曾经从自己身边溜走的人……
posts - 0,comments - 3,trackbacks - 0
在TableViewer或TreeViewer编辑时候,Eclipse提供了基本的CellEditor,如TextCellEditor、CheckboxCellEditor、ComboBoxCellEditor、DialogCellEditor等,但在实际应用过程中,我们通常有特殊需要,如下图类型的单元格编辑器:

实现的方式相当简单,我组合了ComboBoxCellEditor、DialogCellEditor,其中ComboBox支持手工输入,返回为String类型值(原ComboBoxCellEditor为Integer类型),贴下具体代码吧:
package com.test.ui.properties.invoke;

import java.text.MessageFormat;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;

public abstract class ComboBoxDialogCellEditor extends CellEditor {

    
//Combo Items
    private String[] items;

    
private Composite editor;
    
    
private CCombo comboBox;
    
    
private Control contents;
    
    
private Button button;
    
private FocusListener buttonFocusListener;

    
private ModifyListener modifyListener;
    
    
private Object value = null;

    
/**
     * Internal class for laying out the dialog.
     
*/

    
private class DialogCellLayout extends Layout {
        
public void layout(Composite editor, boolean force) {
            Rectangle bounds 
= editor.getClientArea();
            Point size 
= button.computeSize(SWT.DEFAULT, SWT.DEFAULT, force);
            
if (contents != null{
                contents.setBounds(
00, bounds.width - size.x, bounds.height);
            }

            button.setBounds(bounds.width 
- size.x, 0, size.x, bounds.height);
        }


        
public Point computeSize(Composite editor, int wHint, int hHint,
                
boolean force) {
            
if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
                
return new Point(wHint, hHint);
            }

            Point contentsSize 
= contents.computeSize(SWT.DEFAULT, SWT.DEFAULT,
                    force);
            Point buttonSize 
= button.computeSize(SWT.DEFAULT, SWT.DEFAULT,
                    force);
            
// Just return the button width to ensure the button is not clipped
            
// if the label is long.
            
// The label will just use whatever extra width there is
            Point result = new Point(buttonSize.x, Math.max(contentsSize.y,
                    buttonSize.y));
            
return result;
        }

    }


    
//Combo default style
    private static final int defaultStyle = SWT.NONE;

    
    
public ComboBoxDialogCellEditor() {
        setStyle(defaultStyle);
    }


    
public ComboBoxDialogCellEditor(Composite parent, String[] items) {
        
this(parent, items, defaultStyle);
    }


    
public ComboBoxDialogCellEditor(Composite parent, String[] items, int style) {
        
super(parent, style);
        setItems(items);
    }


    
public String[] getItems() {
        
return items;
    }


    
public void setItems(String[] items) {
        Assert.isNotNull(items);
        
this.items = items;
        populateComboBoxItems();
    }

    
    
protected Button createButton(Composite parent) {
        Button result 
= new Button(parent, SWT.DOWN);
        result.setText(
""); //$NON-NLS-1$
        return result;
    }


    
protected Control createContents(Composite cell) {
        comboBox 
= new CCombo(cell, getStyle());
        comboBox.setFont(cell.getFont());
        populateComboBoxItems();

        comboBox.addKeyListener(
new KeyAdapter() {
            
public void keyPressed(KeyEvent e) {
                keyReleaseOccured(e);
            }

        }
);

        comboBox.addModifyListener(getModifyListener());

        comboBox.addSelectionListener(
new SelectionAdapter() {
            
public void widgetDefaultSelected(SelectionEvent event) {
                applyEditorValueAndDeactivate();
            }

            
            
public void widgetSelected(SelectionEvent event) {
                value 
= comboBox.getText();
            }

        }
);
        
        comboBox.addTraverseListener(
new TraverseListener() {
            
public void keyTraversed(TraverseEvent e) {
                
if (e.detail == SWT.TRAVERSE_ESCAPE
                        
|| e.detail == SWT.TRAVERSE_RETURN) {
                    e.doit 
= false;
                }

            }

        }
);

        comboBox.addFocusListener(
new FocusAdapter() {
            
public void focusLost(FocusEvent e) {
                
if(!button.isFocusControl()) {
                    ComboBoxDialogCellEditor.
this.focusLost();
                }

            }

        }
);

        
return comboBox;
    }

    
    @Override
    
protected Control createControl(Composite parent) {
        Font font 
= parent.getFont();
        Color bg 
= parent.getBackground();

        editor 
= new Composite(parent, getStyle());
        editor.setFont(font);
        editor.setBackground(bg);
        editor.setLayout(
new DialogCellLayout());

        contents 
= createContents(editor);
        updateContents(value);
        
        button 
= createButton(editor);
        button.setFont(font);

        button.addKeyListener(
new KeyAdapter() {
            
public void keyReleased(KeyEvent e) {
                
if (e.character == '\u001b'// Escape
                    fireCancelEditor();
                }

            }

        }
);
        button.addFocusListener(getButtonFocusListener());
        button.addSelectionListener(
new SelectionAdapter() {
            
public void widgetSelected(SelectionEvent event) {
                button.removeFocusListener(getButtonFocusListener());
                Object newValue 
= openDialogBox(editor);
                button.addFocusListener(getButtonFocusListener());
                
if (newValue != null{
                    
boolean newValidState = isCorrect(newValue);
                    
if (newValidState) {
                        markDirty();
                        doSetValue(newValue);
                    }
 else {
                        setErrorMessage(MessageFormat.format(getErrorMessage(),
                                
new Object[] { newValue.toString() }));
                    }

                    fireApplyEditorValue();
                }

            }

        }
);

        setValueValid(
true);
        
        
return editor;
    }


    
public void deactivate() {
        
if (button != null && !button.isDisposed()) {
            button.removeFocusListener(getButtonFocusListener());
        }

        
        
super.deactivate();
    }


    @Override
    
protected Object doGetValue() {
        
return value;
    }


    @Override
    
protected void doSetFocus() {
        
if (comboBox != null)
            comboBox.setFocus();
    }


    @Override
    
protected void doSetValue(Object value) {
        
this.value = value;
        updateContents(value);
    }


    
private void populateComboBoxItems() {
        
if (comboBox != null && items != null{
            comboBox.removeAll();
            
for (int i = 0; i < items.length; i++{
                comboBox.add(items[i], i);
            }

            comboBox.setText(
"");
        }

    }


    
void applyEditorValueAndDeactivate() {
        Object newValue 
= comboBox.getText();
        
if (newValue != null && !newValue.equals(value.toString())) {
            
boolean newValidState = isCorrect(newValue);
            
if (newValidState) {
                markDirty();
                doSetValue(newValue);
            }
 else {
                setErrorMessage(MessageFormat.format(getErrorMessage(),
                        
new Object[] { newValue.toString() }));
            }

        }

        fireApplyEditorValue();
        deactivate();
    }

    
    
/*
     *  (non-Javadoc)
     * @see org.eclipse.jface.viewers.CellEditor#focusLost()
     
*/

    
protected void focusLost() {
        
if (isActivated()) {
            applyEditorValueAndDeactivate();
        }

    }


    
    
/*
     * (non-Javadoc)
     * @see org.eclipse.jface.viewers.CellEditor#keyReleaseOccured(org.eclipse.swt.events.KeyEvent)
     
*/

    
protected void keyReleaseOccured(KeyEvent keyEvent) {
        
if (keyEvent.character == '\r'// Return key
            if (comboBox != null && !comboBox.isDisposed())
                fireCancelEditor();
        }
 else if (keyEvent.character == '\t'// tab key
            applyEditorValueAndDeactivate();
        }

    }


    
protected void editOccured(ModifyEvent e) {
        String value 
= comboBox.getText();
        
if (value == null{
            value 
= "";//$NON-NLS-1$
        }

        Object typedValue 
= value;
        
boolean oldValidState = isValueValid();
        
boolean newValidState = isCorrect(typedValue);
        
if (typedValue == null && newValidState) {
            Assert.isTrue(
false,
                    
"Validator isn't limiting the cell editor's type range");//$NON-NLS-1$
        }

        
if (!newValidState) {
            
// try to insert the current value into the error message.
            setErrorMessage(MessageFormat.format(getErrorMessage(),
                    
new Object[] { value }));
        }

        valueChanged(oldValidState, newValidState);
    }


    
private ModifyListener getModifyListener() {
        
if (modifyListener == null{
            modifyListener 
= new ModifyListener() {
                
public void modifyText(ModifyEvent e) {
                    editOccured(e);
                }

            }
;
        }

        
return modifyListener;
    }


    
private FocusListener getButtonFocusListener() {
        
if (buttonFocusListener == null{
            buttonFocusListener 
= new FocusListener() {
                
public void focusGained(FocusEvent e) {};
                
public void focusLost(FocusEvent e) {
                    ComboBoxDialogCellEditor.
this.focusLost();
                }

            }
;
        }
;
        
return buttonFocusListener;
    }


    
private void updateContents(Object value) {
        Assert.isTrue(comboBox 
!= null);
        
        
if (value != null &&  value instanceof String) {
            comboBox.removeModifyListener(getModifyListener());
            comboBox.setText((String) value);
            comboBox.addModifyListener(getModifyListener());
        }

    }

    
    
protected abstract Object openDialogBox(Control cellEditorWindow);

}

posted on 2008-06-02 13:46 自由 阅读(3915) 评论(2)  编辑  收藏 所属分类: SWT

FeedBack:
# re: 自定义 CellEditor
2012-12-01 18:41 | ljj
怎么调用呢?能给个例子么?  回复  更多评论
  
# re: 自定义 CellEditor[未登录]
2016-02-16 11:57 |
有个问题请教一下,我使用swt table开发了一个小程序自己用,没想到特别麻烦,table里用了TextCellEditor,在输入编辑的时候能做到换行,输入完以后表格里的文本只能显示一行。求问高手,怎么才能实现表格里文本多行显示?(不通过换行符,通过wrap这种方式)
谢谢  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: