Galera, tenho o seguinte problema. Possuo uma janela com 3 ScrollPane. Um principal no meio, outro do lado esquerdo e outro abaixo do principal. Gostaria de sincronizar os scrolls dos 3 ScrollPane. Exemplo: se eu mexer o scroll horizontal do ScrollPane Principal, o scroll horizontal do ScrollPane debaixo mexeria igualmente. Se eu mexesse o scroll vertical do ScrollPane Principal, o scroll vertical do ScrollPane da esquerda mexeria junto. Já tentei 42 tipos de eventos, mas nenhum é ativado quando eu mexo o scroll. Ou eu estou escrevendo errado ou não tem evento para isso. Como eu acho que é a primeira opção, peço a ajuda de vcs. Os testes estão sendo feitos assim:
spPrancheta.setOnScroll((ScrollEvent e)->{
System.out.println(“teste 42”);
spEnderecos.setVvalue(spPrancheta.getVvalue());
spDias.setHvalue(spPrancheta.getHvalue());
});
Há algum tempo eu também precisei sincronizar diferentes JScrollPane
numa mesma tela, na época eu criei uma classe chamada ScrollSynchronizer
com um método add(JScrollPane scroll)
que permitia que eu adicionasse cada JScrollPane
o qual deveria ter o seu movimento sincronizado com os outros.
Exemplo de como sincronizar 3 objetos JScrollPane
:
ScrollSynchronizer synchronizer = new ScrollSynchronizer();
synchronizer.add(meuObjetoJScrollPane1);
synchronizer.add(meuObjetoJScrollPane2);
synchronizer.add(meuObjetoJScrollPane3);
Código fonte da classe ScrollSynchronizer
:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.event.ChangeListener;
public final class ScrollSynchronizer {
private final List<JScrollPane> scrolls = new LinkedList<>();
private final Map<JScrollPane, ChangeListener> verticalListeners = new HashMap<>();
private final Map<JScrollPane, ChangeListener> horizontalListeners = new HashMap<>();
private boolean scrolling;
public ScrollSynchronizer() {}
public void add(JScrollPane scroll) {
ChangeListener verticalListener = event -> onScroll(scroll, true);
ChangeListener horizontalListener = event -> onScroll(scroll, false);
verticalListeners.put(scroll, verticalListener);
horizontalListeners.put(scroll, horizontalListener);
scroll.getVerticalScrollBar().getModel().addChangeListener(verticalListener);
scroll.getHorizontalScrollBar().getModel().addChangeListener(horizontalListener);
scrolls.add(scroll);
}
public void remove(JScrollPane scroll) {
ChangeListener verticalListener = verticalListeners.get(scroll);
ChangeListener horizontalListener = horizontalListeners.get(scroll);
scroll.getVerticalScrollBar().getModel().removeChangeListener(verticalListener);
scroll.getHorizontalScrollBar().getModel().removeChangeListener(horizontalListener);
scrolls.remove(scroll);
}
private void onScroll(JScrollPane source, boolean vertical) {
if (scrolling) {
return;
}
try {
scrolling = true;
JScrollBar scrollBar1 = vertical ? source.getVerticalScrollBar() : source.getHorizontalScrollBar();
for (JScrollPane destiny : scrolls) {
if (destiny != source) {
JScrollBar scrollBar2 = vertical ? destiny.getVerticalScrollBar() : destiny.getHorizontalScrollBar();
synchronizeScrollBars(scrollBar1, scrollBar2);
}
}
} finally {
scrolling = false;
}
}
private void synchronizeScrollBars(JScrollBar scroll1, JScrollBar scroll2) {
int min1 = scroll1.getMinimum();
int max1 = scroll1.getMaximum();
double delta1 = max1 - min1;
int min2 = scroll2.getMinimum();
int max2 = scroll2.getMaximum();
double delta2 = max2 - min2;
double value1 = scroll1.getValue();
double value2 = value1;
if (delta1 != delta2) {
value2 = value1 * delta2 / delta1;
}
scroll2.setValue((int) (min2 + value2));
}
}