// -*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
// @homepage@

package example;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collections;
import javax.swing.*;
import javax.swing.plaf.LayerUI;

public final class MainPanel extends JPanel {
  private MainPanel() {
    super(new GridLayout(2, 1));

    String text = String.join("\n", Collections.nCopies(100, "aaaaa"));

    JTextArea textArea = new JTextArea("Mouse cursor flickers over the JScrollBar.\n" + text);
    textArea.addMouseListener(new MouseAdapter() {
      @Override public void mouseEntered(MouseEvent e) {
        JScrollPane sp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, (Component) e.getSource());
        sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
      }

      @Override public void mouseExited(MouseEvent e) {
        JScrollPane sp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, (Component) e.getSource());
        sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
      }
    });

    add(makeTitledPanel("MouseListener", makeScrollPane(textArea)));
    add(makeTitledPanel("JLayer", new JLayer<>(makeScrollPane(new JTextArea(text)), new ScrollBarOnHoverLayerUI())));
    setPreferredSize(new Dimension(320, 240));
  }

  private static JScrollPane makeScrollPane(JComponent c) {
    JScrollPane scroll = new JScrollPane(c);
    scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
    scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    return scroll;
  }

  private static Component makeTitledPanel(String title, Component c) {
    JPanel p = new JPanel(new BorderLayout());
    p.setBorder(BorderFactory.createTitledBorder(title));
    p.add(c);
    return p;
  }

  public static void main(String[] args) {
    EventQueue.invokeLater(MainPanel::createAndShowGui);
  }

  private static void createAndShowGui() {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
      ex.printStackTrace();
      Toolkit.getDefaultToolkit().beep();
    }
    JFrame frame = new JFrame("@title@");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MainPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}

class ScrollBarOnHoverLayerUI extends LayerUI<JScrollPane> {
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    if (c instanceof JLayer) {
      ((JLayer<?>) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
    }
  }

  @Override public void uninstallUI(JComponent c) {
    if (c instanceof JLayer) {
      ((JLayer<?>) c).setLayerEventMask(0);
    }
    super.uninstallUI(c);
  }

  @Override protected void processMouseEvent(MouseEvent e, JLayer<? extends JScrollPane> l) {
    int id = e.getID();
    if (id == MouseEvent.MOUSE_ENTERED) {
      l.getView().setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    } else if (id == MouseEvent.MOUSE_EXITED) {
      l.getView().setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
    }
    // super.processMouseEvent(e, l);
  }
}

@@ -368,25 +368,24 @@
 out(2, 1));%0A
-%0A
     String t
@@ -438,13 +438,13 @@
 0, %22
-aaaaa
+12345
 %22));
@@ -660,38 +660,21 @@
     
-JScrollPane sp = (JScrollPane)
+Container c =
  Swi
@@ -715,33 +715,37 @@
 rollPane.class, 
-(
+e.get
 Component) e.get
@@ -741,36 +741,80 @@
 nent
-) e.getSource());%0A        sp
+());%0A        if (c instanceof JScrollPane) %7B%0A          ((JScrollPane) c)
 .set
@@ -881,24 +881,34 @@
 AR_ALWAYS);%0A
+        %7D%0A
       %7D%0A%0A   
@@ -972,38 +972,21 @@
     
-JScrollPane sp = (JScrollPane)
+Container c =
  Swi
@@ -1035,17 +1035,21 @@
 .class, 
-(
+e.get
 Componen
@@ -1053,36 +1053,80 @@
 nent
-) e.getSource());%0A        sp
+());%0A        if (c instanceof JScrollPane) %7B%0A          ((JScrollPane) c)
 .set
@@ -1192,24 +1192,34 @@
 BAR_NEVER);%0A
+        %7D%0A
       %7D%0A    
@@ -1222,17 +1222,16 @@
     %7D);%0A
-%0A
     add(
@@ -1286,24 +1286,87 @@
 textArea)));
+%0A%0A    JScrollPane scroll = makeScrollPane(new JTextArea(text));
 %0A    add(mak
@@ -1405,43 +1405,14 @@
 r%3C%3E(
-makeScrollPane(new JTextArea(text))
+scroll
 , ne
@@ -1439,24 +1439,25 @@
 yerUI())));%0A
+%0A
     setPrefe

use 'MouseEvent#getComponent()' instead of '(Component) MouseEvent#getSource()'