同步两个JSliders

时间:2016-04-11 17:47:38

标签: java swing

我已经写了一个小程序作为初学者练习,只用两个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的步长改变?

2 个答案:

答案 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,而另一侧则类似。