2015-12-30 3 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 является JFrame или JWindow. Чтобы проверить, я написал небольшой фрагмент кода, где JSplitPane добавлен к JPanel, который затем добавляется к JFrame. Курсор изменяется, как ожидается, при зависании над разделителем.

Но я занимаюсь разработкой Tool Window плагин для IntelliJ и там, JSplitPane (содержится в JPanel) добавляют к ToolWindow контейнера. В этом случае курсор остается тем же, когда я навешиваю над разделителем.

Ниже приведен некоторый тестовый код, который я написал для имитации вышеуказанных сценариев.

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

} 

Выход: Работает, как ожидалось. Курсор меняется, когда завис над разделителем

enter image description here

Case 02: Intellij плагин

Примечание: Это проект IntelliJ плагин, где расширение toolWindow задается в файле plugin.xml. В основном метод createToolWindowContent выполняется, когда окно инструмента открывается в среде IDE. Отсюда и просмотр и любое последующее взаимодействие с пользователем.

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» вызываются правильно, но метод 'setCursor', похоже, не работает, когда контейнер верхнего уровня не является JFrame или JWindow. – fsociety

+0

не знаю о вашей проблеме из Win7, для лучшей помощи скорее опубликуйте SSCCE/MCVE, короткий, исполняемый, скомпилируемый, потому что, вызывая Cursor.DEFAULT_CURSOR из mouseExited, все курсоры (в Win10, Java8) правильно окрашены (DEFAULT_CURSOR для всех Rectangle in ContentPane, и он изменяется на E_RESIZE_CURSOR, если я нахожусь на его границах), на самом деле не знаю о вашей проблеме, потому что эта функциональность работает в WInXP/Win7, Win8 и WIn10 совершенно правильно – mKorbel

+0

Код, который вы публикуете, отлично работает. Проблема заключается в моем плагине окна intellij. По какой-то причине метод 'setCursor' не работает, когда я добавляю' JPanel' с 'JSplitPane' в контейнер' ToolWindow'. Я понял, как заставить его работать. см. мой ответ – fsociety