Java 同步两个JSlider
我写了一个小程序作为初学者练习,用两个JSlider将Celcius转换为华氏温度,反之亦然。我让两个JSliders互相监听,目标是每当我移动一个滑块时,无论是Celcius滑块(窗口中的上一个)还是华氏滑块(下一个),另一个都应该自动移动到正确的位置。但是,程序有一个我无法理解的错误。当我运行它时,它工作了,但我的Celcius学位JLabel在Celcius栏“Clabel”下仅显示为0,5,10,15的度量值。。等等,当我移动它的滑块时。我的华氏度只在9的范围内跳跃,比如0,9,18,27等等。为什么会这样?为什么两个酒吧不能顺畅地移动而不结巴 这是我的密码:Java 同步两个JSlider,java,swing,Java,Swing,我写了一个小程序作为初学者练习,用两个JSlider将Celcius转换为华氏温度,反之亦然。我让两个JSliders互相监听,目标是每当我移动一个滑块时,无论是Celcius滑块(窗口中的上一个)还是华氏滑块(下一个),另一个都应该自动移动到正确的位置。但是,程序有一个我无法理解的错误。当我运行它时,它工作了,但我的Celcius学位JLabel在Celcius栏“Clabel”下仅显示为0,5,10,15的度量值。。等等,当我移动它的滑块时。我的华氏度只在9的范围内跳跃,比如0,9,18,2
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
public class ThermoWindow extends JFrame {
private JSlider C, F;
private JPanel panel, labelpanel;
private JLabel Flabel, Clabel;
public ThermoWindow() {
super("Thermometer Converter");
panel = new JPanel(new BorderLayout());
labelpanel = new JPanel(new BorderLayout());
C = new JSlider(JSlider.HORIZONTAL,-100,100,0);
C.setMajorTickSpacing(10);
C.setMinorTickSpacing(1);
C.setPaintTicks(true);
C.setPaintLabels(true);
F = new JSlider(JSlider.HORIZONTAL,-100,100,toFahrenheit(0));
F.setMajorTickSpacing(10);
F.setMinorTickSpacing(1);
F.setPaintTicks(true);
F.setPaintLabels(true);
Clabel = new JLabel(" C°: " + 0);
Flabel = new JLabel(" F°: " + toFahrenheit(0));
C.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
F.setValue(toFahrenheit(C.getValue()));
Clabel.setText(" C°: " + C.getValue());
}
});
F.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
C.setValue(toCelcius(F.getValue()));
Flabel.setText(" F°: " + F.getValue());
}
});
panel.add(C, BorderLayout.NORTH);
panel.add(F, BorderLayout.SOUTH);
labelpanel.add(Clabel, BorderLayout.NORTH);
labelpanel.add(Flabel, BorderLayout.SOUTH);
panel.add(labelpanel);
add(panel);
setBounds(900,200,900,200);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
}
public int toFahrenheit(int temp){
temp = (int)(temp/(5/(double)9))+32;
return temp;
}
public int toCelcius(int temp){
temp = (int)((temp-32)*(5/(double)9));
return temp;
}
}
public class myThermometer {
public static void main (String[] args){
new ThermoWindow();
}
}
如果我在第二个Changelistener中注释掉以下行
C.setValue(toCelcius(F.getValue()));
然后移动上部的Celcius条会显示在Celcius条下移动的每个Celcius度,如0,1,2,3,4等等(就像它应该的那样)。但是如果我这样做,我会在移动华氏温度条时失去Celcius条上的任何功能,因为我不再使用通过移动华氏温度滑块设置的任何值来控制Celcius条。因此,我坚持认为要么只有上JSlider能够控制下JSlider并显示每个值的变化(比如20,21,22 C),要么两个JSlider相互监听,但只在0,5,10,15 C的间隔内,以此类推
有谁能告诉我,为什么当两个滑块互相监听时,我无法获得每个单位数字变化的平滑反馈?为什么它只在5或9秒内改变?正如您所发现的,您的问题是每个
changelister
都在改变另一个滑块的值。滑块C更改滑块F的值,从而更改滑块C的值,从而更改滑块F的值。只有当每次更改都不会导致另一个滑块的位置发生变化时,这种相互递归才会结束,这种变化发生在5(C)和9(F)上
您需要如下代码:
C.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (!updateInProgress) {
updateInProgress = true;
F.setValue(toFahrenheit(C.getValue()));
updateInProgress = false;
}
Clabel.setText(" C°: " + C.getValue());
}
});
F.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (!updateInProgress) {
updateInProgress = true;
C.setValue(toCelcius(F.getValue()));
updateInProgress = false;
}
Flabel.setText(" F°: " + F.getValue());
}
});
加上declare
private boolean updateInProgress=false在ThermoWindow
类中的code>。问题是,每次在其中一个中设置一个值时,其他值都会更改,这也会触发其回调。由于要对值进行舍入,从0开始,直到将摄氏度光标移动到5为止,华氏度值一直保持在32,另一侧类似