简体   繁体   中英

Change cursor when hovering over JSplitPane divider

I need my cursor to change when i hover over the JSplitPane divider. This is purely for improved usability. I discovered two methods to accomplish this. Code shown below

Method 01

BasicSplitPaneUI basicSplitPaneUI = (BasicSplitPaneUI)splitPane.getUI();
BasicSplitPaneDivider divider = basicSplitPaneUI.getDivider();
divider.setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));

Method 02

Component divider = splitPane.getComponent(2);
divider.setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));

My problem is, both these methods work as expected if the top container of the JSplitPane is a JFrame or a JWindow . To test, I wrote a small piece of code where the JSplitPane is added to a JPanel which is then added to a JFrame . The cursor changes as expected when hovering over the divider.

But i'm developing a Tool Window plugin for intellij and there, the JSplitPane (contained within a JPanel ) is added to a ToolWindow container. In this case, the cursor remains the same when i hover over the divider.

Below is some test code I've written to simulate the above scenarios.

Case 01

public class Main {

public static void main(String args[]){

    JFrame f = new JFrame();
    f.setLayout(new BorderLayout());

    //PanelWithSplitPane extends JPanel. Builds the JSplitPane
    PanelWithSplitPane viewer = new PanelWithSplitPane();
    f.add(viewer, BorderLayout.CENTER);

    f.pack();
    f.setVisible(true);
    }

}

Output: Works as expected. The cursor changes when hovered above the divider

在此处输入图片说明

Case 02: Intellij plugin

note: This is an intellij plugin project, where a toolWindow extension is specified in a plugin.xml file. Basically the createToolWindowContent method is executed when the tool Window is opened in the IDE. The view and any further user interaction is handled from here.

public class TestPane implements ToolWindowFactory {

//this method gets called when the toolWindow is opened in the IDE
@Override
public void createToolWindowContent(Project project, ToolWindow toolWindow) {
   PanelWithSplitPane viewer = new PanelWithSplitPane();
   toolWindow.getComponent().add(panel);
}
}

output: Does not work as expected. The cursor remains the same when hovered above the divider

在此处输入图片说明

PanelWithSplitPane code

public class PanelWithSplitPane extends JPanel {

public PanelWithSplitPane() {
    this.setLayout(new BorderLayout());

    JSplitPane splitPane = new javax.swing.JSplitPane();
    splitPane.setBorder(null);
    splitPane.setDividerLocation(1300);
    splitPane.setDividerSize(6);
    splitPane.setContinuousLayout(true);
    splitPane.setOneTouchExpandable(true);

    BasicSplitPaneUI basicSplitPaneUI = (BasicSplitPaneUI)splitPane.getUI();
    BasicSplitPaneDivider divider = basicSplitPaneUI.getDivider();
    divider.setCursor(new Cursor(Cursor.HAND_CURSOR));

    this.add(splitPane);
}

}

  • for example, by using MouseListener and its methods mouseEntered/mouseExited (by returns Cursor back to the default)

  • note I'm not able to remove the black rectangle (unwnanted painting artefact created at runtime, when the divider is moved, you can see that at left side)

在此处输入图片说明

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;

public class JSplitPaneToy {

    private JSplitPane sp;

    public JSplitPaneToy() {
        sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, makePanel(), makePanel());
        /*SplitPaneUI ui = sp.getUI();
         if (ui instanceof BasicSplitPaneUI) {
         ((BasicSplitPaneUI) ui).getDivider().setBorder(null);
         }*/
        BasicSplitPaneUI l_ui = (BasicSplitPaneUI) sp.getUI();
        final BasicSplitPaneDivider l_divider = l_ui.getDivider();
        l_divider.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                Dimension l_pane_size = sp.getSize();
                if (sp.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
                    int l_new_loc = sp.getDividerLocation() + e.getX();
                    if (l_new_loc >= 0 && l_new_loc <= l_pane_size.width) {
                        sp.setDividerLocation(l_new_loc);
                    }
                } else {
                    int l_new_loc = sp.getDividerLocation() + e.getY();
                    if (l_new_loc >= 0 && l_new_loc <= l_pane_size.height) {
                        sp.setDividerLocation(l_new_loc);
                    }
                }
            }
        });
        l_divider.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                l_divider.setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                l_divider.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
            }
        });
        sp.setBorder(BorderFactory.createEmptyBorder());
        /*sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
         ui = sp.getUI();
         if (ui instanceof BasicSplitPaneUI) {
         ((BasicSplitPaneUI) ui).getDivider().setBorder(null);
         }
         sp.setBorder(BorderFactory.createEmptyBorder());
         sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
         ui = sp.getUI();
         if (ui instanceof BasicSplitPaneUI) {
         ((BasicSplitPaneUI) ui).getDivider().setBorder(null);
         }
         sp.setBorder(BorderFactory.createEmptyBorder());
         sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
         ui = sp.getUI();
         if (ui instanceof BasicSplitPaneUI) {
         ((BasicSplitPaneUI) ui).getDivider().setBorder(null);
         }
         sp.setBorder(BorderFactory.createEmptyBorder());*/
        JFrame frame = new JFrame("JSplitPane Toy");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(sp);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        /*try {
         for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
         if ("Nimbus".equals(info.getName())) {
         javax.swing.UIManager.setLookAndFeel(info.getClassName());
         break;
         }
         }
         } catch (ClassNotFoundException ex) {
         } catch (InstantiationException ex) {
         } catch (IllegalAccessException ex) {
         } catch (javax.swing.UnsupportedLookAndFeelException ex) {
         }*/
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JSplitPaneToy jSplitPaneToy = new JSplitPaneToy();
            }
        });
    }

    private JScrollPane makePanel() {
        JScrollPane pane = new JScrollPane(new JTable(
                new Object[][]{{0, 1, 2}, {1, 2, 3}, {2, 3, 4}}, new Object[]{1, 2, 3}) {
                    private static final long serialVersionUID = 1L;
                });
        pane.setPreferredSize(new Dimension(200, 100));
        return pane;
    }
}

I changed the code where I add the JPanel to the ToolWindow , and now the setCursor method works as expected. Changes are shown below.

Old variant:

    PanelWithSplitPane viewer = new PanelWithSplitPane();
    toolWindow.getComponent().add(panel);

New Variant:

        PanelWithSplitPane viewer = new PanelWithSplitPane();
        final ContentFactory contentFactory = toolWindow.getContentManager().getFactory();
        final Content content = contentFactory.createContent(viewer, "", true);
        toolWindow.getContentManager().addContent(content);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM