繁体   English   中英

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

[英]Change cursor when hovering over JSplitPane divider

当我将鼠标悬停在JSplitPane分隔符上时,需要更改光标。 这纯粹是为了提高可用性。 我发现了两种方法可以完成此任务。 如下所示的代码

方法01

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

方法02

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

我的问题是,如果JSplitPane的顶部容器是JFrameJWindow ,那么这两种方法都能按预期工作。 为了测试,我编写了一小段代码,其中将JSplitPane添加到JPanel ,然后将其添加到JFrame 将鼠标悬停在分隔线上时,光标将按预期的方式更改。

但是我正在为intellij开发Tool Window插件,在那里, JSplitPane (包含在JPanel )被添加到ToolWindow容器中。 在这种情况下,当我将鼠标悬停在分隔线上时,光标将保持不变。

下面是我编写的用于模拟上述情况的一些测试代码。

案例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);
    }

}

输出:按预期工作。 光标悬停在分隔线上方时会发生变化

在此处输入图片说明

案例02:Intellij插件

注意:这是一个的IntelliJ插件项目,其中一个toolWindow扩展在plugin.xml文件中指定。 基本上,当在IDE中打开工具窗口时,将执行createToolWindowContent方法。 从此处处理视图和任何其他用户交互。

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);
}
}

输出:不能按预期工作。 将光标悬停在分隔线上方时,光标保持不变

在此处输入图片说明

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);
}

}

  • 例如,通过使用MouseListener及其方法mouseEntered / mouseExited(通过将Cursor返回到默认值)

  • 请注意,我无法删除黑色矩形(运行时创建的无用绘画伪像,当移动分隔线时,您可以在左侧看到它)

在此处输入图片说明

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;
    }
}

我更改了将JPanel添加到ToolWindow的代码,现在setCursor方法可以按预期工作。 更改如下所示。

旧版本:

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

新版本:

        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