我的示例代码import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;public class MyTestFrame extends JFrame {

/**
 * @param args
 */
private JPanel panel;
private JButton button;
private JTextField textField;
public MyTestFrame(){
super();
init();
}
private void init(){
setSize(800, 600);
setContentPane(getPanel());
this.setResizable(false);
setTitle("TestFrame");
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
this.setBackground(Color.WHITE);
this.addWindowListener(new WindowListener() {
public void windowActivated(WindowEvent e) {

}

public void windowClosed(WindowEvent e) {

}

public void windowClosing(WindowEvent e) {
System.exit(0);
}

public void windowDeactivated(WindowEvent e) {

}

public void windowDeiconified(WindowEvent e) {

}

public void windowIconified(WindowEvent e) {

}

public void windowOpened(WindowEvent e) {

}

});


}
private JPanel getPanel(){
if(panel==null){
panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setLayout(null);
button = new JButton();
button.setBounds(370, 200, 60, 20);
button.setText("OK");
button.addActionListener(new ActionListener(){ @Override
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText()+"A");
try {
Thread.sleep(500);//模拟业务所需时间
} catch (InterruptedException e1) {


}

}

});
textField = new JTextField();
textField.setBounds(350, 160, 100, 20);
panel.add(button);
panel.add(textField);
}
return panel;
} public static void main(String[] args) {
new MyTestFrame().setVisible(true);

}

}
当我在textField中输入内容 然后处理,处理结束。将结果写入textField。用户根据情况决定是否继续执行处理,所以不能使用enable=false。问题是,如果不小心双击就会造成不必要的处理。如何避免用户连续点击问题。在处理结束时,弹出对话框会解决这个问题。有没有个更好的解决办法。还有为什么弹出对话框就能解决?重新设定了事件派发还是remove了事件。还有在事件中设置 button.setEnable(false),那么后续事件 也就是连续点击事件就不会触发,是什么道理,连续点击的事件是否进入了事件派发线程。手头没有好的swing书籍。推荐一本。问题较多,谢谢!

解决方案 »

  1.   

    晕,你的问题就是要打到所谓的锁屏问题吧。连续点击的事件会添加到事件派发线程队列中,当事件派发线程空闲时顺序执行,所以就有可能在长时间事件处理,界面不友好会造成多次点击(比如我们在打游戏的时候应该对用户的心情有很深的了解)。锁屏分为假锁 和 真锁:1、假锁:就是通过setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));实现,最好通过try/catch/finally实现,在最开始的设置光标WAIT,
       在finally中设置setCursor(Cursor.getDefaultCursor());  实际上就是给用户警示,我已经开始处理业务了。2、真锁:我当初的实现就是接管事件派发线程,event.getNextEvent()如果是Button触发的,抛弃不执行。//不过并不提倡这么做。还有就是通过setEnabled(状态)来处理,同样也是要在finally中setEnabled(true);设置setEnable(false),实际上还是有Action的,只是Button的状态并不满足事件的触发条件而已,并不是将监听remove
            if (b) {
                stateMask |= ENABLED;
            } else {
                stateMask &= ~ENABLED;
        // unarm and unpress, just in case
                stateMask &= ~ARMED;
                stateMask &= ~PRESSED;
            }建议去看看 O'reilly的Java Swing
      

  2.   

    import java.awt.Color;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowEvent;
    import java.awt.event.WindowListener;import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;public class MyTestFrame extends JFrame {

    /**
     * @param args
     */
    private JPanel panel;
    private JButton button;
    private JTextField textField;

    public MyTestFrame() {
    super();
    init();
    }

    private void init() {
    setSize(800, 600);
    setContentPane(getPanel());
    this.setResizable(false);
    setTitle("TestFrame");
    setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
    this.setBackground(Color.WHITE);
    this.addWindowListener(new WindowListener() {
    public void windowActivated(WindowEvent e) {

    }

    public void windowClosed(WindowEvent e) {

    }

    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }

    public void windowDeactivated(WindowEvent e) {

    }

    public void windowDeiconified(WindowEvent e) {

    }

    public void windowIconified(WindowEvent e) {

    }

    public void windowOpened(WindowEvent e) {

    }

    });

    }

    private JPanel getPanel() {
    if (panel == null) {
    panel = new JPanel();
    panel.setBackground(Color.WHITE);
    panel.setLayout(null);
    button = new JButton();
    button.setBounds(370, 200, 60, 20);
    button.setText("OK");
    button.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
    new Thread() {

    public void run() {
    try {
    button.setEnabled(false);
    textField.setText(textField.getText() + "A");
    try {
    Thread.sleep(500);// 模拟业务所需时间
    } catch (InterruptedException e1) {

    }
    } finally {
    button.setEnabled(true);
    }
    }
    }.start();

    }

    });
    textField = new JTextField();
    textField.setBounds(350, 160, 100, 20);
    panel.add(button);
    panel.add(textField);
    }
    return panel;
    }

    public static void main(String[] args) {
    new MyTestFrame().setVisible(true);

    }

    }
    修改如上实现了目的 不知合理不?
      

  3.   

    可以这么实现,比较简单。最好配合光标的设置:
                                try {
                                    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                                    button.setEnabled(false);
                                    textField.setText(textField.getText() + "A");
                                    try {
                                        Thread.sleep(500);// 模拟业务所需时间
                                    } catch (InterruptedException e1) {
                                        
                                    }
                                } finally {
                                    button.setEnabled(true);
                                    setCursor(Cursor.getDefaultCursor());
                                }