2013-02-22 3 views
0

짧은 :
노브가없는 JSlider에 알 수없는 값을 설정할 수 있습니까? 긴JSlider에서 알 수없는 값을 설정할 수 있습니까?

: 나는 사용자가 슬라이더를 사용하여 몇 가지 매개 변수를 측정하는 데 필요한 자바 스윙에서 개발 한 데스크톱 클라이언트가있는 프로젝트에서 일하고 있어요
. 그것이 슬라이더이어야한다는 요구 사항입니다.
사용자가 슬라이더와 상호 작용할 때까지 값을 알 수 없으므로 손잡이가 없음을 의미합니다. 그것은 요구 사항이기도합니다.
JSlider을 사용할 때 노브는 항상 표시되며 경계 밖으로 값을 설정하거나 원시 유형 int을 사용하고 객체 Integer을 사용하지 않으므로 null로 설정할 방법이 없습니다.
null 값 또는 적어도 손잡이가없는 값을 설정하는 방법이 있습니까? 그렇게 할 수있는 확장 프로그램이 있습니까?

답변

1

노브, 마침내이 문제를 해결 할 수있었습니다을 숨기기에 대한 해리 기쁨의 큰 도움으로 :

또한 여기 좀 봐.

해리의 답변을 확인하면 손잡이를 숨기는 방법 BasicSliderUI.paintThumb(Graphics)을 재정의하는 방법을 읽을 수 있습니다. 그것은 & F는 신디사이저를 기반으로하지 (그리고 그 후광을 의미)가 조금 까다 롭습니다 설치 L & F.

에 사용자 정의를 통해 접근 방식은 다른 것,하지만 행할 수를 가장 L에 잘 작동하십시오 PropertyChangeListener을 가진 L & F의 변경을 확인하고 구성 요소에 적절한 UI 대리자를 설치하는 UIManager에서 마법을 만듭니다 (이 솔루션에서는 다른 사람이 복사 붙여 넣기 인 BasicSliderUI에 기반한 것을 보여주고 있습니다). 또한 처음 클릭 한 위치에 값을 설정하기 위해 약간 조정했습니다. 델리게이트가 노브를 그려야하는지 알 수 없으면 이라고하는 JSlider이라는 클라이언트 속성을 사용하기로 결정했습니다. 이는 boolean입니다. 이 방법을 사용하면 대리자는 확장 된 것일뿐만 아니라 JSlider에 설치할 수 있습니다.

이제 알 수없는 값을 관리하는 방법은 무엇입니까? 다른 새 속성 "selectedValue"을 추가하면 "value""ready"Integer 유형 모두에 바인딩됩니다. "ready"null 여부 및 viceversa에, 두 "value"을 그리고 "selectedValue""selectedValue"null에 설정하지 않는 한 준비되지 같은 값 (하나되는 int 다른 Integer)를 개최 경우에 따라 false 또는 true이다. 그것은 복잡하게 들릴지도 모르지만 그렇지 않습니다. 또한 [Esc]로 값을 지우고 구현 된 구성 요소에서 속성을 전파하기위한 약간의 조정이 있습니다.여기

코드입니다 :

BasicSliderUIExt

import java.awt.Graphics; 
import java.awt.event.MouseEvent; 
import javax.swing.JSlider; 
import javax.swing.SwingConstants; 
import javax.swing.plaf.basic.BasicSliderUI; 

public class BasicSliderUIExt extends BasicSliderUI { 

    public BasicSliderUIExt(JSlider slider) { 
     super(slider); 
    } 

    @Override 
    public void paintThumb(Graphics g) { 
     if (isReady(super.slider)) { 
      super.paintThumb(g); 
     } 
    } 

    @Override 
    protected TrackListener createTrackListener(final JSlider slider) { 
     return new TrackListener() { 
      @Override 
      public void mousePressed(MouseEvent event) { 
       if (isReady(slider)) { 
        super.mousePressed(event); 
       } else { 
        JSlider slider = (JSlider) event.getSource(); 
        switch (slider.getOrientation()) { 
        case SwingConstants.VERTICAL: 
         slider.setValue(valueForYPosition(event.getY())); 
         break; 
        case SwingConstants.HORIZONTAL: 
         slider.setValue(valueForXPosition(event.getX())); 
         break; 
        } 
        super.mousePressed(event); 
        super.mouseDragged(event); 
       } 
      } 

      @Override 
      public boolean shouldScroll(int direction) { 
       if (isReady(slider)) { 
        return super.shouldScroll(direction); 
       } 

       return false; 
      }}; 
    } 

    public static boolean isReady(JSlider slider) { 
     Object ready = slider.getClientProperty(JSliderExt.READY_PROPERTY); 
     return (ready == null) || (!(ready instanceof Boolean)) || (((Boolean) ready).booleanValue()); 
    } 

} 

JSliderExt

import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.lang.reflect.Constructor; 
import javax.swing.BoundedRangeModel; 
import javax.swing.JSlider; 
import javax.swing.LookAndFeel; 
import javax.swing.UIManager; 
import javax.swing.plaf.SliderUI; 

public class JSliderExt extends JSlider { 

    private static final long serialVersionUID = 1L; 

    public static final String EXTENT_PROPERTY = "extent"; 
    public static final String MAXIMUM_PROPERTY = "maximum"; 
    public static final String MINIMUM_PROPERTY = "minimum"; 
    public static final String READY_PROPERTY = "ready"; 
    public static final String SELECTED_VALUE_PROPERTY = "selectedValue"; 
    public static final String VALUE_PROPERTY = "value"; 

    public static final boolean READY_DEFAULT_VALUE = false; 

    protected SliderUI uix = new BasicSliderUIExt(this); 

    public JSliderExt(BoundedRangeModel model, boolean ready) { 
     super(model); 

     init(ready); 
    } 

    public JSliderExt(BoundedRangeModel model) { 
     super(model); 

     init(READY_DEFAULT_VALUE); 
    } 

    public JSliderExt(int orientation, int minimmum, int maximum, int value, boolean ready) { 
     super(orientation, minimmum, maximum, value); 

     init(ready); 
    } 

    public JSliderExt(int orientation, int minimmum, int maximum, int value) { 
     super(orientation, minimmum, maximum, value); 

     init(READY_DEFAULT_VALUE); 
    } 

    public JSliderExt(int minimmum, int maximum, int value, boolean ready) { 
     super(minimmum, maximum, value); 

     init(ready); 
    } 

    public JSliderExt(int minimmum, int maximum, int value) { 
     super(minimmum, maximum, value); 

     init(READY_DEFAULT_VALUE); 
    } 

    public JSliderExt(int minimmum, int maximum, boolean ready) { 
     super(minimmum, maximum); 

     init(ready); 
    } 

    public JSliderExt(int minimmum, int maximum) { 
     super(minimmum, maximum); 

     init(READY_DEFAULT_VALUE); 
    } 

    public JSliderExt(int orientation, boolean ready) { 
     super(orientation); 

     init(ready); 
    } 

    public JSliderExt(int orientation) { 
     super(orientation); 

     init(READY_DEFAULT_VALUE); 
    } 

    public JSliderExt(boolean ready) { 
     super(); 

     init(ready); 
    } 

    public JSliderExt() { 
     super(); 

     init(READY_DEFAULT_VALUE); 
    } 

    private void init(boolean ready) { 
     UIManager.addPropertyChangeListener(new PropertyChangeListener() { // Changes the UI delegate in L&F change 
      @Override 
      public void propertyChange(PropertyChangeEvent event) { 
       if ("lookAndFeel".equals(event.getPropertyName())) { 
        Object newValue = event.getNewValue(); 
        if ((newValue != null) && (newValue instanceof LookAndFeel)) { 
         LookAndFeel lookAndFeel = (LookAndFeel) newValue; 

         try { 
          if (lookAndFeel instanceof MetalLookAndFeel) { 
           JSliderExt.this.uix = new MetalSliderUIExt(); 
          } else if (lookAndFeel instanceof com.sun.java.swing.plaf.motif.MotifLookAndFeel) { 
           JSliderExt.this.uix = new MotifSliderUIExt(JSliderExt.this); 
          } else if (lookAndFeel instanceof com.sun.java.swing.plaf.windows.WindowsLookAndFeel) { 
           JSliderExt.this.uix = new WindowsSliderUIExt(JSliderExt.this); 
          } else { 
           throw new NullPointerException("Default Look & Feel not matched"); 
          } 
         } catch (Exception e) { 
          try { 
           Package sliderPackage = JSliderExt.this.getClass().getPackage(); 
           String lookAndFeelName = lookAndFeel.getName(); 
           if (lookAndFeelName.equals("CDE/Motif")) { 
            lookAndFeelName = "Motif"; 
           } else if (lookAndFeelName.equals("Windows Classic")) { 
            lookAndFeelName = "Windows"; 
           } else if (lookAndFeelName.startsWith("JGoodies")) { 
            lookAndFeelName = "Basic"; 
           } 

           Class<?> sliderUiType = Class.forName(sliderPackage.getName() + "." + lookAndFeelName 
             + "SliderUIExt"); 

           Constructor<?> constructor1 = null; 
           try { 
            constructor1 = sliderUiType.getConstructor(JSlider.class); 
           } catch (Exception e3) { // Nothing to do here 
           } 
           Constructor<?> constructor0 = null; 
           try { 
            constructor0 = sliderUiType.getConstructor(); 
           } catch (Exception e3) { // Nothing to do here 
           } 

           Object sliderUi = null; 
           if (constructor1 != null) { 
            sliderUi = constructor1.newInstance(JSliderExt.this); 
           } else if (constructor0 != null) { 
            sliderUi = constructor0.newInstance(); 
           } 

           if ((sliderUi != null) && (sliderUi instanceof SliderUI)) { 
            JSliderExt.this.setUI((SliderUI) sliderUi); 
           } 
          } catch (Exception e2) { 
           JSliderExt.this.uix = new BasicSliderUIExt(JSliderExt.this); 
          } 
         } 
        } else { 
         JSliderExt.this.uix = new BasicSliderUIExt(JSliderExt.this); 
        } 
        updateUI(); 
       } 
      }}); 

     addPropertyChangeListener(new PropertyChangeListener() { 
      @Override 
      public void propertyChange(PropertyChangeEvent event) { 
       String propertyName = event.getPropertyName(); 

       if (READY_PROPERTY.equals(propertyName)) { 
        Object newValue = event.getNewValue(); 

        if ((newValue == null) || (!(newValue instanceof Boolean)) || (((Boolean) newValue).booleanValue())) { 
         setSelectedValue(Integer.valueOf(getValue())); 
        } else { 
         setSelectedValue(null); 
        } 
       } else if (SELECTED_VALUE_PROPERTY.equals(propertyName)) { 
        Object newValue = event.getNewValue(); 
        System.out.println(newValue); 

        if ((newValue != null) && (newValue instanceof Integer)) { 
         int value = getValue(); 
         int newSelectedValue = ((Integer) newValue).intValue(); 

         if (value != newSelectedValue) { 
          setValue(newSelectedValue); 
         } 

         setReady(true); 
        } else { 
         setReady(false); 
        } 

        repaint(); 
       } else if (VALUE_PROPERTY.equals(propertyName)) { 
        setReady(true); 

        Object newValue = event.getNewValue(); 

        if ((newValue != null) && (newValue instanceof Integer)) { 
         setSelectedValue((Integer) newValue); 
        } 
       } 
      }}); 

     addKeyListener(new KeyAdapter() { // Enables escape key for clearing value 
      @Override 
      public void keyPressed(KeyEvent event) { 
       if (event.getKeyCode() == KeyEvent.VK_ESCAPE) { 
        JSliderExt.this.setReady(false); 
       } 
      }}); 

     setReady(ready); 
    } 

    @Override 
    public void setValue(int value) { 
     int oldValue = getValue(); 
     super.setValue(value); 
     firePropertyChange(VALUE_PROPERTY, Integer.valueOf(oldValue), Integer.valueOf(value)); 
    } 

    @Override 
    public void setExtent(int extent) { 
     int oldExtent = getExtent(); 
     super.setExtent(extent); 
     firePropertyChange(EXTENT_PROPERTY, Integer.valueOf(oldExtent), Integer.valueOf(extent)); 
    } 

    @Override 
    public void setMinimum(int minimum) { 
     int oldMinimum = getMinimum(); 
     super.setMinimum(minimum); 
     firePropertyChange(MINIMUM_PROPERTY, Integer.valueOf(oldMinimum), Integer.valueOf(minimum)); 
    } 

    @Override 
    public void setMaximum(int maximum) { 
     int oldMaximum = getMaximum(); 
     super.setMaximum(maximum); 
     firePropertyChange(MAXIMUM_PROPERTY, Integer.valueOf(oldMaximum), Integer.valueOf(maximum)); 
    } 

    public Integer getSelectedValue() { 
     return (Integer) getClientProperty(SELECTED_VALUE_PROPERTY); 
    } 

    public void setSelectedValue(Integer selectedValue) { 
     putClientProperty(SELECTED_VALUE_PROPERTY, selectedValue); 
    } 

    public boolean isReady() { 
     Object ready = getClientProperty(READY_PROPERTY); 
     return ((ready != null) && (ready instanceof Boolean)) ? ((Boolean) ready).booleanValue() 
       : READY_DEFAULT_VALUE; 
    } 

    public void setReady(boolean waiting) { 
     putClientProperty(READY_PROPERTY, Boolean.valueOf(waiting)); 
    } 

    @Override 
    public void updateUI() { 
     setUI(this.uix); 
     updateLabelUIs(); 
    } 

} 

이 코드를 사용하여,이 때문에 응용 프로그램에 따라 대의원을 선택에 약간의 변경이 필요할 수 있습니다를 Windows 시스템 용입니다. Synth/Nimbus는 다른 방식으로 작동해야하지만 사용자 정의 L & F 또는 OSX의 경우에도 적절한 대리인을 확장하여 청취자에게 추가해야합니다.

2

을 직접 구현하고 paintThumb(Graphics g)을 재정 의하여 필요한 작업을 수행하십시오. How to hide the knob of jSlider?

+0

글쎄 실제로 많은 도움이되지만 완전히 문제를 해결하지는 않습니다. 우리의 응용 프로그램은 2 가지 모양과 느낌을 지원하며 그 중 하나는 Windows이며 Windows LAF에서는 작동하지 않습니다. 다른 말로, 나는 'BoundedRangeModel'이 최소값과 최대 값 사이의 값을 정정하고 그 동작과 연관시키기 때문에 알려지지 않은 값을 설정하는 방법을 여전히 갖고있다. –

+0

Windows LAF에서 작동합니다. 설치를 잘못하고있었습니다. 어쨌든 두 번째 문제는 아직 풀리지 않습니다. –

+0

@ YagoMéndezVidal 무엇이 완료되지 않았습니까? 손잡이 숨기고 있니? –

관련 문제