繁体   English   中英

全局禁用SWT对话框中的输入/返回键

[英]globally disable enter/return key in a SWT dialog

我创建了一个对话框类,填充了一些常见的小部件,如文本,组合和树。 当我按下任何一个小部件时按下回车/返回时,有一个默认行为来解除这个对话框(与按下默认的'OK'按钮相同)很烦人。

为了防止这种行为,我必须为每个小部件添加一个遍历侦听器来过滤遍历键:

if (SWT::TRAVERSE_RETURN == event.detail) {
  event.doit = false 
}

这有点烦人。 有没有办法在对话级别全局做?

我发现在JFace对话框中,通过重写createButtonsForButtonBar方法可以很容易地禁用默认的Enter键。

和最后一个参数:

createButton(parent,IDialogConstants.OK_ID,IDialogConstants.OK_LABEL,false);

需要是假的:

@Override
protected void createButtonsForButtonBar(Composite parent) {
Button button = createButton(parent, IDialogConstants.OK_ID,
        IDialogConstants.OK_LABEL, false);
}

根据这个帖子 ,这似乎是唯一的方法,也由Snippet127说明(“防止Tab从遍历控件”)

可能是这个Dialog说明了TraverseListenerkeyTraversed()方法的全局使用。

你可以将默认按钮设置为null(Shell #setDefaultButton(null))以防止完整对话框的行为,否则我猜你必须挑出你想要按下Enter键的小部件。

看起来我的答案太晚了,也许我的解决方案在2009年是不可能的......但无论如何我发布它。

可以使用Display.addFilter解决此问题。 您必须在程序开头的某处为遍历事件添加过滤器。

Display.getDefault().addFilter( SWT.Traverse, new Listener() {
    @Override
    public void handleEvent( Event event ) {
        if( SWT.TRAVERSE_RETURN == event.detail ) {
            System.out.println( "Global SWT.TRAVERSE_RETURN" );
            event.doit = false;
        }
    };
} );

稍后您创建对话框,其默认按钮不起作用:

Shell shell = new Shell( SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL );
shell.setLayout( new GridLayout( 2, false ) );
shell.setSize( 250, 100 );

Label loginLabel = new Label( shell, SWT.NONE );
loginLabel.setLayoutData( new GridData( SWT.LEFT, SWT.CENTER, false, false ) );
loginLabel.setText( "Login" );

Text text = new Text( shell, SWT.BORDER );
text.setLayoutData( new GridData( SWT.FILL, SWT.CENTER, true, false ) );

Composite buttonsContentComposite = new Composite( shell, SWT.NONE );
buttonsContentComposite.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, false, 2, 1 ) );
buttonsContentComposite.setLayout( new GridLayout( 2, false ) );

Button okButton = new Button( buttonsContentComposite, SWT.PUSH );
okButton.setLayoutData( new GridData( SWT.RIGHT, SWT.CENTER, true, false ) );
okButton.setText( "Ok" );
okButton.addSelectionListener( new SelectionAdapter() {
    @Override
    public void widgetSelected( SelectionEvent e ) {
        System.out.println( "Ok" );
    };
} );

Button cancelButton = new Button( buttonsContentComposite, SWT.PUSH );
cancelButton.setLayoutData( new GridData( SWT.LEFT, SWT.CENTER, false, false ) );
cancelButton.setText( "Cancel" );
cancelButton.addSelectionListener( new SelectionAdapter() {
    @Override
    public void widgetSelected( SelectionEvent e ) {
        System.out.println( "Cancel" );
    };
} );

shell.setDefaultButton( okButton );

shell.open();
while (!shell.isDisposed()) {
    if( !Display.getCurrent().readAndDispatch() ) {
        Display.getCurrent().sleep();
    }
}

Filter捕获遍历事件并禁止将其发送到shell,因此默认按钮将不起作用。 但是这个解决方案有一个细微差别 - 你可以为shell添加Traverse监听器并覆盖全局过滤器效果:

shell.addTraverseListener( new TraverseListener() {
    @Override
    public void keyTraversed( TraverseEvent event ) {
        event.doit = true;
    }
} );

此侦听器启用事件返回和默认按钮将被触发。

我对此问题的解决方案,到目前为止似乎工作,是创建一个不可见的禁用按钮,并将其设置为shell的默认按钮。 为了避免弄乱布局的其余部分,我使用传递给createButtonsForButtonBar()的父对象在对话框的按钮栏中创建了按钮。

    final Button hiddenButton = new Button(parent, SWT.PUSH);
    hiddenButton.setVisible(false);
    hiddenButton.setEnabled(false);
    parent.getShell().setDefaultButton(hiddenButton);

现在,所有默认选择事件都会按下该按钮。 根据需要,它什么都不做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM