Salut,
je suis en train d'essayer une méthode pour simuler un Slider avec 2 thumbs. Voici le code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package swing;
 
import java.awt.event.MouseListener;
 
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.OverlayLayout;
import javax.swing.plaf.basic.BasicSliderUI;
 
public class JRangeSliderPanel extends JPanel {
 
 
	protected JSlider lowerSlider;
	protected JSlider upperSlider;
 
 
	public JRangeSliderPanel(int orientation, int min, int max, int lowerValue, int upperValue) {
		super();
		this.initcomponents(orientation, min, max, lowerValue, upperValue);
		this.initListeners();
	}
 
 
	protected void initcomponents(int orientation, int min, int max, int lowerValue, int upperValue) {
		// Layout
		OverlayLayout overlay = new OverlayLayout(this);
		this.setLayout(overlay);
 
		this.lowerSlider = new JSlider(orientation, min, max, lowerValue);
		this.upperSlider = new JSlider(orientation, min, max, upperValue);
 
		this.add(this.lowerSlider);
		this.add(this.upperSlider);
 
		this.lowerSlider.setOpaque(false);
		this.upperSlider.setOpaque(false);
 
	}
 
 
	private void initListeners() {
 
		// Lower
		MouseListener[] listeners = this.lowerSlider.getMouseListeners();
        for (int i = listeners.length - 1; i >= 0; i--) {
        	this.lowerSlider.removeMouseListener(listeners[i]);
		}
 
        BasicSliderUI.TrackListener trackListener = ((BasicSliderUI) this.lowerSlider.getUI()).new TrackListener() {
             @Override
             public boolean shouldScroll(int dir) {
         		setComponentZOrder(upperSlider, 0);
         		upperSlider.setPaintTrack(false);
         		lowerSlider.setPaintTrack(true);
                return false;
             }
         };
		this.lowerSlider.addMouseListener(trackListener);
 
		// Upper
		listeners = this.upperSlider.getMouseListeners();
        for (int i = listeners.length - 1; i >= 0; i--) {
        	this.upperSlider.removeMouseListener(listeners[i]);
		}
 
        trackListener = ((BasicSliderUI) this.upperSlider.getUI()).new TrackListener() {
             @Override
             public boolean shouldScroll(int dir) {
         		setComponentZOrder(lowerSlider, 0);            	 
         		lowerSlider.setPaintTrack(false);
         		upperSlider.setPaintTrack(true);
         		return false;
             }
         };
		this.upperSlider.addMouseListener(trackListener);
	}
 
 
 
	public void setUpperValue(int n)	{
		this.upperSlider.setValue(n);
	}
 
 
	public void setLowerValue(int n)	{
		this.lowerSlider.setValue(n);
	}
 
 
	public int getLowerValue()	{
		return this.lowerSlider.getValue();
	}
 
	public int getUpperValue()	{
		return this.upperSlider.getValue();
	}
 
	public void setMajorTickSpacing(int n)	{
		this.lowerSlider.setMajorTickSpacing(n);
		this.upperSlider.setMajorTickSpacing(n);
	}
 
	public void setPaintTicks(boolean b)	{
		this.lowerSlider.setPaintTicks(b);
		this.upperSlider.setPaintTicks(b);
	}
 
	public void setPaintLabels(boolean b)	{
		this.lowerSlider.setPaintLabels(b);
		this.upperSlider.setPaintLabels(b);
	}
 
	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
 
		JFrame frame = new JFrame();
 
		JRangeSliderPanel slider = new JRangeSliderPanel(JSlider.HORIZONTAL, 0, 500, 50, 320);
		slider.setMajorTickSpacing(100);
		slider.setPaintTicks(true);
		slider.setPaintLabels(true);
 
		frame.add(slider);
		frame.setSize(400, 400);
		frame.setVisible(true);
	}
}
L'idée est de tracer 2 JSlider l'un sur l'autre grâce au layout OverlayLayout.
Le problème est que seuls les événements du JSlider au premier plan sont pris en compte. D'où ma redéfinition du TackListener qui change le z index des composants si je clique ailleurs que sur le curseur.
Si je clique ailleurs que sur le curseur, "l'autre" JSlider passe au premier plan et je peux donc bouger le curseur. Le souci est qu'il faut que je clique 2 fois : une fois pour repasser le composant au premier plan et une autre fois pour que l'événement sur le nouveau composant soit pris en compte.
Il y a un petit test-case dans le main.

Est-ce que vous verriez une solution plus simple à ce problème ?

D'autre part, j'aimerais bloquer l'événement quand la valeur du lowerSlider dépasse celle de l'upperSlider et vice-versa, pour éviter les chevauchements mais je n'ai pas trouvé comment annuler l'événement. Auriez-vous une idée sur la question ?
Merci d'avance