JScrollPane track the component that is focused

0

I have a screen with JSrollPane and several JTextFields . When changing textfield using the tab key, JScrollPane does not match if the textfield that receives the focus is "down the screen."

I wanted it when I shifted the focus to a textfield that was not appearing, the JScrollPane followed and went down or up depending on which textfield I changed the focus.

Code to generate the screen, it is a very simple screen with only the same textfield:

package newpackage;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class GridLayoutButtonsTest extends JFrame {

    private JPanel contentPane;
    private int qtButton = 0;

    public static void main(String[] args) {
        GridLayoutButtonsTest frame = new GridLayoutButtonsTest();
        frame.setVisible(true);
    }

    public GridLayoutButtonsTest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(500, 200));
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);

        JScrollPane scroll = new JScrollPane();
        scroll.setPreferredSize(new Dimension(464, 139));

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(0, 1, 10, 10));

        for (int i = 0; i < 15; i++) {
            panel.add(gerarField());
        }
        scroll.setViewportView(panel);
        contentPane.add(scroll);

        pack();
    }

    public JTextField gerarField() {
        qtButton++;
        JTextField NewField = new JTextField(String.valueOf(qtButton));
        return NewField;
    }
}
    
asked by anonymous 12.12.2018 / 13:48

1 answer

1

As removed from this question in SOEn , you can register a PropertyChangeListener . "focusOwner" is the name of a property within the KeyboardFocusManager class where the owner of the current focus is registered.

This code snippet will be triggered whenever a component in the active window gains focus, and if this new component to receive focus (fieldFocus) is a JTextComponent and belongs to the panel containing the text fields, it will move the area visible from the scroll to it through the scrollRectToVsisible() , along with focus.

KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("focusOwner",
                new PropertyChangeListener() {

                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if (!(evt.getNewValue() instanceof JTextComponent)) {
                            return;
                        }
                        JTextComponent campoFocado = (JTextComponent) evt.getNewValue();
                        if (scroll.isAncestorOf(campoFocado)) {
                            panel.scrollRectToVisible(campoFocado.getBounds());
                        }
                    }
                });

See working:

    
12.12.2018 / 14:33