我已经写了一个小程序作为初学者练习,只用两个JSliders将Celcius转换为Fahrenheit,反之亦然。我让两个JSliders互相监听,目标是每当我移动一个滑块时,无论是Celcius滑块(窗口中的上部滑块)还是华氏滑块(下部),另一个滑块应自动移动到正确的位置但是,程序有一个我无法理解的错误。当我运行它,它可以工作,但我的Celcius学位JLabel在Celcius酒吧" 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()));
然后移动上方的Celcius条显示每个Celcius度数在celcius条下移动,如0,1,2,3,4等等(就像它应该的那样)。但是如果我这样做的话,当我移动华氏温度条时,我在Celcius条上失去了任何功能,因为我不再用移动华氏温度滑块设置的任何值来控制Celcius条。所以我坚持只有上层JSlider能够控制较低的一个并显示每个值的变化(如20,21,22 C)或两个JSliders互相监听但只是间隔0,5,10 ,15 C等等。
有人能告诉我为什么当两个滑块互相收听时,我无法获得每个数字变化的平滑反馈吗?为什么它只是以5s或9s的步长改变?
答案 0 :(得分:3)
您的问题正如您所发现的那样,每个IMsgSetRequest requestMsgSet = qbSessionManager.CreateMsgSetRequest("UK", 13, 0);
ISalesReceiptQuery salesReceiptQuery = requestMsgSet.AppendSalesReceiptQueryRq();
salesReceiptQuery.metaData.SetValue(ENmetaData.mdNoMetaData);
salesReceiptQuery.IncludeRetElementList.Add("Memo");
IMsgSetResponse responseMsgSet = qbSessionManager.DoRequests(requestMsgSet);
IResponse response = responseMsgSet.ResponseList.GetAt(0);
ISalesReceiptRetList salesReceiptRetList = (ISalesReceiptRetList)response.Detail;
for (int i = 0; i < salesReceiptRetList.Count; i++)
{
if (salesReceiptRetList.GetAt(i).Memo != null)
{
string memo = salesReceiptRetList.GetAt(i).Memo.GetValue();
if (memo != string.Empty)
{
ExistingOrderIds.Add(memo);
}
}
}
都会更改另一个滑块的值。滑块C更改滑块F的值,这会更改滑块C的值,从而更改滑块F的值。这种相互递归仅在每次更改不会导致其他滑块位置发生变化时结束,该位置发生在5(在C中)和9(在F中)。
您需要以下代码:
ChangeListener
在 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());
}
});
课程中声明private boolean updateInProgress = false;
。
答案 1 :(得分:0)
问题在于,每次在一个值中设置其他更改的值时,这也会触发其回调。由于您将值四舍五入,从0开始直到将摄氏度光标移动到5,华氏温度值将保持为32,而另一侧则类似。