Search code examples
javaswingfocusjscrollpanejscrollbar

Hide ScrollBar of the JScrollPane when user not touching JScrollpane


This application is for a touch panel. I just need the scrollbar of the JScrollPane visible only when the user touches the JScrollPane area.

I am new to GUI and swing. It will be helpful, what are things, I am failing to understand or please provide the links if this question has been asked in a different forum.

Edit 1

As there was no effect by the first suggestion by @gthanop I would like be more specific.

My jscrollPane holds a panel which populates the subpanels dynamically. So, the focus should be for this panel.

Edit 2

The edit1 answer of @gthanop worked, but it works only on panel (jscrollPane viewport's view). Scrollbar disables when I hover or click on sub panel, which is populated on the same panel.

So, how to set jscrollPane viewport's view to the jpanel and also its contents? (This may be different question though)


Solution

  • You can set whether each scrollbar is visible via the proper arguments in a method call of setHorizontalScrollBarPolicy and setVerticalScrollBarPolicy on the JScrollPane.

    You can do this inside a FocusListener (which is for focus events such as when the focus is gained and lost) which will be installed in the contents of the JScrollPane, or to be more precise, in the JScrollPane's Viewport's view component (which is what the JScrollPane is scrolling).

    Take for example the following code:

    import java.awt.Dimension;
    import java.awt.event.FocusEvent;
    import java.awt.event.FocusListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.ScrollPaneConstants;
    
    public class Main {
        private static void prepare(final JScrollPane scroll) {
            scroll.getViewport().getView().addFocusListener(new FocusListener() {
                @Override
                public void focusGained(final FocusEvent e) {
                    scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
                    scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
                }
    
                @Override
                public void focusLost(final FocusEvent e) {
                    scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                    scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
                }
            });
        }
    
        public static void main(final String[] args) {
            final JTextArea area = new JTextArea("Type your messages here...");
    
            final JScrollPane scroll = new JScrollPane(area);
            scroll.setPreferredSize(new Dimension(400, 100));
    
            prepare(scroll);
    
            final JPanel components = new JPanel();
            components.add(new JButton("Click me to change focus!"));
            components.add(scroll);
    
            final JFrame frame = new JFrame("Scroll auto focus.");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(components);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    

    When you click at the button of the frame that pops up, the focus will be lost from the view of the Viewport of the JScrollPane and the scrollbars will hide. After that, when you click back inside the JTextArea (which in this case is the JScrollPane's Viewport's view component) the focus will be regained in it, so you simply show the scrollbars with the appropriate method call.

    Edit 1

    As I understood from the comments of this answer, you need to show the scrollbars when the user hovers the mouse over the JScrollPane's Viewport's view. If so, in this case, you can add a MouseListener to the view like so:

    import java.awt.Dimension;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.ScrollPaneConstants;
    
    public class MainMouse {
        private static void prepare(final JScrollPane scroll) {
            scroll.getViewport().getView().addMouseListener(new MouseAdapter() {
                @Override
                public void mouseEntered(final MouseEvent e) {
                    scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
                    scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
                }
    
                @Override
                public void mouseExited(final MouseEvent e) {
                    scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                    scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
                }
            });
        }
    
        public static void main(final String[] args) {
            final JTextArea area = new JTextArea("Type your messages here...");
    
            final JScrollPane scroll = new JScrollPane(area);
            scroll.setPreferredSize(new Dimension(400, 100));
    
            prepare(scroll);
    
            final JPanel components = new JPanel();
            components.add(new JButton("Click me to change focus!"));
            components.add(scroll);
    
            final JFrame frame = new JFrame("Scroll auto focus.");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(components);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    

    Now when you hover over the JTextArea then the scrollbars will appear. When you hover outside the JTextArea then the scrollbars will disappear.