Ho un'app Swing con un pannello grande che è avvolto in un JScrollPane
. Normalmente gli utenti si spostano tra i sottocomponenti del pannello tramite tabulazione, quindi quando si sfogliano per visualizzare qualcosa fuori, voglio che il riquadro di scorrimento scorri automaticamente in modo che il componente con lo stato attivo sia sempre visibile.Come faccio a far scorrere JScrollPane per seguire lo stato attivo di input?
Ho provato con KeyboardFocusManager
ad ascoltare per le modifiche di messa a fuoco di ingresso, e quindi chiamando scrollRectToVisible
.
Ecco un SSCCE visualizzazione mia strategia corrente (solo copia/incolla e correre!):
import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
public class FollowFocus {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final int ROWS = 100;
final JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content.add(new JLabel(
"Thanks for helping out. Use tab to move around."));
for (int i = 0; i < ROWS; i++) {
JTextField field = new JTextField("" + i);
field.setName("field#" + i);
content.add(field);
}
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addPropertyChangeListener("focusOwner",
new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!(evt.getNewValue() instanceof JComponent)) {
return;
}
JComponent focused = (JComponent) evt.getNewValue();
if (content.isAncestorOf(focused)) {
System.out.println("Scrolling to " + focused.getName());
focused.scrollRectToVisible(focused.getBounds());
}
}
});
JFrame window = new JFrame("Follow focus");
window.setContentPane(new JScrollPane(content));
window.setSize(200, 200);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
});
}
}
Se si esegue questo esempio, si noterà che non funziona molto bene. Ottiene le notifiche di cambio di messa a fuoco, ma la chiamata a scrollRectToVisible
non sembra avere alcun effetto. Nella mia app (che è troppo complessa da mostrare qui), scrollRectToVisible
funziona all'incirca alla metà del tempo in cui inserisco una scheda al di fuori del viewport.
Esiste un modo consolidato per risolvere questo problema? Se fa alcuna differenza, l'app Swing è costruita su Netbeans RCP (e la maggior parte dei nostri clienti esegue Windows).
Grazie per la spiegazione. –
Sì, grazie per la spiegazione. La tua proposta di correzione non funzionava nella mia app (anche se ha funzionato come un fascino nell'esempio sopra), ma dopo un po 'di sperimentazione ho trovato il seguente lavoro: '((JComponent) focused.getParent()). ScrollRectToVisible (focused.getBounds()) 'Ora, nessuno respira o l'inseguitore di messa a fuoco si rompe ...;) – gustafc