【问题标题】:SWT remove all listener from StyledTextSWT 从 StyledText 中删除所有侦听器
【发布时间】:2012-08-29 02:18:43
【问题描述】:

如果我缺少实例,如何从 SWT StyledText 中删除所有侦听器?我尝试使用StyledText.getListeners(int) 方法来获取所有实例,然后能够将它们删除。但是找到所有必需的 int 值是很累的。这是最直接的方法吗?谢谢!

这是我的临时解决方案:

public void removeAllListener(StyledText st) {
    int[] eventTypes = { 3007, 3011, SWT.Resize, SWT.Move, SWT.Dispose,
            SWT.DragDetect, 3000, SWT.FocusIn, SWT.FocusOut, SWT.Gesture,
            SWT.Help, SWT.KeyUp, SWT.KeyDown, 3001, 3002, SWT.MenuDetect,
            SWT.Modify, SWT.MouseDown, SWT.MouseUp, SWT.MouseDoubleClick,
            SWT.MouseMove, SWT.MouseEnter, SWT.MouseExit, SWT.MouseHover,
            SWT.MouseWheel, SWT.Paint, 3008, SWT.Selection, SWT.Touch,
            SWT.Traverse, 3005, SWT.Verify, 3009, 3010 };

    for (int eventType : eventTypes) {
        Listener[] listeners = st.getListeners(eventType);
        for (Listener listener : listeners) {
            st.removeListener(eventType, listener);
        }
    }
}

我不得不复制一些值,因为它们是使用 default 修饰符声明的 StyledText 类的一部分。所以我无法访问它们。

我希望,我没有错过任何 int 值 ;)

【问题讨论】:

    标签: java swt listener


    【解决方案1】:

    一般来说,没有机制可以做到这一点。但是,我设法通过子类化StyledText 使其工作。新类称为StyledTextWithListeners。如果你愿意,你可以重命名它;)。但是,您将不得不使用

    styledText.addListenerByUser(int eventType, Listener listener);
    

    加你Listeners 而不是

    styledText.addListener(int eventTyle, Listener listener);
    

    这对于区分您添加的Listeners 和SWT 在创建时添加的Listeners 是必要的。

    要删除所有用户(您)添加的监听器,只需调用

    styledText.removeAllListeners();
    

    代码如下:

    import java.util.HashMap;
    
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.custom.StyledText;
    import org.eclipse.swt.layout.GridLayout;
    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.Shell;
    
    public class MiniExample {
    
        public static void main(String[] args) {
            Display display = Display.getDefault();
            final Shell shell = new Shell(display);
            shell.setLayout(new GridLayout(1, false));
    
            StyledTextWithListeners text = new StyledTextWithListeners(shell, SWT.BORDER);
    
            text.setText("TEXT");
    
            text.addListenerByUser(SWT.Verify, new Listener() {
    
                @Override
                public void handleEvent(Event arg0) {
    
                }
            });
    
            text.removeAllListeners();
    
            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch())
                    display.sleep();
            }
        }
    
        public static class StyledTextWithListeners extends StyledText
        {
            HashMap<Integer, Listener> listeners;
            public StyledTextWithListeners(Composite parent, int style) {
                super(parent, style);
            }
    
            public void addListenerByUser(int eventType, Listener listener)
            {
                addListener(eventType, listener);
                System.out.println("Adding: " + listener.getClass().toString());
    
                if(listeners == null)
                    listeners = new HashMap<Integer, Listener>();
    
                listeners.put(eventType, listener);
            }
    
            public void removeAllListeners()
            {
                for(Integer type : listeners.keySet())
                {
                    System.out.println("Removing: " + listeners.get(type).getClass().toString());
                    removeListener(type.intValue(), listeners.get(type));
                }
                listeners = new HashMap<Integer, Listener>();
            }
        }
    }
    

    它基本上保存了您在HashMap 中添加的所有Listeners,并在您调用removeAllListeners 时将其删除。

    请记住,我没有处理您在 StyledText 中添加第二个 Listener 和相同 eventType 的情况。在这种情况下,旧的Listener 将在HashMap 中被替换,但不会从StyledText 中删除。如果您的场景中可能出现这种情况,您只需自己添加一些代码即可。

    【讨论】:

    • 当我尝试用Text 做同样的事情时,我得到一个SWTException 说不允许子类化(Eclipse 3.6),但我在使用StyledText 时不允许。为什么?我该如何克服呢?此外,他们是否有一天会在尝试继承 StyledText 时抛出相同的异常,从而使这变得不可能?
    • 我通过添加这个方法绕过了子类化异常:protected void checkSubclass(){ }
    • @DinisCruz 是的,可以对这些小部件进行子类化,但它是not recommended。我不再建议这个答案,而是将StyledText 包装在另一个类中并在那里处理添加/删除Listeners。
    • @MrMas 那是因为here解释的原因。我不再建议这个答案,而是将StyledText 包装在另一个类中并在那里处理添加/删除Listeners。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    相关资源
    最近更新 更多