gpt4 book ai didi

java - 事件无限循环 SWT

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:54:38 26 4
gpt4 key购买 nike

我正在阅读“SWT 和 JFace 的权威指南”,我正在尝试理解以下代码:

public class MultipleListenersExample implements HelpListener, VerifyListener, 
ModifyListener{

// Constants used for conversions
private static final double FIVE_NINTHS = 5.0 / 9.0;
private static final double NINE_FIFTHS = 9.0 / 5.0;

// Widgets used in the window
private Text fahrenheit;
private Text celsius;
private Label help;

/**
* Runs the application
*/
public void run() {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Temperatures");
createContents(shell);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}

/**
* Create the main window's contents
* @param shell the main window
*/
private void createContents(Shell shell) {
shell.setLayout(new GridLayout(3, true));

// Create the label and input box for Fahrenheit
new Label(shell, SWT.LEFT).setText("Fahrenheit:");
fahrenheit = new Text(shell, SWT.BORDER);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
fahrenheit.setLayoutData(data);

// Set the context-sensitive help
fahrenheit.setData("Type a temperature in Fahrenheit");

// Add the listeners
fahrenheit.addHelpListener(this);
fahrenheit.addVerifyListener(this);
fahrenheit.addModifyListener(this);

// Create the label and input box for Celsius
new Label(shell, SWT.LEFT).setText("Celsius:");
celsius = new Text(shell, SWT.BORDER);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
celsius.setLayoutData(data);

// Set the context-sensitive help
celsius.setData("Type a temperature in Celsius");

// Add the listeners
celsius.addHelpListener(this);
celsius.addVerifyListener(this);
celsius.addModifyListener(this);

// Create the area for help
help = new Label(shell, SWT.LEFT | SWT.BORDER);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 3;
help.setLayoutData(data);
}

/**
* Called when user requests help
*/
public void helpRequested(HelpEvent event) {
// Get the help text from the widget and set it into the help label
help.setText((String) event.widget.getData());
}

/**
* Called when the user types into a text box, but before the text box gets
* what the user typed
*/
public void verifyText(VerifyEvent event) {
// Assume you don't allow it
event.doit = false;

// Get the character typed
char myChar = event.character;
String text = ((Text) event.widget).getText();
System.out.println(text);

// Allow '-' if first character
if (myChar == '-' && text.length() == 0) event.doit = true;

// Allow zero to nine
if (Character.isDigit(myChar)) event.doit = true;

// Allow backspace
if (myChar == '\b') event.doit = true;
}

/**
* Called when the user modifies the text in a text box
*/
public void modifyText(ModifyEvent event) {
// Remove all the listeners, so you don't enter any infinite loops
celsius.removeVerifyListener(this);
celsius.removeModifyListener(this);
fahrenheit.removeVerifyListener(this);
fahrenheit.removeModifyListener(this);

// Get the widget whose text was modified
Text text = (Text) event.widget;

try {
// Get the modified text
int temp = Integer.parseInt(text.getText());

// If they modified Fahrenheit, convert to Celsius
if (text == fahrenheit) {
celsius.setText(String.valueOf((int) (FIVE_NINTHS * (temp - 32))));
} else {
// Convert to Fahrenheit
fahrenheit.setText(String.valueOf((int) (NINE_FIFTHS * temp + 32)));
}
} catch (NumberFormatException e) { /* Ignore */ }

// Add the listeners back
celsius.addVerifyListener(this);
celsius.addModifyListener(this);
fahrenheit.addVerifyListener(this);
fahrenheit.addModifyListener(this);
}

/**
* The application entry point
* @param args the command line arguments
*/
public static void main(String[] args) {
new MultipleListenersExample().run();
}

}

在“modifyText”方法中,它删除了所有监听器(VerifyListenerModifyListener),我不明白为什么?为什么会出现死循环?

最佳答案

因为您实际上是在 Text GUI 元素的 modifyText() 方法中修改文本字符串(值),所以此文本更改将触发 ModifyEvent 再次调用 modifyText() 方法。因此,您必须删除这些监听器,将文本更改为适当的值,然后将这些监听器添加回去,否则会发生无限循环。

编辑(基于评论)

你是对的。首先,您在 Text 字段中键入一个键,然后调用 verifyText()。当此方法完成并且输入的文本被批准时,将调用 modifyText() 方法。正如我之前所说,此方法通过 setText() 方法更改 Text 字段的文本字符串。因此,在实际更改文本字符串之前调用 verifyText() 并批准新的文本字符串,然后转到 modifyText() 方法,该方法应该实际更改 Text GUI 元素,但它会尝试调用该元素的 setText() 并再次开始循环。

因此,您在 Text 元素中键入一些数字(如 '5'),调用 verifyText() 并调用 modifyText () 之后,它调用 setText(),它又调用了 verifyText()modifyText(),它调用了 setText(),等等......哦,是的,无限循环就在这里..

关于java - 事件无限循环 SWT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8994732/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com