Java 对模型使用JTextField(在focusLost上)并对模型数据运行操作
我有一个JavaSwing应用程序,它有许多JTextFields和一个datamodel 离开文本字段(焦点丢失)时,文本将写入模型。到目前为止,一切顺利 有一些JMenu操作从模型中读取数据并将其发送到服务器 问题在于,通过加速器运行菜单操作时,“焦点丢失”不会触发。因此,操作从数据模型读取并传输旧值 有很多方法可以解决这个问题。。。?您是否有建议如何解决此问题 什么对我不起作用:Java 对模型使用JTextField(在focusLost上)并对模型数据运行操作,java,swing,jtextfield,Java,Swing,Jtextfield,我有一个JavaSwing应用程序,它有许多JTextFields和一个datamodel 离开文本字段(焦点丢失)时,文本将写入模型。到目前为止,一切顺利 有一些JMenu操作从模型中读取数据并将其发送到服务器 问题在于,通过加速器运行菜单操作时,“焦点丢失”不会触发。因此,操作从数据模型读取并传输旧值 有很多方法可以解决这个问题。。。?您是否有建议如何解决此问题 什么对我不起作用: 每次按键时写入模型(通过文档侦听器):不可用,应仅在离开文本字段时写入(焦点丢失)。文本在写入模型后进行(昂
- 每次按键时写入模型(通过文档侦听器):不可用,应仅在离开文本字段时写入(焦点丢失)。文本在写入模型后进行(昂贵的)评估-不能在每次按键后运行李>
- 在每个动作中处理对模型的写入。大约有500个文本字段和100个操作。很难匹配而不忘记任何东西李>
可运行的演示代码:
package swingmodel;
import java.awt.FlowLayout;
import java.awt.event.*;
import javax.swing.*;
/**
* Simple Demo Problem. Enter a Text in the first Textfield and press ALT-T. The
* focus listener did no run, therefore the old value from model is displayed.
*/
public class TextDemoOnMenu extends JPanel {
private Model model;
public TextDemoOnMenu() {
super(new FlowLayout());
model = new Model();
MyTextField textField = new MyTextField(20, model);
add(textField);
add(new JTextField(5));
}
class MyTextField extends JTextField {
private Model model;
public MyTextField(int arg, Model model) {
super(arg);
this.model = model;
addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
System.out.println("focus lost");
writeToModel();
}
});
}
public void writeToModel() {
this.model.setText(getText());
}
}
class ShowModelTextAction extends AbstractAction {
public ShowModelTextAction(String string) {
super(string);
}
@Override
public void actionPerformed(ActionEvent e) {
String message = "text is: " + model.getText();
JOptionPane.showMessageDialog(TextDemoOnMenu.this, message);
}
}
class Model {
private String text;
void setText(String t) {
text = t;
}
public String getText() {
return text;
}
}
private void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("TextDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add contents to the window.
frame.add(this);
Action action = new ShowModelTextAction("show text");
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("My Menu");
menuBar.add(menu);
JMenuItem menuItem = new JMenuItem("show text");
menuItem.setAction(action);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, ActionEvent.ALT_MASK));
menu.add(menuItem);
frame.setJMenuBar(menuBar);
// Display the window.
frame.setSize(400, 200);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TextDemoOnMenu().createAndShowGUI();
}
});
}
}
为每个文本字段创建一个脏标志。如果发生保存事件,您可以使用任何脏文本字段更新模型 如果您担心您会“忘记”为特定的文本字段执行此操作,那么问题在于您对文本字段的管理。您应该为它们提供一个工厂方法,该方法可以正确设置它们并为它们创建脏标志
我的另一个建议是,当保存操作发生时,您向隐藏组件请求焦点,以触发textField上的focusLost。保存完成后,您会将焦点返回给以前的所有者 为每个文本字段创建一个脏标志。如果发生保存事件,您可以使用任何脏文本字段更新模型 如果您担心您会“忘记”为特定的文本字段执行此操作,那么问题在于您对文本字段的管理。您应该为它们提供一个工厂方法,该方法可以正确设置它们并为它们创建脏标志
我的另一个建议是,当保存操作发生时,您向隐藏组件请求焦点,以触发textField上的focusLost。保存完成后,您会将焦点返回给以前的所有者 您可以修改所有操作以使用KeyboardFocusManager。您将获得具有焦点的当前组件。如果它是自定义文本字段之一,则可以在处理操作之前强制更新模型 将文本写入模型后,对其进行(昂贵的)评估
而且,听起来你也应该处理焦点问题。然后可以保存原始文本,并在自动更新模型之前对焦点丢失的文本进行比较。(即,如果有人只是在所有文本字段中进行制表符操作会怎么样?)您可以修改所有操作以使用KeyboardFocusManager。您将获得具有焦点的当前组件。如果它是自定义文本字段之一,则可以在处理操作之前强制更新模型 将文本写入模型后,对其进行(昂贵的)评估 而且,听起来你也应该处理焦点问题。然后可以保存原始文本,并在自动更新模型之前对焦点丢失的文本进行比较。(即,如果有人只是在所有文本字段中进行了制表符操作怎么办?)