简体   繁体   English

将鼠标悬停在JSplitPane分频器上时更改光标

[英]Change cursor when hovering over JSplitPane divider

I need my cursor to change when i hover over the JSplitPane divider. 当我将鼠标悬停在JSplitPane分隔符上时,需要更改光标。 This is purely for improved usability. 这纯粹是为了提高可用性。 I discovered two methods to accomplish this. 我发现了两种方法可以完成此任务。 Code shown below 如下所示的代码

Method 01 方法01

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

Method 02 方法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 . 我的问题是,如果JSplitPane的顶部容器是JFrameJWindow ,那么这两种方法都能按预期工作。 To test, I wrote a small piece of code where the JSplitPane is added to a JPanel which is then added to a JFrame . 为了测试,我编写了一小段代码,其中将JSplitPane添加到JPanel ,然后将其添加到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. 但是我正在为intellij开发Tool Window插件,在那里, JSplitPane (包含在JPanel )被添加到ToolWindow容器中。 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 案例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 案例02:Intellij插件

note: This is an intellij plugin project, where a toolWindow extension is specified in a plugin.xml file. 注意:这是一个的IntelliJ插件项目,其中一个toolWindow扩展在plugin.xml文件中指定。 Basically the createToolWindowContent method is executed when the tool Window is opened in the IDE. 基本上,当在IDE中打开工具窗口时,将执行createToolWindowContent方法。 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 PanelWithSplitPane代码

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) 例如,通过使用MouseListener及其方法mouseEntered / mouseExited(通过将Cursor返回到默认值)

  • 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. 我更改了将JPanel添加到ToolWindow的代码,现在setCursor方法可以按预期工作。 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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