当我在 swt 中通过包含文本框、单选按钮、按钮的向导对话框进行切换时。问题是每当我通过一个看起来像 ()radioText 的禁用单选按钮进行选项卡时,它会像这样 (.):radioText: 一样被激活,连同这个单选按钮,有 2 个文本框在选项卡时的行为方式相同键被点击。那么,选项卡应该专注于单选按钮但不应该激活它的方式是什么,我的意思是从 ()radioText 状态到 (.)radioText 状态。有人可以分享他们实施这一点的经验吗?
4 回答
我有一个丑陋的解决方案,但它有效。
您可以在它之前放置另一个隐藏控件,而不是让焦点直接到达单选按钮。在我的情况下,我使用了画布。当该控件获得焦点时,获取其后面的单选按钮的选择,将焦点设置为第一个单选按钮,然后将选择恢复为以前的状态。这适用于前向遍历。对于后退 (CTRL+TAB),您必须对单选按钮后的隐藏控件执行相同操作。
请注意,使用此解决方案,可以在选项卡遍历期间触发选择侦听器。但在它之后,选择将和以前一样。
这是一个执行此操作的小片段。它仅在前进模式下有效,并且画布并没有真正隐藏。您必须为您的案例修复布局。
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();
}
此答案适用于单选按钮后有文本字段的情况。在其他情况下,可以使用我的其他答案。它并不完美,而且很丑陋,但也许它可以解决您的问题。
除了内部状态,我将选择值保留为数据( ),并在每次选择事件后setData()
更新官方选择。
这是完整的片段:
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();
}
}
}
}
在表单中,如果您想向用户提问并且该问题需要是/否的答案,那么最好显示空选项。
此外,如果用户无法提供答案,则更清楚,因为他可以清楚地看到表单中遗漏了什么。
这确实需要调整(如上面的答案所示)。我通过添加我人为隐藏并获得初始选择(即“真实”值)的第三个按钮来实现它。
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);
}
});
诀窍是您不能使用 setVisible(false) 隐藏按钮,否则,该行中的下一个按钮将获得选择。
要解决此问题,您可以通过拦截按钮上的 PaintEvents 将组件的大小强制为零