I have a JSlider in my program. Program does something when the value of slider is changed. What I want to do is to increase the value of slider until its max value and I need to wait every time slider value is increased for the things that I do in the ChangeListener class.
Here is my related codes (svPlay is like a play button):
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();
}
}
}
});
The problem is, for example if i=10, then program waits 10*1000(milisecond that I used with sleep() method) and it does all the changeListener jobs at the same time.
After slider.setValue(i), changeListener must work and then program should sleep for 1000 ms. How can I do that?
Edit: This is how I changed my program, according to above code. But now nothing is happening when slider value is changed and slider "freezes".
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();
}
});
I put if statement before and after Thread.sleep() in addChangeListener method but both way did not worked. I do not know if I convert it well or not. Can you help through this code please?
This is what I understand from your question: you have long calculations going on in Slider change listener. You want to perform calculations for a range of values, and reflect that on the slider.
If the above premise is correct, you don't want to sleep n seconds while calculations are going on -- you want to wait for them to finish and proceed asap. One way to do it, is using wait and notify commands on a lock (note, that recent Java comes with java.util.concurrent package, which contains higher level multithreading control and I think would be better to use, however I'm not familiar with it myself)
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);
});
}
}