2017-10-21 2 views
1

Ich habe einen JSlider in meinem Programm. Programm macht etwas, wenn der Wert des Schiebereglers geändert wird. Was ich tun möchte, ist, den Wert des Schiebereglers bis zu seinem Maximalwert zu erhöhen und ich muss jedes Mal warten, wenn der Schiebereglerwert für die Dinge, die ich in der ChangeListener-Klasse mache, erhöht wird.Wie Java-Programm warten, während ein Listener arbeitet?

Hier sind meine verwandten Codes (svPlay wie eine Play-Taste ist):

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

Das Problem ist, zum Beispiel, wenn i = 10, dann wartet Programm 10 * 1000 (milisecond, die ich mit dem Schlaf verwendet () Methode) und alle ChangeListener-Jobs gleichzeitig ausführt.

Nach slider.setValue (i) muss changeListener funktionieren und dann sollte das Programm für 1000 ms schlafen. Wie kann ich das machen?

Edit: So habe ich mein Programm geändert, laut obigem Code. Aber jetzt passiert nichts, wenn der Schiebereglerwert geändert wird und der Schieberegler "einfriert".

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

Ich habe if-Anweisung vor und nach Thread.sleep() in addChangeListener Verfahren aber beide Art und Weise nicht funktioniert hat. Ich weiß nicht, ob ich es gut umsetze oder nicht. Können Sie bitte durch diesen Code helfen?

+1

Es ist nicht klar für mich, was genau Sie erreichen möchten. Auch schlafen für eine willkürliche Menge Zeit, weil Sie darauf warten, was ich davon ausgehe, dass etwas auf einem anderen Thread getan wird, ist ein schlechter Ansatz. Es wäre besser, wenn Sie innerhalb des svPlay-Listeners 'wait' verwenden und innerhalb des Slider-Listeners' notify'. –

+0

@CoderinoJavarino Ich versuchte sowohl notify und notifyAll, aber es hat nicht funktioniert. Dieses Mal die Dinge, die innerhalb des Sliders geändert wird, funktioniert der Hörer nur, wenn ich auf die SVPlay-Taste klicke. Einfach möchte ich das: Programm sollte für 1 Sekunde warten, nachdem jeder Schieberegler Wert geändert und Slider geändert Listener arbeitet. Wie kann ich das machen? – JollyRoger

+0

@CoderinoJavarino Eigentlich habe ich versucht, diesen Code in mein Programm zu konvertieren, aber ich konnte es nicht schaffen. Kannst du bitte die nächste Antwort sehen? – JollyRoger

Antwort

0

Das ist, was ich von Ihrer Frage verstehe: Sie haben lange Berechnungen in Slider Change Listener. Sie möchten Berechnungen für einen Bereich von Werten durchführen und dies auf dem Schieberegler widerspiegeln.

Wenn die obige Prämisse korrekt ist, möchten Sie nicht n Sekunden schlafen, während die Berechnungen ausgeführt werden - Sie möchten darauf warten, dass sie fertig sind und so schnell wie möglich fortfahren. Eine Möglichkeit, dies zu tun, ist die Verwendung von Warte- und Benachrichtigungsbefehlen für eine Sperre (beachten Sie, dass Java in letzter Zeit mit dem java.util.concurrent-Paket geliefert wird, das ein Multithreading-Steuerelement höherer Ebene enthält und ich denke, dass es besser wäre vertraut mit ihm selbst)

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

Ja, Sie verstehen korrekt. Ich bin sicher, dass dieser Code mein Problem lösen kann. Aber es gibt so viele Konzepte, die ich noch nie benutzt habe. Ich versuche einen Weg zu finden, diesen Code an mein Programm anzupassen. Vielen Dank für Ihre Antwort. – JollyRoger

Verwandte Themen