2017-10-21 14 views
1

私のプログラムにJSliderがあります。スライダの値が変更されると、プログラムは何かをします。私がしたいのは、スライダの値をその最大値まで増加させ、ChangeListenerクラスで行うことのためにスライダの値が増加するたびに待つ必要があるということです。リスナーが動作している間にJavaプログラムを待機させる方法は?

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(); 
       } 
      } 
     } 
    }); 

私は= 10、その後、プログラムは、私は眠りに使用さ10×1000(milisecondを待つならば、問題は、例えば、(:ここ

は私の関連するコード(svPlayが再生ボタンのようなものである)であります)メソッド)を実行し、同時にすべてのchangeListenerジョブを実行します。

slider.setValue(i)の後、changeListenerは動作しなければならず、プログラムは1000ミリ秒間スリープする必要があります。どうやってやるの?

編集:これは私のプログラムを上記のコードに従って変更した方法です。しかし、スライダの値が変更され、スライダが「フリーズ」しても何も起こりません。

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(); 
     } 
    }); 

は私が前とのaddChangeListener方法でのThread.sleep()の後にif文を入れますが、両方の方法は、働いていませんでした。私はそれをうまく変換するかどうかわかりません。あなたはこのコードを助けてくれますか?

+1

正確に何を達成したいのかはわかりません。また、あなたが何か別のスレッドで行われるものと仮定して待っているので、任意の時間量のために寝ていることは悪いアプローチです。あなたはsvPlayリスナの中で 'wait'を使う方が良いでしょう。スライダリスナの中で' notify'するのが良いでしょう。 –

+0

@CoderinoJavarino私はnotifyとnotifyAllの両方を試しましたが、うまくいきませんでした。今回は、スライダーの変更されたリスナーの中にあるものだけが動作します。私はsvPlayボタンをクリックします。単純に私はそれが欲しいです:スライダの値が変更され、スライダが変更されたリスナが働くたびに、プログラムは1秒間待たなければなりません。どうやってやるの? – JollyRoger

+0

@CoderinoJavarino実際にこのコードをプログラムに変換しようとしましたが、できませんでした。あなたは次の答えを見ていただけますか? – JollyRoger

答えて

0

これは私があなたの質問から理解していることです。スライダ変更リスナーで長い計算が行われています。ある範囲の値に対して計算を行い、その値をスライダに反映させたいとします。

上記の前提が正しい場合、計算が実行されている間にn秒間スリープ状態にしたくない場合は、それらが完了してからお待ちください。これを行う1つの方法は、ロックに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

関連する問題