tabla eventos evento ejemplo derecho java contextmenu jtree

eventos - mouse click java



Haga clic derecho en el menĂº contextual para Java JTree? (6)

Creo que estás haciendo las cosas mucho más difíciles de lo necesario.
JTree tiene varios métodos "add_foo_Listener" en él. Implementa uno de ellos (TreeSelectionListener se ve bien), y luego tienes el nodo seleccionado actualmente.
Implemente un MouseListener para que pueda detectar el evento de clic derecho (y agregarlo al JTree, ya que JTree es un Componente), y luego debe tener todo lo que necesita para publicar un menú contextual.
Mira este tutorial para más detalles.

Estoy tratando de implementar menús emergentes en Java JTree. He subclasificado DefaultTreeCellRenderer (para cambiar la apariencia del nodo) y DefaultTreeCellEditor (para crear Componentes para adjuntar detectores de eventos, ya que aparentemente los Componentes que DefaultTreeCellRenderer.getTreeCellRendererComponent () devuelven no pueden hacerlo). Realmente no quiero "editar" los nodos, solo puedo abrir un menú emergente cuando se hace clic derecho en un nodo, pero esta es la única forma en que puedo pensar hacerlo ahora mismo ...

A continuación está el código que tengo hasta ahora, solo intento descubrir cómo capturar MouseEvents. De alguna manera funciona, pero mal. ¿Cuál es una mejor manera de lograr lo que estoy tratando de hacer aquí?

private class My_TreeCellRenderer extends DefaultTreeCellRenderer { My_TreeCellRenderer() { super (); } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); // set label text and tool tips setText(((My_Object)value).getTreeLabel()); setToolTipText(((My_Object)value).getTreeToolTip()); return this; } } private class My_TreeCellEditor extends DefaultTreeCellEditor { private MouseAdapter ma; My_TreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) { super (tree, renderer); ma = new MouseAdapter() { public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) { System.out.println("My Popup"); } } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { System.out.println("My Popup"); } } }; } public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) { String src_filename = null; // return non-editing component Component c = renderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, true); // add mouse listener if it''s not listening already MouseListener mouseListeners[] = c.getMouseListeners(); int i; for (i=0; i < mouseListeners.length && mouseListeners[i] != ma; i++); if (i >= mouseListeners.length) c.addMouseListener(ma); return c; } protected boolean canEditImmediately(EventObject event) { if (event instanceof MouseEvent && ((MouseEvent)event).getClickCount() == 1) return true; else return false; } }


El Renderer es solo un "sello de goma" transitorio, por lo que agregar un oyente de entrada no será particularmente útil. El Editor, como usted señala, solo está allí una vez que ha hecho un gesto para editar. Por lo tanto, desea agregar un oyente al JTree (suponiendo que no esté implementado como un componente compuesto).


Gracias a todos. Sabía que algo andaba mal cuando estaba gastando tanto esfuerzo en implementar una ventana emergente simple.

Desestimé esta línea de pensamiento al principio porque me pareció extraño recurrir a las coordenadas xey para encontrar el nodo que busco, pero supongo que esta es la manera de hacerlo.

// add MouseListener to tree MouseAdapter ma = new MouseAdapter() { private void myPopupEvent(MouseEvent e) { int x = e.getX(); int y = e.getY(); JTree tree = (JTree)e.getSource(); TreePath path = tree.getPathForLocation(x, y); if (path == null) return; tree.setSelectionPath(path); My_Obj obj = (My_Obj)path.getLastPathComponent(); String label = "popup: " + obj.getTreeLabel(); JPopupMenu popup = new JPopupMenu(); popup.add(new JMenuItem(label)); popup.show(tree, x, y); } public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) myPopupEvent(e); } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) myPopupEvent(e); } }; (...) JTree tree = new JTree(); tree.addMouseListener(ma);


Tomado directamente de la API JTree

// If you are interested in detecting either double-click events or when a user clicks on a node, regardless of whether or not it was selected, we recommend you do the following: final JTree tree = ...; MouseListener ml = new MouseAdapter() { public void mousePressed(MouseEvent e) { int selRow = tree.getRowForLocation(e.getX(), e.getY()); TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); if(selRow != -1) { if(e.getClickCount() == 1) { mySingleClick(selRow, selPath); } else if(e.getClickCount() == 2) { myDoubleClick(selRow, selPath); } } } }; tree.addMouseListener(ml);

Por supuesto, debe modificarlo un poco para hacer clic con el botón derecho en lugar de hacer clic izquierdo


Esta tarea es simple de lograr, lo siguiente es todo lo que necesita:

//create a class which implements the MouseListener interface and //implement the following in your overridden mouseClicked method @Override public void mouseClicked(MouseEvent e) { if (SwingUtilities.isRightMouseButton(e)) { int row = tree.getClosestRowForLocation(e.getX(), e.getY()); tree.setSelectionRow(row); popupMenu.show(e.getComponent(), e.getX(), e.getY()); } }

A continuación, puede agregar este oyente personalizado a su (s) árbol (s) deseado (s).


Llame a addRightClickListener() para agregar el oyente del menú contextual al menú contextual de su JTree . Ambas anulaciones son para la funcionalidad multiplataforma apropiada ( Windows y Linux diferentes aquí).

private void addRightClickListener() { MouseListener mouseListener = new MouseAdapter() { @Override public void mousePressed(MouseEvent mouseEvent) { handleContextMenu(mouseEvent); } @Override public void mouseReleased(MouseEvent mouseEvent) { handleContextMenu(mouseEvent); } }; tree.addMouseListener(mouseListener); } private void handleContextMenu(MouseEvent mouseEvent) { if (mouseEvent.isPopupTrigger()) { MyContextMenu contextMenu = new MyContextMenu(); contextMenu.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); } }