2015-12-30 195 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

相關問題