我的程序中有一个JSlider。当滑块的值改变时,程序会执行某些操作。我想要做的是增加滑块的值直到它的最大值,我需要等待每次滑块值增加我在ChangeListener类中做的事情。
这是我的相关代码(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(我使用sleep()方法的毫秒)并且它同时执行所有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语句放在了但是两种方式都没有用。我不知道我是否将其转换得很好。你能帮忙解决这个问题吗?
答案 0 :(得分:0)
这是我从你的问题中理解的:你在Slider change listener中进行了长时间的计算。您想要对一系列值执行计算,并在滑块上反映出来。
如果上述前提是正确的,那么在计算过程中你不想睡n秒 - 你想等待它们完成并尽快继续。一种方法是在锁上使用wait和notify命令(注意,最近的Java附带了java.util.concurrent包,其中包含更高级别的多线程控件,我认为最好使用,但是我&#39;我自己并不熟悉)
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);
});
}
}