Eclipse SWT:启用垂直滚动时无法滚动文本

Eclipse SWT: Can't scroll over Text when vertical scrolling is enabled

我有一个Text inside a Group, which is inside a Composite and that resides inside a ScrolledComposite. All Elements are inside an EditorPart

ScrolledComposite mySc
|- Composite myComposite
   |- Group myGroup
      |- Text myText

我可以滚动(使用鼠标滚轮)EditorPart 中的所有元素,但是当光标位于文本区域时,滚动停止。 我只想在文本具有键盘焦点时在文本内滚动。

文本 myText 的实例化:

myText = new Text(myGroup, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);

没有 SWT.V_SCROLL 它可以工作,但是我没有滚动条和在文本中滚动的可能性。

我想我可以在父级上使用 forceFocus() 以防文本没有焦点控制:

myText.addListener(SWT.MouseWheel, new Listener() {
    @Override
    public void handleEvent(Event event) {
        if (!commandText.isFocusControl()) {
            System.out.println("no focus");
            Control wheelControl = myText.getParent();

            Point cursorPos = wheelControl.toControl(event.display.getCursorLocation());
            event.x = cursorPos.x;
            event.y = cursorPos.y;
            event.widget = wheelControl;
            wheelControl.forceFocus();
            wheelControl.notifyListeners(SWT.MouseWheel, event);
        } else {
            System.out.println("Focus control");
        }
    }
});

但是没用。完全没有变化。它只正确打印 "Focus control" 和 "no focus"。

编辑:

这是一个最小的工作示例:

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

public class MyEditor extends EditorPart {

    private Text myText;
    private boolean dirty = false;

    public MyEditor() {
        super();
    }

    @Override
    public void init(IEditorSite site, IEditorInput input) {
        setSite(site);
        setInput(input);
    }


    @Override
    public void doSave(IProgressMonitor monitor) {
        return;
    }


    @Override
    public void doSaveAs() {
        return;
    }


    @Override
    public boolean isDirty() {
        return dirty;
    }


    @Override
    public boolean isSaveAsAllowed() {
        return false;
    }


    @Override
    public void createPartControl(Composite parent) {
        parent.setLayout(new FillLayout());

        ScrolledComposite mySc = new ScrolledComposite(parent, SWT.V_SCROLL);
        Composite myComposite = new Composite(mySc, SWT.BORDER);
        myComposite.setLayout(new GridLayout(1, false));

        // Set the child as the scrolled content of the ScrolledComposite
        mySc.setContent(myComposite);
        // Expand both horizontally and vertically
        mySc.setExpandHorizontal(true);
        mySc.setExpandVertical(true);

        Group myGroup = new Group(myComposite, SWT.NONE);
        myGroup.setText("Hello or something");
        myGroup.setLayout(new GridLayout(1, false));
        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.verticalIndent = 10;
        myGroup.setLayoutData(gd);

        Label aLabel = new Label(myGroup, SWT.NONE);
        aLabel.setText("You can write here: ");

        myText = new Text(myGroup, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        myText.setText("Some Default Text");
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.heightHint = 300;
        gd.horizontalIndent = 10;
        myText.setLayoutData(gd);

        myText.addListener(SWT.MouseWheel, new Listener() {
            @Override
            public void handleEvent(Event event) {
                if (!myText.isFocusControl() ) {
                    System.out.println("no focus");
                    Control wheelControl = myText.getParent();

                    Point cursorPos = wheelControl.toControl(event.display.getCursorLocation());
                    event.x = cursorPos.x;
                    event.y = cursorPos.y;
                    event.widget = wheelControl;
                    wheelControl.forceFocus();
                    wheelControl.notifyListeners(SWT.MouseWheel, event);
                    myText.setCapture(false);
                } else {
                    System.out.println("Focus control");
                    myText.setCapture(true);
                }
            }
        });

        mySc.setMinSize(myComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        // TODO Auto-generated method stub
    }

    @Override
    public void setFocus() {
        // TODO Auto-generated method stub
    }
}

我找到的解决方案是禁用垂直滚动条。这也会禁用鼠标滚轮滚动。还使用 SWT 的 addMouseWheelListener()mouseScrolled() 方法代替 addListener()。不仅仅是使用它的 getOrigin() 方法滚动 ScrolledComposite。

myText.addMouseWheelListener(new MouseWheelListener() {
    @Override
    public void mouseScrolled(MouseEvent e) {
        if (!myText.isFocusControl() ) {
            myText.getVerticalBar().setEnabled(false);
            if (e.count == 3) {
                mySc.setOrigin(sc.getOrigin().x, mySc.getOrigin().y - 30);
            } else if (e.count == -3) {
                mySc.setOrigin(sc.getOrigin().x, mySc.getOrigin().y + 30);
            }
        } else {
            myText.getVerticalBar().setEnabled(true);
        }
    }
});

count 始终 returns 3 或 -3,具体取决于滚动方向。滚动 up/down 的值 30 对我来说很好,可能或多或少用于其他目的。我还没有检查 Windows 机器上的行为。