while循环重复actionPerformed的JButton

时间:2017-11-17 19:18:48

标签: java swing while-loop do-while

我的JFrame有一些JButtons。 "更新"按钮(名为JButton1)执行许多填充表单的查询。 现在,我希望另一个JButton成为"自动更新" (名为JButton2),所以我希望它在JButton1ActionPerformed方法中循环,直到不再选择JButton2。 当我按JButton2时窗口冻结。

我的代码是对的吗?你认为我需要一个停止按钮吗?

private void jToggleButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                               

       long start = System.currentTimeMillis();
       if(jToggleButton2.isSelected()){
           start = System.currentTimeMillis();

            do{
                do{
                    jButton1ActionPerformed(evt);
                }
                while(System.currentTimeMillis()-start>3000);

            }
            while(jToggleButton2.isSelected()); 
       }

        if(jToggleButton2.isSelected()){
            jToggleButton2.setSelected(false);
        }


    }  

2 个答案:

答案 0 :(得分:2)

Swing是:

  • 单线程;这意味着您不应在Event Dispatching Thread
  • 的上下文中执行任何长时间运行或阻塞操作
  • 不是线程安全的;这意味着您不应该更新UI或UI可能依赖于EDT之外的任何内容。尝试解决EDT之外的UI元素也存在风险,因为线程模型可能会返回错误值

如果没有更多问题上下文,我可能会建议使用Swing function Uncheck-SelectAllBox { $cb4Checkbox.Checked = $false } $CBlabel = New-Object System.Windows.Forms.Label $CBlabel.Location = New-Object System.Drawing.Point(10,125) $CBlabel.Size = New-Object System.Drawing.Size(280,20) $CBlabel.Text = "Select a box:" $form.Controls.Add($CBlabel) $cb1Checkbox = New-Object System.Windows.Forms.Checkbox $cb1Checkbox .Location = New-Object System.Drawing.Size(10,145) $cb1Checkbox .Size = New-Object System.Drawing.Size(280,20) $cb1Checkbox .Text = "Checkbox 1" $cb1Checkbox.add_click({ Uncheck-SelectAllBox }) $form.Controls.Add($cb1Checkbox) $cb2Checkbox = New-Object System.Windows.Forms.Checkbox $cb2Checkbox .Location = New-Object System.Drawing.Size(10,165) $cb2Checkbox .Size = New-Object System.Drawing.Size(280,20) $cb2Checkbox .Text = "Checkbox 2" $cb2Checkbox.add_click({ Uncheck-SelectAllBox }) $form.Controls.Add($cb2Checkbox) $cb3Checkbox = New-Object System.Windows.Forms.Checkbox $cb3Checkbox .Location = New-Object System.Drawing.Size(10,185) $cb3Checkbox .Size = New-Object System.Drawing.Size(280,20) $cb3Checkbox .Text = "Checkbox 3" $cb3Checkbox.add_click({ Uncheck-SelectAllBox }) $form.Controls.Add($cb3Checkbox) $cb4Checkbox = New-Object System.Windows.Forms.Checkbox $cb4Checkbox.Location = New-Object System.Drawing.Size(x,y) $cb4Checkbox.Size = New-Object System.Drawing.Size(x,y) $cb4Checkbox.Text = "Checkbox 4 - Select All" $cb4Checkbox.Add_Click({ If ($cb4CheckBox.Checked -eq $true){ $cb1Checkbox.Checked = $true $cb2Checkbox.Checked = $true $cb3Checkbox.Checked = $true } }) $form.Controls.Add($cb4Checkbox) 。两个主要原因:

  1. 在EDT的上下文中调用Timer,从而可以安全地从内部更新UI
  2. 您可以指定更新之间的延迟,从而降低EDT过载的风险,从而导致性能问题
  3. 例如......

    ActionListener

    另一个解决方案可能是使用private void jToggleButton2ActionPerformed(java.awt.event.ActionEvent evt) { long start = System.currentTimeMillis(); if (jToggleButton2.isSelected()) { // You could use an instance field instead and determine // if the Timer is already running or not Timer timer = new Timer(100, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (!jToggleButton2.isSelected()) { ((Timer) e.getSource()).stop(); return; } jButton1ActionPerformed(evt); } }); timer.start(); // Just want to point out that this doesn't make sense // As if the button was selected, you'd still be in // your previous loop //if (jToggleButton2.isSelected()) { // jToggleButton2.setSelected(false); //} } } ,它为您提供了一种在EDT上执行长时间运行或阻止操作的方法,但它也提供了从EDT内安全更新UI的功能。

    看看:

    了解更多详情

答案 1 :(得分:-1)

让我们放下你不应该像我会告诉你的那样克服线程(例如使用var pageTitle = $("#titleHolder").data("page-title"); )你需要做这样的事情:

private void jToggleButton2ActionPerformed(java.awt.event.ActionEvent evt){

SwingWorker

我不关注你的代码是否有效,它只是展示了如何在后台运行,所以你不会冻结你的GUI。