노브, 마침내이 문제를 해결 할 수있었습니다을 숨기기에 대한 해리 기쁨의 큰 도움으로 :
또한 여기 좀 봐.
해리의 답변을 확인하면 손잡이를 숨기는 방법 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 가지 모양과 느낌을 지원하며 그 중 하나는 Windows이며 Windows LAF에서는 작동하지 않습니다. 다른 말로, 나는 'BoundedRangeModel'이 최소값과 최대 값 사이의 값을 정정하고 그 동작과 연관시키기 때문에 알려지지 않은 값을 설정하는 방법을 여전히 갖고있다. –
Windows LAF에서 작동합니다. 설치를 잘못하고있었습니다. 어쨌든 두 번째 문제는 아직 풀리지 않습니다. –
@ YagoMéndezVidal 무엇이 완료되지 않았습니까? 손잡이 숨기고 있니? –