"nichts einfacher als das" - dachte ... (вставить название: -)
По сути, все такие расширенные функциональные возможности должны быть реализованы в модели: для JSlider это BoundedRangeModel. Внедрить / расширить и применить его значение для соблюдения «комбинированного» макс. Что-то вроде
public static class LimitedBoundedRangeModel extends DefaultBoundedRangeModel {
BoundedRangeModel limit;
public LimitedBoundedRangeModel(BoundedRangeModel limit) {
this.limit = limit;
}
/**
* @inherited <p>
*/
@Override
public void setRangeProperties(int newValue, int newExtent, int newMin,
int newMax, boolean adjusting) {
if (limit != null) {
int combined = newValue + limit.getValue();
if (combined > newMax) {
newValue = newMax - limit.getValue();
}
}
super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
}
}
// use
LimitedBoundedRangeModel firstModel = new LimitedBoundedRangeModel(null);
LimitedBoundedRangeModel secondModel = new LimitedBoundedRangeModel(firstModel);
firstModel.limit= secondModel;
JSlider first = new JSlider(firstModel);
JSlider second = new JSlider(secondModel);
Хотя простой (только два иждивенца) и грубый (прямая двунаправленная связь) и, как таковой, на самом деле не может использоваться в дикой природе, он должен по крайней мере работать ... но не работает - один из тех сюрпризов, которые поразили меня со временем ко времени ;-) Визуальная проблема заключается в положении большого пальца:
- комбинированный максимум учитывается при нажатии справа от большого пальца: большой палец никогда не перемещается по порогу
- при перетаскивании, большой палец можно перемещать везде, чего и следовало ожидать, поскольку пользовательский интерфейс не знает о подстройке модели - он знает только «локальный» максимум
- на конце перетаскивания большой палец остается в этом недопустимом положении ... которое пахнет жуком, поскольку теперь большой палец не синхронизирован с моделью
Причиной этого неправильного поведения является то, что changeListener в Handler: он не пересчитывает свою позицию большого пальца при перетаскивании (что нормально). Тонкая ошибка в том, что внутренний флаг перетаскивания сбрасывается только после , а свойство настройки модели сбрасывается, поэтому отсутствует самое последнее уведомление о конечном значении ...
Обходной путь - вызвать срабатывание дополнительного changeEvent, если корректирующий флаг меняется с true на false
boolean invoke =
(adjusting != getValueIsAdjusting()) && !adjusting;
super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
if (invoke) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
fireStateChanged();
}
});
}