2015-12-30 107 views
0

当我将鼠标悬停在JSplitPane分隔线上时,需要更改光标。这完全是为了提高可用性。我发现了两种方法来实现这一点。代码如下所示将鼠标悬停在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。当鼠标悬停在分隔符上时,光标会按预期更改。

但我正在开发一个Tool Window插件的IntelliJ和那里,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); 
    } 

} 

输出:按预期工作。的IntelliJ插件

注:分频器

enter image description here

案例02上方盘旋当光标变为这是一个的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); 
} 
} 

输出:无法正常工作。分隔器上方盘旋当光标保持不变

enter image description here

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

}

回答

0

我更改了代码,将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); 
4
  • 例如,通过使用的MouseListener及其方法的mouseEntered /的mouseExited(由将光标恢复为默认值)

  • 注意到我无法取出黑色矩形(在运行时,当分配器移动创建unwnanted画假象,你可以看到在左侧)

enter image description here

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

谢谢您的答复。但是这也行不通。正确调用'mouseEntered'和'mouseExited'方法,但当顶层容器不是JFrame或JWindow时,'setCursor'方法似乎不起作用。 – fsociety

+0

不知道你从Win7发布的问题,为了更好的帮助,尽快发布一个SSCCE/MCVE,因为通过从mouseExited调用Cursor.DEFAULT_CURSOR所有游标(在Win10中,Java8)正确绘制(DEFAULT_CURSOR对于所有Rectangle in ContentPane,如果我是hover_over它的边界,它会更改为E_RESIZE_CURSOR),但对于您的问题真的不知道,因为这种funcionality在WInXP/Win7,Win8和WIn10中工作得相当正确 – mKorbel

+0

您发布的代码正常工作。问题出在我的intellij工具窗口插件上。出于某种原因,当我将具有'JSplitPane'的'JPanel'添加到'ToolWindow'容器时'setCursor'方法不起作用。我想出了一个让它工作的方法。看到我的答案 – fsociety

相关问题