2015-12-30 1 views
0

J'ai besoin de mon curseur pour changer lorsque je passe la souris sur le diviseur JSplitPane. Ceci est purement pour une facilité d'utilisation améliorée. J'ai découvert deux méthodes pour accomplir ceci. Code ci-dessousChanger le curseur en survolant JSplitPane divider

Méthode 01

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

Méthode 02

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

Mon problème est, ces deux méthodes fonctionnent comme prévu si le récipient supérieur du JSplitPane est un JFrame ou un JWindow. Pour tester, j'ai écrit un petit morceau de code où le JSplitPane est ajouté à un JPanel qui est ensuite ajouté à un JFrame. Le curseur change comme prévu lorsque vous passez la souris sur le diviseur.

Mais je développe un plugin Tool Window pour IntelliJ et là, le JSplitPane (contenu dans un JPanel) est ajouté à un récipient ToolWindow. Dans ce cas, le curseur reste le même lorsque je survole le diviseur. Ci-dessous est un code de test que j'ai écrit pour simuler les scénarios ci-dessus.

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

} 

sortie: Fonctionne comme prévu. Le curseur change lorsque planait au-dessus du diviseur

enter image description here

Case 02: le plugin IntelliJ

note: Ceci est un projet de plugin IntelliJ, où une extension toolWindow est spécifiée dans un fichier plugin.xml. Fondamentalement, la méthode createToolWindowContent est exécutée lorsque l'outil Window est ouvert dans l'EDI. La vue et toute autre interaction de l'utilisateur sont traitées à partir d'ici.

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

sortie: Ne fonctionne pas comme prévu.Le curseur reste le même lorsque plané au-dessus du diviseur

enter image description here

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

}

Répondre

0

J'ai changé le code où j'ajoute le JPanel au ToolWindow, et maintenant la méthode setCursor fonctionne comme prévu. Les modifications sont indiquées ci-dessous.

ancienne variante:

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

nouvelle variante:

 PanelWithSplitPane viewer = new PanelWithSplitPane(); 
     final ContentFactory contentFactory = toolWindow.getContentManager().getFactory(); 
     final Content content = contentFactory.createContent(viewer, "", true); 
     toolWindow.getContentManager().addContent(content); 
4
  • par exemple, en utilisant MouseListener et ses méthodes mouseEntered/mouseExited (par renvoie le curseur à la valeur par défaut)

  • note que je ne suis pas en mesure de retirer le rectangle noir (artefact de peinture unwnanted créé lors de l'exécution, lorsque le diviseur est déplacé, vous pouvez voir que sur le côté gauche)

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

Merci pour votre réponse. Mais cela ne fonctionne pas non plus. Les deux méthodes 'mouseEntered' et' mouseExited' sont appelées correctement, mais la méthode 'setCursor' ne semble pas fonctionner lorsque le conteneur de niveau supérieur n'est pas un JFrame ou un JWindow. – fsociety

+0

aucune idée sur votre problème de Win7, pour une meilleure aide plus tôt post un SSCCE/MCVE, court, runnable, compilable, car en appelant Cursor.DEFAULT_CURSOR de mouseExited tous les curseurs sont (dans Win10, Java8) correctement peint (DEFAULT_CURSOR pour tous Rectangle dans ContentPane, et il change à E_RESIZE_CURSOR si je suis hover_over ses frontières), vraiment aucune idée de votre problème avec, parce que cette fonctionnalité fonctionne dans WINXP/Win7, Win8 et WIn10 tout à fait correctement – mKorbel

+0

Le code que vous publiez fonctionne très bien. Le problème est avec mon plugin fenêtre intellij outil. Pour une raison quelconque, la méthode 'setCursor' ne fonctionne pas lorsque j'ajoute le' JPanel' avec le 'JSplitPane' au conteneur' ToolWindow'. J'ai trouvé un moyen de le faire fonctionner. voir ma réponse – fsociety