Search code examples
javaswingfocusjtextareapropertychangelistener

How to prevent component focusability java swing


in my java swing application, i want to display an information text (JTextArea in the top of the screen) whenever i click on a field of the form. To do this i implemented the interface PropertyChangeListener as follow :

private final class FocusChangeHandler implements PropertyChangeListener {
    @Override
    public void propertyChange(final PropertyChangeEvent evt) {
        final String propertyName = evt.getPropertyName();
        if (!"permanentFocusOwner".equals(propertyName)) {
            return;
        }

        final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();

        final String focusHint = (focusOwner instanceof JComponent) ? ((String) ValidationComponentUtils.getInputHint((JComponent) focusOwner))
                : null;

        infoArea.setText(focusHint);
        infoAreaPane.setVisible(focusHint != null);
    }
}

my problem is that whenever the value of the infoArea changes it gains focus and the scrollbar return to the top.

I want to prevent this behavior, i want to update the value of the infoArea without putting focus on it.

I tried the method .setFocusable(false) but the scrollbar keep on returning to the top of the screen.

Please let me know if any further information is needed.

Thank you


Solution

  • I found a hack for this problem.

    private final class FocusChangeHandler implements PropertyChangeListener {
        @Override
        public void propertyChange(final PropertyChangeEvent evt) {
            final String propertyName = evt.getPropertyName();
            if (!"permanentFocusOwner".equals(propertyName)) {
                return;
            }
    
            final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
    
            final String focusHint = (focusOwner instanceof JComponent) ? ((String) ValidationComponentUtils.getInputHint((JComponent) focusOwner))
                    : null;
            final int scrollBarPosition = panelScrollPane.getVerticalScrollBar().getValue();
            infoAreaPane.setVisible(focusHint != null);
            infoArea.setText(infoHint);
            if(focusHint != null) {
                javax.swing.SwingUtilities.invokeLater(new Runnable() {
                       public void run() { 
                           panelScrollPane.getVerticalScrollBar().setValue(scrollBarPosition);
                       }
                    });
            }
        }
    }