2011-01-08 5 views
16

C'è un modo per aggiungere un MouseListener a un oggetto grafico.
Ho questa semplice interfaccia grafica che disegna un ovale.
quello che voglio è la gestione dell'evento, quando l'utente fa clic sull'ovaleC'è un modo per aggiungere un MouseListener a un oggetto grafico?

import java.awt.*; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import javax.swing.*; 

public class Gui2 extends JFrame { 
JFrame frame = new JFrame(); 
MyDrawPanel drawpanel = new MyDrawPanel(); 

public static void main(String[] args) { 
    Gui2 gui = new Gui2(); 
    gui.go(); 
} 

public void go() { 

    frame.getContentPane().add(drawpanel); 
    // frame.addMouseListener(this); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(300, 300); 
    frame.setVisible(true); 

} 

} 

class MyDrawPanel extends JComponent implements MouseListener { 

public void paintComponent(Graphics g) { 

    int red = (int) (Math.random() * 255); 
    int green = (int) (Math.random() * 255); 
    int blue = (int) (Math.random() * 255); 
    Color startrandomColor = new Color(red, green, blue); 

    red = (int) (Math.random() * 255); 
    green = (int) (Math.random() * 255); 
    blue = (int) (Math.random() * 255); 
    Color endrandomColor = new Color(red, green, blue); 

    Graphics2D g2d = (Graphics2D) g; 
    this.addMouseListener(this); 
    GradientPaint gradient = new GradientPaint(70, 70, startrandomColor, 
    150, 150, endrandomColor); 

    g2d.setPaint(gradient); 
    g2d.fillOval(70, 70, 100, 100); 

} 

@Override 
public void mouseClicked(MouseEvent e) { 
    if ((e.getButton() == 1) 
    && (e.getX() >= 70 && e.getX() <= 170 && e.getY() >= 70 && e 
     .getY() <= 170)) { 
    this.repaint(); 
    // JOptionPane.showMessageDialog(null,e.getX()+ "\n" + e.getY()); 
    } 

} 

@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 mousePressed(MouseEvent e) { 
    // TODO Auto-generated method stub 

} 

@Override 
public void mouseReleased(MouseEvent e) { 
    // TODO Auto-generated method stub 

} 

} 

Questo funziona Solo che spara quando il click è all'interno di un box virtuale intorno all'ovale.
Qualcuno potrebbe aiutarmi a farlo sparare quando il clic è ESATTAMENTE sull'ovale.
Grazie in anticipo.

risposta

19

Il modo più semplice a cui posso pensare è di evitare fillOval e utilizzare la geometria nel pacchetto java.awt.geom. Quindi puoi dichiarare un'ellisse poiché sembra che l'ovale che stai disegnando abbia dimensioni statiche.

class MyDrawPanel extends JComponent implements MouseListener { 
     Ellipse2D oval = new Ellipse2D.Double(70, 70, 100, 100); 

     .... 

} 

Quindi in paintComponent si utilizza il metodo di riempimento (Forma) per disegnare questo.

public void paintComponent(Graphics g) { 
     .... 
     Graphics2D g2d = (Graphics2D) g; 
     .... 
     g2d.fill(oval); 

    } 

Poi, nel caso del mouse è possibile rilevare se il clic è in ovale o non in questo modo:

public void mouseClicked(MouseEvent e) { 
    if ((e.getButton() == 1) && oval.contains(e.getX(), e.getY())) { 
     repaint(); 
    // JOptionPane.showMessageDialog(null,e.getX()+ "\n" + e.getY()); 
    } 
} 
+0

+1: Wow, non ho mai saputo che si potesse fare in un modo così semplice! Dannazione, quante ore ho perso. – Rekin

+0

@Rekin Questo è lo scopo del pacchetto geom. Per incapsulare tutte le operazioni geometriche sulla grafica 2D. –

+0

Questo è esattamente quello che voglio. Grazie, Vincent –

4

Tutto il codice dovrebbe essere contenuta nella classe componente personalizzato. Hai il codice personalizzato per dipingere l'ovale. Ora hai bisogno di un codice personalizzato per il rilevamento dei clic. Lo fai sovrascrivendo il metodo contains (...). Sulla base di suggerimento Vincents si dovrebbe aggiungere qualcosa come:

public boolean contains(int x, int y) 
{ 
    return oval.contains(x, y); 
} 

In questo modo non è necessario alcun codice personalizzato nel MouseListener.

0

No, non è possibile aggiungere direttamente il listener del mouse a Graphics perché non è un componente. L'ascoltatore del mouse dovrebbe essere aggiunto al tuo Component (o JComponent) che riceve l'oggetto Graphics adatto passato quando Swing invoca paint(Graphics) e gli amici.

Se qualcosa cambia in risposta alle azioni del mouse, è necessario modificare lo stato (campi) del componente e quindi richiamare repaint. I metodi del gruppo di colori verranno richiamati in un momento successivo.

Ancora di più non puoi mettere un ascoltatore sulla figura geometrica come l'ovale. È necessario ottenere le coordinate del clic del mouse e cercare di determinare l'uno o l'altro modo se il clic è stato all'interno della figura.

Problemi correlati