2017-10-21 67 views
1

我的程序中有一个JSlider。当滑块的值发生变化时,程序会执行某些操作。我想要做的是增加滑块的值直到它的最大值,并且我需要等待每次滑块值增加时,我在ChangeListener类中做的事情。如何在侦听器正在工作时让Java程序等待?

这是我的相关码(svPlay是像一个播放按钮):

this.svPlay.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      for(int i=slider.getValue()+1;i<=slider.getMaximum();i++){ 
       slider.setValue(i); 
       try{ 
        Thread.sleep(1000); 
       }catch (Exception ex){ 
        ex.printStackTrace(); 
       } 
      } 
     } 
    }); 

的问题是,例如,如果I = 10,则程序等待10 * 1000(milisecond我睡眠使用( )方法),它同时执行所有changeListener作业。

在slider.setValue(i)之后,changeListener必须工作,然后程序应睡眠1000 ms。我怎样才能做到这一点?

编辑:这是我如何根据上述代码更改我的程序。但是,当滑块值被改变并且滑块“冻结”时,现在什么也没有发生。

this.slider.addChangeListener(new ChangeListener() { 
     @Override 
     public void stateChanged(ChangeEvent e) { 
      new Thread(() -> { 
       try { 
        synchronized (lock) { 
         Thread.sleep(1234); 
         if(checkBox.isSelected()){ 
          CyApplicationManager manager = adapter.getCyApplicationManager(); 
          CyNetworkView networkView = manager.getCurrentNetworkView(); 
          CyNetwork network = networkView.getModel(); 
          CyTable table = network.getDefaultNodeTable(); 
          FilterUtil filter = new FilterUtil(network,table); 
          ArrayList<CyNode> activities = filter.FilterRowByNodeType("activity", "nodeType"); 

          CyColumn timeColumn = table.getColumn("startTime"); // Getting start time column 
          List<String> timeList = filter.getTimeFromColumn(timeColumn); // Gets value of start time column without null value 
          sliderVisualization.sortActivityTimes(timeList, activities); 
          sliderLabel.setText(timeList.get(slider.getValue())); 
          sliderVisualization.hideFutureNodes(timeList, filter, network, networkView); 
          networkView.updateView(); 
         } 
         lock.notify(); 
        } 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      }).start(); 

     } 
    }); 

    this.svPlay.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      new Thread(() -> { 
       slider.setEnabled(false); 
       for(int i=slider.getValue()+1;i<=slider.getMaximum();i++){ 
        synchronized (lock) { 
         slider.setValue(i); 
         try { 
          lock.wait(); 
         } catch (Exception ex) { 
          ex.printStackTrace(); 
         } 
        } 
       } 
       slider.setEnabled(true); 
      }).start(); 
     } 
    }); 

我把if语句之前和Thread.sleep()方法中addChangeListener方法后,但两者的方法没有奏效。我不知道我是否转换得好。你能帮助通过这个代码吗?

+1

目前还不清楚你到底想达到什么目的。因为你在等待我假设要在不同的线程上完成的事情,所以也要睡觉任意时间,这是不好的方法。你最好在svPlay监听器里面使用'wait',在滑块监听器里面使用'notify'。 –

+0

@CoderinoJavarino我试了通知和notifyAll,但它没有奏效。这一次,滑块内部的事情改变了侦听器,只有我点击svPlay按钮。简单地说,我希望这样:程序应该在每次更改滑块值并等待滑块更改侦听器工作后等待1秒钟。我怎样才能做到这一点? – JollyRoger

+0

@CoderinoJavarino其实我试着将这段代码转换成我的程序,但我无法做到。你能看看下一个答案吗? – JollyRoger

回答

0

这是我从你的问题中了解到的:你在滑块变化侦听器中进行了长时间的计算。您希望对一系列值执行计算,并将其反映在滑块上。

如果上述前提是正确的,则在计算进行时您不想睡眠n秒 - 您想等待它们完成并尽快完成。一种方法是在锁上使用wait和notify命令(请注意,最近的Java随java.util.concurrent包一起提供,它包含更高级别的多线程控制,我认为使用会更好,但是我不是我自己也很熟悉)

package testas; 

import javax.swing.*; 

public class Slider { 

    static class View { 

     public JPanel panel; 
     public JSlider slider; 
     public JButton button; 
     public JTextField tf; 

     public View() { 
      panel = new JPanel(); 
      button = new JButton("a"); 
      slider = new JSlider(); 
      tf = new JTextField(4); 
      panel.add(button); 
      panel.add(slider); 
      panel.add(tf); 
     } 


    } 

    static class Controller { 

     private Object lock; 
     private View view; 

     public Controller() { 
      lock = new Object(); 
     } 

     private synchronized void buttonHandler() { 
      new Thread(() -> { 
       view.slider.setEnabled(false); 
       for(int i=view.slider.getValue()+1;i<=view.slider.getMaximum();i++){ 
        synchronized (lock) { 
         view.slider.setValue(i); 
         try { 
          lock.wait(); 
         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
       } 
       view.slider.setEnabled(true); 
      }).start(); 
     } 

     private synchronized void sliderChangeHandler(int value) { 
      new Thread(() -> { 
       try { 
        synchronized (lock) { 
         Thread.sleep(1234);//some long calculations 
         view.tf.setText(String.valueOf(value)); 
         lock.notify(); 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      }).start(); 
     } 

     public void setView(View v) { 

      view = v; 
      v.button.addActionListener(l -> buttonHandler()); 
      v.slider.addChangeListener(l -> { 
       JSlider slider = (JSlider) l.getSource(); 
       if (!slider.getValueIsAdjusting()) 
        sliderChangeHandler(slider.getValue()); 
      }); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      Controller c = new Controller(); 
      View v = new View(); 
      c.setView(v); 
      JFrame f = new JFrame(); 
      f.add(v.panel); 
      f.pack(); 
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      f.setVisible(true); 
     }); 
    } 
} 
+0

是的,你理解正确。我相信这段代码可以解决我的问题。但有太多的概念,我以前没有用过。我正在尝试找到一种方法将此代码适用于我的程序。非常感谢你的回答。 – JollyRoger

相关问题