简体   繁体   English

我应如何防止Tab键激活我的单选按钮,但仍应能够专注于单选按钮的文本

[英]How should i prevent tab key to activate my radio button, but it still should be able to focus on text of radio button

When I'm tabbing through a wizard dialog in swt which contains text boxes, radio buttons, push buttons. 当我浏览swt中的向导对话框时,该对话框包含文本框,单选按钮和按钮。 Problem is whenever I tab through a disabled radio button which looks like ()radioText, this is getting activated like this (.):radioText:, along with this radio buttons, there are 2 text boxes which are to acting the same way when tab key is clicked. 问题是,每当我通过一个看起来像()radioText的禁用单选按钮进行制表时,就会像这样(。):radioText:那样被激活,连同该单选按钮一样,有两个文本框在制表符时的作用相同单击键。 So what is the way so that tab should focus on the radio button but it should not activate it, I mean from ()radioText state to (.)radioText state. 那么,选项卡应将焦点放在单选按钮上而不激活它的方式是什么,我的意思是从()radioText状态更改为(。)radioText状态。 Could some one share their experience in implementing this. 有人可以分享他们在实施此方面的经验。

I have an ugly solution, but it works. 我有一个丑陋的解决方案,但是可以。

Instead of allowing focus to get directly to the radio button, you can put another hidden control before it. 您可以将另一个隐藏的控件放在其前面,而不是让焦点直接移至该单选按钮。 In my cases, I used a canvas. 就我而言,我使用了一块画布。 When that control gets focus, get the selection for the radio buttons following it, set the focus to the first radio button, and then revert the selection back to what it used to be. 当该控件获得焦点时,获取其后的单选按钮的选择,将焦点设置为第一个单选按钮,然后将选择还原为以前的样子。 This works for forward traversal. 这适用于向前遍历。 For backward (CTRL+TAB), you have to do the same with a hidden control after the radio buttons. 对于后退(CTRL + TAB),您必须对单选按钮后的隐藏控件执行相同的操作。

Be aware that with this solution selection listeners can be fired during tab traversal. 请注意,通过此解决方案,可以在选项卡遍历期间触发选择侦听器。 But after it the selection will be as before. 但是选择之后将与以前一样。

Here is a small snippet that does this. 这是一个执行此操作的小片段。 It only works in forward mode, and the canvas is not really hidden. 它仅在前进模式下有效,并且画布并未真正隐藏。 You have to fix the layout for you case. 您必须根据情况修复布局。

public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new GridLayout(1, false));

    new Button(shell, SWT.TOGGLE);
    new Scale(shell, SWT.HORIZONTAL);

    final Canvas invisible = new Canvas(shell, SWT.NONE);
    invisible.addListener(SWT.KeyDown, new Listener() {
        @Override
        public void handleEvent(Event event) {
        }
    });

    final Button radioButton1 = new Button(shell, SWT.RADIO);
    radioButton1.setText("text1");

    final Button radioButton2 = new Button(shell, SWT.RADIO);
    radioButton2.setText("text2");

    invisible.addFocusListener(new FocusListener() {
        @Override
        public void focusGained(FocusEvent e) {
            final boolean selection1 = radioButton1.getSelection();
            final boolean selection2 = radioButton2.getSelection();
            radioButton1.setFocus();
            radioButton1.setSelection(selection1);
            radioButton2.setSelection(selection2);
        }

        @Override
        public void focusLost(FocusEvent e) {
        }
    });

    shell.open();
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
    display.dispose();
}

This answer is for the case where there is a text field after the radio button. 此答案适用于单选按钮后有一个文本字段的情况。 In other cases my other answer can be used. 在其他情况下,可以使用其他答案。 It is not perfect, and it is quite ugly, but maybe it solves your problem. 它并不完美,而且很难看,但也许可以解决您的问题。

Besides the internal state, I keep the selection value as data ( setData() ) and update the official selection after each selection event. 除了内部状态之外,我setData()选择值保留为data( setData() ),并在每次选择事件之后更新正式选择。

Here is the complete snippet: 这是完整的代码段:

public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());

    final Composite composite = new Composite(shell, SWT.NO_RADIO_GROUP);
    composite.setLayout(new GridLayout(2, false));

    new Button(composite, SWT.TOGGLE);
    new Scale(composite, SWT.HORIZONTAL);

    final Button radioButton1 = new Button(composite, SWT.RADIO);
    radioButton1.setText("text1");
    radioButton1.setData("selection", false);
    new Text(composite, SWT.SINGLE);

    final Button radioButton2 = new Button(composite, SWT.RADIO);
    radioButton2.setText("text2");
    radioButton2.setData("selection", false);
    new Text(composite, SWT.SINGLE);

    final Button[] radioGroup = {radioButton1, radioButton2};

    final Listener listener = new Listener() {
        @Override
        public void handleEvent(Event event) {
            final Button button = (Button) event.widget;
            switch (event.type) {
                case SWT.MouseDown:
                    event.widget.setData("selection", true);
                    break;
                case SWT.KeyDown:
                    if (event.keyCode == SWT.SPACE) {
                        event.widget.setData("selection", true);
                    }
                    break;
                case SWT.Selection:
                    final boolean selection = (boolean) button.getData("selection");
                    if (selection != button.getSelection()) {
                        button.setSelection(selection);
                    }
                    if (selection) {
                        for (Button radioButton : radioGroup) {
                            if (radioButton != button) {
                                radioButton.setData("selection", false);
                                radioButton.setSelection(false);
                            }
                        }
                    }
                    break;
            }
        }
    };
    radioButton1.addListener(SWT.MouseDown, listener);
    radioButton1.addListener(SWT.KeyDown, listener);
    radioButton1.addListener(SWT.Selection, listener);
    radioButton2.addListener(SWT.MouseDown, listener);
    radioButton2.addListener(SWT.KeyDown, listener);
    radioButton2.addListener(SWT.Selection, listener);

    shell.open();
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
    display.dispose();
}
package myexamples;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.wb.swt.layout.grouplayout.GroupLayout;
import org.eclipse.wb.swt.layout.grouplayout.LayoutStyle;
import org.eclipse.swt.widgets.Combo;

public class MySample {
    private static Text text;
    private static Text text_1;
    private static Text text_2;

    /**
     * Launch the application.
     * @param args
     */
    public static void main(String[] args) {
        Display display = Display.getDefault();
        Shell shell = new Shell();

        Composite composite = new Composite(shell, SWT.NONE);
        composite.setBounds(197, 177, 393, 110);
        composite.setLayout(new GridLayout(2, false));
        new Label(composite, SWT.NONE);
        new Label(composite, SWT.NONE);

        Button btnButton = new Button(composite, SWT.RADIO);
        btnButton.setText(" Button1");

        Composite composite_1 = new Composite(composite, SWT.NONE);
        composite_1.setLayout(new GridLayout(4, false));
        GridData gd_composite_1 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        gd_composite_1.heightHint = 37;
        gd_composite_1.widthHint = 306;
        composite_1.setLayoutData(gd_composite_1);

        text = new Text(composite_1, SWT.BORDER);
        text.setSize(new Point(10, 8));
        GridData gd_text = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
        gd_text.widthHint = 72;
        text.setLayoutData(gd_text);

        Label lblLabel = new Label(composite_1, SWT.NONE);
        lblLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblLabel.setText("Label2");

        text_1 = new Text(composite_1, SWT.BORDER);
        text_1.setSize(new Point(12, 8));
        GridData gd_text_1 = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
        gd_text_1.widthHint = 60;
        text_1.setLayoutData(gd_text_1);

        Label lblLabel_1 = new Label(composite_1, SWT.NONE);
        lblLabel_1.setText(" Label3");
        new Label(composite_1, SWT.NONE);
        new Label(composite_1, SWT.NONE);
        new Label(composite_1, SWT.NONE);
        new Label(composite_1, SWT.NONE);

        Button btnButton_1 = new Button(composite, SWT.RADIO);
        btnButton_1.setText(" Button2");

        Composite composite_2 = new Composite(composite, SWT.NONE);
        composite_2.setLayout(new GridLayout(5, false));
        GridData gd_composite_2 = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        gd_composite_2.widthHint = 305;
        gd_composite_2.heightHint = 30;
        composite_2.setLayoutData(gd_composite_2);

        Combo combo = new Combo(composite_2, SWT.NONE);
        combo.setSize(new Point(10, 8));
        combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        combo.setEnabled(false);
        Combo combo_1 = new Combo(composite_2, SWT.NONE);
        combo_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        combo_1.setEnabled(false);
        Label lblLabelxyz = new Label(composite_2, SWT.NONE);
        lblLabelxyz.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
        lblLabelxyz.setText("LabelXYZ1");

        text_2 = new Text(composite_2, SWT.BORDER);
        text_2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

        Label lblLabelxyz_1 = new Label(composite_2, SWT.NONE);
        lblLabelxyz_1.setText("LabelXYZ2");
        text_2.setEnabled(false);
        Label label = new Label(shell, SWT.NONE);
        label.setBounds(62, 112, 55, 15);
        label.setText("");
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
}

In a form, if you want to ask a question to a user and that question requires a Yes/No answer, it is nice to display empty options. 在表单中,如果您想向用户提问,而该问题需要是/否答案,则最好显示空白选项。

Besides it is clearer if the user is not able to provide an answer, as he can clearly see what was left out in the form. 此外,由于用户可以清楚地看到表单中遗漏的内容,因此用户是否能够提供答案也更加清楚。

This indeed requires a tweak (as the answers above suggest). 这确实需要进行调整(如以上答案所示)。 I achieved it by adding a 3rd button that I artificially hide and that gets the initial selection (ie the "true" value). 我通过添加第三个按钮实现了这一目的,该按钮被人为隐藏并获得了初始选择(即“ true”值)。

Composite c = toolkit.createComposite(parent);
c.setLayout(new RowLayout());

yesButton = toolkit.createButton(c, "Yes", SWT.RADIO);
noButton = toolkit.createButton(c, "No", SWT.RADIO);

yesButton.setSelection(false);
noButton.setSelection(false);

hiddenButton = toolkit.createButton(c, "", SWT.RADIO);
hiddenButton.setSelection(true);
hiddenButton.addPaintListener(new PaintListener() {
    @Override
    public void paintControl(PaintEvent paintevent) {
        // before you paint, shrink the button size to zero
        ((Button)paintevent.widget).setSize(0, 0);
    }
});

The trick is that you cannot hide the button using setVisible(false), otherwise, the next button in the row will get the selection. 诀窍是您无法使用setVisible(false)隐藏按钮,否则,该行中的下一个按钮将获得选择。

To work around that, you can force the size of the component to zero by intercepting the PaintEvents on the button 要解决此问题,您可以通过拦截按钮上的PaintEvents将组件的大小强制为零。

暂无
暂无

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

相关问题 如何将单选按钮中的字符串保存在arraylist中,并在文本框中显示在下一页 - How should I save string from the Radio Button in arraylist and display it on next page in text box 单击按钮后如何启用/激活单选按钮? - How can I enable/activate a radio button after a button is clicked? 当取消选中复选框或单选按钮时,如何阻止我的if语句更改值 - How do I prevent my if statement from changing the value when a check box or radio button is deselected 我想要一个单选按钮,当检查应该增加计数,这里计数不增加,如果我有一行 - I want to a radio button when checked should increment count ,here count is not incrementting if i have one row 更改单选按钮选中状态时如何从单选按钮组中的单选按钮获取文本 - How to get the text from radio button in a radio group when radio button checked state is changed 如何在选择单选按钮上显示文本字段 - how to display text fields on select the radio button 如何在Android中对齐单选按钮文本? - How to align Radio Button text in Android? 如何在失去焦点的事件中等待单选按钮被选中 - How to wait for radio button to get selected in lost focus event 我如何确保从单选按钮组中选择单选按钮会影响其他单选按钮组中单选按钮的选择。 - How do i ensure that the selection of a radio button from a radio group affects the selection of a radio button in a different radio group. 如何自定义右侧的单选按钮? - How can I customise a radio button on the right?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM