2017-10-21 104 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

相關問題