Agregar un MouseListener a un panel

Estoy intentando agregar las acciones del mouse a mi panel. Esto es lo que se supone que hace el progtwig:

Escriba un progtwig que permita al usuario especificar un triángulo con tres pulsaciones del ratón. Después de la primera pulsación del ratón, dibuja un pequeño punto. Después de la segunda pulsación del ratón, dibuje una línea que une los dos primeros puntos. Después de presionar el tercer ratón, dibuja todo el triángulo. La cuarta presión del mouse borra el triángulo anterior y comienza uno nuevo.

No veo ningún lugar donde se cree una instancia de la clase MouseListen. También necesitas llamar a addMouseListener ().

Aquí hay líneas de algo que escribí hace un tiempo que funcionó:

 public class ColorPanel extends JPanel implements MouseListener { . . . ColorPanel(JTextField jTextFieldColor) { super(); this.jTextField = jTextFieldColor; addMouseListener(this); } @Override public void mouseClicked(MouseEvent evt) { System.out.println("Instance of ColorPanel clicked."); jColorChooser = new JColorChooser(this.getBackground()); this.add(jColorChooser); int retval = JOptionPane.showConfirmDialog(null, jColorChooser, "JOptionPane Example : ", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (retval == JOptionPane.OK_OPTION) { jTextField.setText(Utils.hexStringFromColor(jColorChooser.getColor())); } } 

Consulte el tutorial en https://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html .

Además, basado en https://docs.oracle.com/javase/tutorial/uiswing/events/eventsandcomponents.html , puede hacer que JFrame implemente MouseListener, lo que haría su código aún más sencillo. (No necesitarías clase MouseListen en absoluto.)

Un grep rápido a través del código Java anterior que he escrito confirma que podrías

 public class MyFrame extends JFrame implements MouseListener 

por lo que es posible que desee examinar esto.

Le recomendaría encarecidamente que comience leyendo detenidamente Cómo escribir un dispositivo de escucha del ratón . Cuando te quedas atascado, estos tutoriales (y los JavaDocs) son el mejor lugar para comenzar

La respuesta “inmediata” a su pregunta es que necesita registrar una instancia de MouseListener con su componente, tal vez algo como …

 private JPanel createCenterPanel() { panel.addMouseListener(new MouseListen()); //panel.setLayout(null); return panel; } 

Esto “responderá” a su problema inmediato.

Sin embargo, le resultará difícil intentar unir las acciones de MouseListener con el panel, que necesita pintar los resultados.

Una mejor solución podría ser comenzar con un JPanel que administra su propio MouseListener

Además, Graphics g = panel.getGraphics() no es la forma en que debe realizarse la pintura personalizada. Echa un vistazo a Performing pintura personalizada para más detalles.

Entonces, en cambio, podría parecer algo más como …

 public class TrianglePanel extends JPanel { private List points = new ArrayList<>(3); public TrianglePanel() { addMouseListener(new MouseListen()); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); //To change body of generated methods, choose Tools | Templates. if (points.size() < 1) { return; } for (int index = 0; index < points.size(); index++) { Point nextPoint = points.get(index); g.fillOval(nextPoint.x - 2, nextPoint.y - 2, 4, 4); } Point startPoint = points.get(0); Point lastPoint = startPoint; for (int index = 1; index < points.size(); index++) { Point nextPoint = points.get(index); g.drawLine(lastPoint.x, lastPoint.y, nextPoint.x, nextPoint.y); lastPoint = nextPoint; } g.drawLine(lastPoint.x, lastPoint.y, startPoint.x, startPoint.y); } class MouseListen extends MouseAdapter { public void mouseReleased(MouseEvent e) { if (points.size() < 3) { points.add(e.getPoint()); repaint(); } } } } 

No estoy muy familiarizado con Swing. Como nuevo progtwigdor, solo he trabajado con JavaFX.

Sin embargo, no tiene ninguna referencia al MouseListener en ningún lugar de su progtwig. Probablemente te olvides de instanciarlo.

Debe registrar el objeto de escucha con Jpanel utilizando el método addMouseListener . Más información;

cam, dado lo que estás haciendo, me subí a mi “máquina de trabajo” y agarré este código. Dibuja un rectángulo en la parte superior de una imagen, y el rectángulo solo aparece después de que sueltes el mouse (es un trabajo en progreso, sin pagar, hecho en mi tiempo libre para cosas que a mi empleador le gustaría). Pero ya que estás mirando hacia adelante para dibujar, etc., aquí está.

Usa un JDialog porque quería que fuera modal; no dejes que eso te moleste

 import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.GroupLayout; import javax.swing.JDialog; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.WindowConstants; public class RectSelectGUI extends JDialog implements MouseListener, ActionListener, WindowListener { private static final long serialVersionUID = 1L; public int overheadWd; public int overheadHt; public ImageJPanel imagePanel; private JMenu jMenuSelection; private JMenuBar jMenuBar1; private Dimension mouseDownLoc; private String errorString; public RectSelectGUI(String imgFileName) { initComponents(imgFileName); } private void initComponents(String imgFileName) { imagePanel = new ImageJPanel(imgFileName); jMenuBar1 = new JMenuBar(); jMenuSelection = new JMenu(); JMenuItem jMenuItemSave = new JMenuItem(); jMenuItemSave.setActionCommand("Save"); jMenuItemSave.addActionListener(this); jMenuItemSave.setText("Save"); jMenuSelection.add(jMenuItemSave); JMenuItem jMenuItemCancel = new JMenuItem(); jMenuItemCancel.setActionCommand("Cancel"); jMenuItemCancel.addActionListener(this); jMenuItemCancel.setText("Cancel"); jMenuSelection.add(jMenuItemCancel); mouseDownLoc = new Dimension(); errorString = "No selection"; imagePanel.addMouseListener(this); this.setModal(true); this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); this.addWindowListener(this); GroupLayout jPanel1Layout = new GroupLayout(imagePanel); imagePanel.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 524, Short.MAX_VALUE)); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 370, Short.MAX_VALUE)); jMenuSelection.setText("Selection"); jMenuBar1.add(jMenuSelection); setJMenuBar(jMenuBar1); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addContainerGap() .addComponent(imagePanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap())); layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addContainerGap() .addComponent(imagePanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap())); pack(); overheadWd = this.getWidth() - imagePanel.getWidth(); overheadHt = this.getHeight() - imagePanel.getHeight(); } public String getSelectionString() { if (errorString.isEmpty()) { double rectWd = (double) imagePanel.rectWd; double rectHt = (double) imagePanel.rectHt; double rectX = (double) imagePanel.rectX; double rectY = (double) imagePanel.rectY; if (Math.abs(RectSelect.displayFactor - 1.0) > 0.001) { System.out.println("Adjusting by displayFactor (" + RectSelect.displayFactor + ")"); rectWd /= RectSelect.displayFactor; rectHt /= RectSelect.displayFactor; rectX /= RectSelect.displayFactor; rectY /= RectSelect.displayFactor; } return Math.round(rectWd) + "x" + Math.round(rectHt) + "+" + Math.round(rectX) + "+" + Math.round(rectY); } else { return "ERROR: " + errorString; } } @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent evt) { mouseDownLoc.setSize(evt.getX(), evt.getY()); } @Override public void mouseReleased(MouseEvent evt) { Dimension mouseUpLoc = new Dimension(evt.getX(), evt.getY()); if (mouseDownLoc.width < mouseUpLoc.width) { imagePanel.rectX = mouseDownLoc.width; imagePanel.rectWd = mouseUpLoc.width - mouseDownLoc.width; } else { imagePanel.rectX = mouseUpLoc.width; imagePanel.rectWd = mouseDownLoc.width - mouseUpLoc.width; } if (mouseDownLoc.height < mouseUpLoc.height) { imagePanel.rectY = mouseDownLoc.height; imagePanel.rectHt = mouseUpLoc.height - mouseDownLoc.height; } else { imagePanel.rectY = mouseUpLoc.height; imagePanel.rectHt = mouseDownLoc.height - mouseUpLoc.height; } imagePanel.haveNewRect = true; imagePanel.repaint(); errorString = ""; } @Override public void actionPerformed(ActionEvent evt) { String cmd = evt.getActionCommand(); switch (cmd) { case "Save": break; case "Cancel": errorString = "Cancelled"; break; default: System.out.println("Unknown action command " + cmd); } this.setVisible(false); } @Override public void windowClosing(WindowEvent e) { errorString = "Cancelled"; this.setVisible(false); } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent e) { // TODO Auto-generated method stub } @Override public void windowOpened(WindowEvent e) { try { Thread.sleep(100); } catch (InterruptedException e1) { } this.repaint(); } @Override public void windowClosed(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowIconified(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowDeiconified(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowActivated(WindowEvent e) { } @Override public void windowDeactivated(WindowEvent e) { // TODO Auto-generated method stub } } import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Toolkit; import javax.swing.JPanel; public class ImageJPanel extends JPanel { private static final long serialVersionUID = 1L; public Image localImage; private int origWd; private int origHt; private int displayWd; private int displayHt; public int rectX; public int rectY; public int rectWd; public int rectHt; public boolean haveNewRect; private Toolkit toolkit; ImageJPanel(String imageFileName) { toolkit = Toolkit.getDefaultToolkit(); localImage = toolkit.getImage(imageFileName); } protected void paintComponent(Graphics g1D) { Graphics2D g; g = (Graphics2D) g1D; // Draw the image using the Graphics object provided g.drawImage(localImage, 0, 0, getDisplayWd(), getDisplayHt(), null); /* * Optional label. Font font = new Font("SansSerif", Font.BOLD, 24); g1D.setFont(font); FontMetrics metrics = g1D.getFontMetrics(); int ht = metrics.getHeight(); int wd = metrics.stringWidth(this.imageFileName); g.setColor(Color.LIGHT_GRAY); g.fillRect(this.getWidth() - wd - 10, this.getHeight() - ht, wd + 10, ht); g1D.setColor(new Color(55, 11, 160)); g1D.drawString(this.imageFileName, this.getWidth() - wd - 10, this.getHeight() - ht + 20); */ // Draw a selection rectangle if requested. if (haveNewRect) { g.drawRect(rectX, rectY, rectWd, rectHt); haveNewRect = false; } } public int getDisplayWd() { return displayWd; } public void setDisplayWd(int displayWd) { this.displayWd = displayWd; } public int getDisplayHt() { return displayHt; } public void setDisplayHt(int displayHt) { this.displayHt = displayHt; } public int getOrigWd() { return origWd; } public void setOrigWd(int origWd) { this.origWd = origWd; } public int getOrigHt() { return origHt; } public void setOrigHt(int origHt) { this.origHt = origHt; } }