2009-09-23 7 views
2

JSlider를 사용하여 응용 프로그램의 진행 상황을 표시하므로 특정 프로세스가 계산됨에 따라 업데이트됩니다.JSlider의 진행 표시기를 엄지 손가락에서 연결 해제하는 방법?

사용자가 과거에 엄지 손가락으로 뒤로 드래그 할 수있게하려는 경우이 경우 진행률 표시기를 현재 위치로 유지하고 싶습니다.

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

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

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

가장 좋은 방법에 대한 안내는 누구든지 제공 할 수 있습니까? 미리 도움을 청하십시오!

+0

당신은 코드 예제를 게시해야합니다. JSlider를 광범위하게 사용하고 슬라이더를 움직이는 것에 대한 응답으로 트랙 변경 크기를 본 적이 없습니다. WAG로서, 어떻게 든 그 값은 구성 요소의 크기로 다시 공급되고 있습니다. 그리고 당신이보고있는 것은 구성 요소를 변경하는 크기입니다. –

+0

아마 내가 잘못 말한 것입니다. 엄지 손가락이 구성 요소 아래로 움직일 때 진행률 표시기 (파란색 선이 커짐)를 정말로 원합니다. 그게 진짜로 뭐라구? – Cuga

+0

당신이 가진 것과 당신이 원하는 것의 차이점은 무엇입니까? 그들은 나에게 똑같이 보입니다. –

답변

1

나는 그것을 이해했다. JSlider를 확장하여 진행률을 추적한다. 현재 엄지 손가락 위치로부터 옮겨, MetalSliderUI의 paintTrack 메소드를 오버라이드 (override) 해, 원하는 위치에 트럭을 묘화합니다.

다음은 중요한 부분을 제거한 솔루션입니다.

새로운 진행률 표시 줄 :

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 : 참고 만 2 라인이 바로 그런 말을 주석에 이어 UI 클래스의 paintTrack() 메소드에 추가가 있었다.

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

글쎄 어떻게 이것이 가능한지 모르겠다. "트랙 값"과 "엄지 손가락 값"의 두 가지 모델 정보를 저장할 필요가 없으므로 슬라이더 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); 
    } 
} 

또한 Overlap Layout이 필요합니다. 어떻게 동기화 할 수 있을지는 당신에게 달린 것입니다. 이 솔루션에는 많은 결함이 있지만 몇 가지 아이디어를 줄 수 있습니다.

+0

나는 당신이 처음 이야기했던 것과 가까운 해결책을 제시했다. JSlider를 확장하여 진행 상황을 추적하고 MetalSliderUI를 재정 의하여 원하는 지점까지 트랙을 그렸다. 도와 주셔서 감사합니다. – Cuga

1

아, 무슨 뜻인지 알 겠어. 불행히도 그렇게 할 방법이 없습니다.

'파란색 막대'는 실제로 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); 
      } 
     }); 
    } 
} 
+0

메탈 LAF에 관해 당신이 말한 것을 봅니다. 내가 게시 한 솔루션마다 paintTrack() 메서드를 확장하기로 결정했습니다. 도와 주셔서 감사합니다. – Cuga

관련 문제