gpt4 book ai didi

java - 同步两个 JSlider

转载 作者:行者123 更新时间:2023-11-30 08:02:51 27 4
gpt4 key购买 nike

我编写了一个小程序作为初学者练习,使用两个 JSlider 将摄氏度转换为华氏度,反之亦然。我让两个 JSliders 互相监听,目标是每当我移动一个 slider 时,Celcius slider (窗口上方的 slider )或 Fahrenheit slider (窗口下方的 slider ),另一个应该自动移动到正确的位置但是,该程序有一个我无法理解的错误。当我运行它时,它可以工作,但是当我移动它的 slider 时,我的摄氏度 JLabel 在摄氏度栏“Clabel”下仅以 0、5、10、15 等度量显示。而我的 Fahrenheitbar 仅在 9 的距离内跳跃,例如 0、9、18、27 等等。为什么是这样?为什么两个条都不能顺利移动而没有卡顿?

这是我的代码:

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

然后移动上方的摄氏度条会显示移动到摄氏度条下方的每个摄氏度,例如 0、1、2、3、4 等等(应该如此)。但是,如果我这样做,我当然会在移动华氏度条时失去摄氏度条上的任何功能,因为我不再通过移动华氏度 slider 设置任何值来控制摄氏度条。所以我要么只有上层的 JSlider 能够控制下层的 JSlider 并显示每个值的变化(比如 20、21、22 C),要么两个 JSlider 互相监听但只能以 0、5、10 的间隔,15 C等。

谁能告诉我,当两个 slider 相互监听时,为什么我无法获得每个单个数字变化的流畅反馈?为什么它只以 5 秒或 9 秒的步长变化?

最佳答案

正如您所发现的,您的问题是每个 ChangeListener 都在更改另一个 slider 的值。 slider C 更改 slider F 的值,这会更改 slider C 的值,这会更改 slider F 的值。这种相互递归仅在每次更改不会导致另一个 slider 的位置发生变化时结束,这发生在 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());
}
});

在您的 ThermoWindow 类中声明 private boolean updateInProgress = false;

关于java - 同步两个 JSlider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36555673/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com