Java 当我的JButton';它点击了吗?

Java 当我的JButton';它点击了吗?,java,swing,validation,Java,Swing,Validation,我正在处理一个Java7Swing“向导”类型的项目,在继续向导的下一步之前,需要验证一个web地址。验证需要通过internet访问URL,以验证预期资源是否可用。在某些情况下,这可能需要几秒钟的时间,这足以让用户感到困惑 作为一个快速解决方案,我想禁用“下一步”按钮,并在验证运行时更改显示文本,以便用户知道向导正在工作,而不会挂断任何连接。问题是,当我添加代码来修改JButton时,在验证完成之前,不会发生任何更改。即使在执行验证方法之前更改按钮并调用revalidate(),情况也是如此

我正在处理一个Java7Swing“向导”类型的项目,在继续向导的下一步之前,需要验证一个web地址。验证需要通过internet访问URL,以验证预期资源是否可用。在某些情况下,这可能需要几秒钟的时间,这足以让用户感到困惑

作为一个快速解决方案,我想禁用“下一步”按钮,并在验证运行时更改显示文本,以便用户知道向导正在工作,而不会挂断任何连接。问题是,当我添加代码来修改JButton时,在验证完成之前,不会发生任何更改。即使在执行验证方法之前更改按钮并调用
revalidate()
,情况也是如此

以下是我尝试过的内容的摘录:

// create next button
next = new JButton("Next", new ImageIcon(getClass().getResource("/navigate_right.png")));

next.setActionCommand("MYACTION");
next.addActionListener(new ActionListener()
{
    @Override
    public void actionPerformed(ActionEvent e)
    {
        System.out.println("Is this the event dispatch thread? "
                + javax.swing.SwingUtilities.isEventDispatchThread());
        System.out.println("Changing button");

        next.setEnabled(false);
        next.setText("Testing Connection");
        next.getRootPane().revalidate();

        System.out.println("Validating Service");
        boolean isValidLocation = ServiceValidator.serviceExists(locationField.getText());

        // ...etc...
当我运行此代码时,“更改按钮”和“验证服务”这两行都会在实际按钮在显示中更改之前打印出来。如何在
System.out.println(“验证服务”)之前更改JButton是否已打印

问题是,当我添加代码来修改JButton时,在验证完成之前,不会发生任何更改

您的代码正在EDT上执行,因此长时间运行的代码会阻止GUI在任务完成执行之前重新绘制自身。对于长时间运行的任务,您需要使用单独的线程,可能是
SwingWorker
。有关更多信息,请阅读上的Swing教程部分

问题是,当我添加代码来修改JButton时,在验证完成之前,不会发生任何更改


您的代码正在EDT上执行,因此长时间运行的代码会阻止GUI在任务完成执行之前重新绘制自身。对于长时间运行的任务,您需要使用单独的线程,可能是
SwingWorker
。有关更多信息,请阅读Swing教程中的部分。

我推荐这篇关于这个主题的教程:我不确定我是否理解为什么并发会成为这里的一个问题。我不需要同时跑,是吗?我想执行一个命令,然后执行另一个命令。对吗?您确实希望它们同时运行,您希望它在用户执行命令的同时为用户重新绘制。重画是在EDT上进行的。我想让我挂断电话的是为什么我打电话给它时它没有重画。如果我的代码在EDT上运行,而重绘在EDT上运行,那么这就向我表明它应该在我调用它时执行。我可以通过直接调用repaint()方法而不是revalidate()来解决这个问题吗?@quakkels每当您更改Swing组件的属性时,它都会为您执行revalidate()和repaint()。问题是repaint()方法调用RepaintManager,而RepaintManager会将绘制请求添加到EDT的末尾,因此直到所有其他代码(即长时间运行的任务)都被执行时,才会执行该请求已经完成了执行。我推荐这篇关于这个主题的教程:我不知道为什么并发会成为这里的一个问题。我不需要同时跑,是吗?我想执行一个命令,然后执行另一个命令。对吗?您确实希望它们同时运行,您希望它在用户执行命令的同时为用户重新绘制。重画是在EDT上进行的。我想让我挂断电话的是为什么我打电话给它时它没有重画。如果我的代码在EDT上运行,而重绘在EDT上运行,那么这就向我表明它应该在我调用它时执行。我可以通过直接调用repaint()方法而不是revalidate()来解决这个问题吗?@quakkels每当您更改Swing组件的属性时,它都会为您执行revalidate()和repaint()。问题是repaint()方法调用RepaintManager,而RepaintManager会将绘制请求添加到EDT的末尾,因此直到所有其他代码(即长时间运行的任务)都被执行时,才会执行该请求已完成执行。阅读此内容,它将回答您的所有问题以及如何修复:阅读此内容,它将回答您的所有问题以及如何修复: