jslider의 진행 지표를 엄지 손가락에서 링크하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1468369

  •  13-09-2019
  •  | 
  •  

문제

JSLIDER를 사용하여 응용 프로그램의 진행 상황을 표시하여 특정 프로세스 계산으로 업데이트됩니다.

나는 사용자가 과거에 엄지 손가락을 체크 마크로 뒤로 끌 수 있기를 원하지만, 이런 일이 발생하면 진행률 표시기가 현재 위치에 남아 있기를 원합니다.

// A dismal attempt at drawing the situation
Progress: ---------
Thumb:            |

// User drags backwards.  What I have:
Progress: ---
Thumb:       |

// What I want instead:
Progress: ---------
Thumb:       |

누구든지 이것을 가장 잘 달성하는 방법에 대한 지침을 제공 할 수 있습니까? 모든 도움에 미리 감사드립니다!

도움이 되었습니까?

해결책 2

나는 그것을 알아. 나는 현재 엄지 손가락 위치와 별도로 진행을 추적하기 위해 JSLIDER를 확장 한 다음 MetalsLiderui의 PaintTrack 방법을 무리화하여 원하는 위치에 트랙을 채우도록합니다.

다음은 중요한 부분을 제거한 해결책입니다.

새로운 진행률 바 :

public class ProgressSlider extends JSlider {
    protected int progress;
    private static final String uiClassID = "ProgressSliderUI";

    public ProgressSlider() {
        progress = 0;
        putClientProperty("JSlider.isFilled", Boolean.TRUE);
        updateUI();
    }
    public void updateUI() {
        setUI(new ProgressSliderUI(this));
    }
    public String getUIClassID() {
        return uiClassID;
    }

    public int getProgress() {
        return this.progress;
    }

    public void setProgress(int value) {
        if (value < this.getMinimum()) {
            this.progress = this.getMinimum();
        }
        else if (value > this.getMaximum()) {
            this.progress = this.getMaximum();
        }
        else {
            this.progress = value;
        }
    }
}

새로운 UI : 참고, UI 클래스에는 PaintTrack () 메소드에 2 개의 줄만 추가되었으며, 그 의견에 따라 그와 같은 주석은 다음과 같습니다.

public class ProgressSliderUI extends MetalSliderUI {

    public ProgressSliderUI() {
        super();
    }

    public ProgressSliderUI(JSlider b) {
    }

    @Override
    public void paintTrack(Graphics g) {
        Color trackColor = !slider.isEnabled() ? MetalLookAndFeel
                .getControlShadow() : Color.blue;

        boolean leftToRight = true;

        g.translate(trackRect.x, trackRect.y);

        int trackLeft = 0;
        int trackTop = 0;
        int trackRight = 0;
        int trackBottom = 0;

        // Draw the track
        if (slider.getOrientation() == JSlider.HORIZONTAL) {
            trackBottom = (trackRect.height - 1) - getThumbOverhang();
            trackTop = trackBottom - (getTrackWidth() - 1);
            trackRight = trackRect.width - 1;
        }
        else {
            if (leftToRight) {
                trackLeft = (trackRect.width - getThumbOverhang())
                        - getTrackWidth();
                trackRight = (trackRect.width - getThumbOverhang()) - 1;
            }
            else {
                trackLeft = getThumbOverhang();
                trackRight = getThumbOverhang() + getTrackWidth() - 1;
            }
            trackBottom = trackRect.height - 1;
        }

        if (slider.isEnabled()) {
            g.setColor(MetalLookAndFeel.getControlDarkShadow());
            g.drawRect(trackLeft, trackTop, (trackRight - trackLeft) - 1, 
                                           (trackBottom - trackTop) - 1);

            g.setColor(MetalLookAndFeel.getControlHighlight());
            g.drawLine(trackLeft + 1, trackBottom, trackRight, trackBottom);
            g.drawLine(trackRight, trackTop + 1, trackRight, trackBottom);

            g.setColor(MetalLookAndFeel.getControlShadow());
            g.drawLine(trackLeft + 1, trackTop + 1, 
                                            trackRight - 2, trackTop + 1);
            g.drawLine(trackLeft + 1, trackTop + 1, trackLeft + 1, 
                                                          trackBottom - 2);
        }
        else {
            g.setColor(MetalLookAndFeel.getControlShadow());
            g.drawRect(trackLeft, trackTop, (trackRight - trackLeft) - 1, 
                                            (trackBottom - trackTop) - 1);
        }

        // Draw the fill
        if (filledSlider) {
            int middleOfThumb = 0;
            int fillTop = 0;
            int fillLeft = 0;
            int fillBottom = 0;
            int fillRight = 0;

            if (slider.getOrientation() == JSlider.HORIZONTAL) {
                middleOfThumb = thumbRect.x + (thumbRect.width / 2);
                middleOfThumb -= trackRect.x; // To compensate for the
                // g.translate()
                fillTop = !slider.isEnabled() ? trackTop : trackTop + 1;
                fillBottom = !slider.isEnabled() ? trackBottom - 1
                        : trackBottom - 2;

                if (!drawInverted()) {
                    fillLeft = !slider.isEnabled() ? trackLeft : trackLeft + 1;

                    // THIS IS THE CHANGE OF NOTE:
                    // Fills the progress with the value from the custom slider
                    fillRight = xPositionForValue(((ProgressSlider) slider)
                            .getProgress());
                    fillRight -= trackRect.x;
                }
                else {
                    fillLeft = middleOfThumb;
                    fillRight = !slider.isEnabled() ? trackRight - 1
                            : trackRight - 2;
                }
            }
            else {
                middleOfThumb = thumbRect.y + (thumbRect.height / 2);
                middleOfThumb -= trackRect.y; // To compensate for the
                // g.translate()
                fillLeft = !slider.isEnabled() ? trackLeft : trackLeft + 1;
                fillRight = !slider.isEnabled() ? trackRight - 1
                        : trackRight - 2;

                if (!drawInverted()) {
                    fillTop = middleOfThumb;
                    fillBottom = !slider.isEnabled() ? trackBottom - 1
                            : trackBottom - 2;
                }
                else {
                    fillTop = !slider.isEnabled() ? trackTop : trackTop + 1;
                    fillBottom = middleOfThumb;
                }
            }

            if (slider.isEnabled()) {
                g.setColor(slider.getBackground());
                g.drawLine(fillLeft, fillTop, fillRight, fillTop);
                g.drawLine(fillLeft, fillTop, fillLeft, fillBottom);

                g.setColor(trackColor);
                g.fillRect(fillLeft + 1, fillTop + 1, fillRight
                                - fillLeft, fillBottom - fillTop);
            }
            else {
                g.setColor(MetalLookAndFeel.getControlShadow());
                g.fillRect(fillLeft, fillTop, fillRight - fillLeft, 
                                      trackBottom - trackTop);
            }
        }

        g.translate(-trackRect.x, -trackRect.y);
    }

}

그리고 운전자가 테스트하기 위해 :

public class ProgressExample extends JFrame
{
    public ProgressExample()
    {
        super("Progress Example");

        ProgressSlider mSlider = new ProgressSlider();
        mSlider.setMinimum(0);
        mSlider.setMaximum(100);
        mSlider.setValue(20);
        mSlider.setProgress(50);

        getContentPane().setLayout(new FlowLayout());
        getContentPane().add(slider);
        getContentPane().add(mSlider);
    }
    public static void main(String args[])
    {
        ProgressExample f = new ProgressExample();
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
        f.setSize(300, 80);
        f.show();
    }
}

다른 팁

아, 무슨 말인지 봅니다. 불행히도 그렇게 할 방법이 없습니다.

'블루 바 "는 실제로 JSLIDER의 일부가 아니며 금속 LAF의 일부입니다. 금속 LAF가 구성 요소를 페인트하기 위해 선택한 방식입니다. 다른 LAF로 시도하면 전혀 막대를 얻지 못합니다.

원하는 것을 얻으려면 jprogressbar와 jslider를 결합해야합니다.

시작점이 있습니다. 올바르게 보이도록 조정해야합니다.

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.event.ChangeListener;

public class ProgressSlider extends javax.swing.JPanel
{
    private JProgressBar progressBar;
    private JSlider slider;
    public ProgressSlider() {
        this(0, 100);
    }
    public ProgressSlider(int min, int max) {
        setLayout(new GridBagLayout());

        GridBagConstraints gbc;
        gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        slider = new JSlider(min, max, min);
        progressBar = new JProgressBar(min, max);
        add(slider, gbc);
        add(progressBar, gbc);
    }
    public void setValue(int n) {
        boolean adjSlider = slider.getValue() == progressBar.getValue();
        progressBar.setValue(n);
        if (adjSlider)
            slider.setValue(n);
    }
    public int getValue() {
        return progressBar.getValue();
    }
    public int getSliderValue() {
        return slider.getValue();
    }
    public void syncSlider() {
        slider.setValue(progressBar.getValue());
    }
    public void addChangeListener(ChangeListener l) {
        slider.addChangeListener(l);
    }
    public void removeChangeListener(ChangeListener l) {
        slider.removeChangeListener(l);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame jf = new JFrame();
                jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                final ProgressSlider ps = new ProgressSlider();
                final JTextField tf = new JTextField(4);
                final JButton jb = new JButton(new AbstractAction("Set") {
                    public void actionPerformed(ActionEvent e) {
                        ps.setValue(Integer.parseInt(tf.getText()));
                    }});
                JPanel jp = new JPanel();
                jp.add(tf);
                jp.add(jb);
                jf.getContentPane().add(ps, BorderLayout.CENTER);
                jf.getContentPane().add(jp, BorderLayout.SOUTH);
                jf.pack();
                jf.setVisible(true);
            }
        });
    }
}

글쎄, 나는 이것이 어떻게 가능한지 알지 못한다. 슬라이더 UI를 사용자 정의하고 모델을 변경해야합니다. "트랙 값"과 "썸 값"이라는 두 가지 모델 정보를 저장할 필요가 없으므로 모델을 변경해야합니다.

큰 해킹을 원한다면 두 개의 슬라이더를 서로 위에 페인트합니다. 하단 슬라이더는 트랙 값을위한 것이고 상단은 썸 값에 대한 것입니다.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.metal.*;

public class SliderTest extends JFrame
{
    public SliderTest()
    {
        JSlider bottom = createSlider();
        bottom.setUI( new MySliderUI1() );

        JSlider top = createSlider();
        top.setUI( new MySliderUI2() );
        top.setOpaque(false);

        JPanel panel = new JPanel();
        panel.setLayout( new OverlapLayout() );
        panel.add( bottom );
        panel.add( top );

        getContentPane().add( panel );
    }

    private JSlider createSlider()
    {
        JSlider slider = new JSlider(2, 50);
        slider.createStandardLabels(10, 5);
        slider.setMajorTickSpacing(10);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        slider.setValue(20);

        return slider;
    }

    class MySliderUI1 extends MetalSliderUI
    {
        public void paintThumb(Graphics g) {}
    }

    class MySliderUI2 extends MetalSliderUI
    {
        public void paintTrack(Graphics g) {}
    }

    public static void main(String[] args)
    {
        JFrame frame = new SliderTest();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
     }
}

당신은 또한 필요합니다 레이아웃 중첩. 당신이 그것들을 동기화하는 방법은 당신에게 달려 있습니다. 솔루션에는 많은 결함이 있지만 아이디어를 줄 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top