[英]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
的顶部容器是JFrame
或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
. 为了测试,我编写了一小段代码,其中将
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.