2013-08-08 12 views
6

Ho una cornice con un'immagine che la copre, e voglio che ogni volta che qualcuno fa clic su un oggetto diverso nell'immagine, agirà come un pulsante e farà qualcosa.
Il problema è, è che quegli oggetti non sono semplici forme, quindi stavo pensando di disegnare i miei pulsanti invisibili nella forma di quegli oggetti.Come posso creare una forma di pulsante complessa?

È possibile? o quale sarebbe un modo migliore per realizzare una cosa del genere?

-Grazie

+1

Seguirà questo. Ho provato qualcosa di molto simile su Android un po 'indietro e ho finito per accontentarsi di soli pulsanti invisibili sopra le forme dispari :) – sealz

+0

funzionerà come un pulsante e fare qualcosa. è ad esempio qualcosa come telecomando virtuale per la TV – mKorbel

+1

Vedi anche l'approccio mostrato [qui] (http://stackoverflow.com/q/10861852/230513). – trashgod

risposta

2

Riesci a monitorare la posizione degli utenti del mouse tramite coordinate?

PointerInfo a = MouseInfo.getPointerInfo(); 
     Point b = a.getLocation(); 
     int x = (int)b.getX(); 
     int y = (int)b.getY(); 

Ora inserire un metodo ActionPerformed e verificare se xey = es. 200, 300 fare questo. In questo modo quando un utente fa clic su un punto (il tuo obiettivo per l'area) lo reindirizzerà a un metodo.

3

definire un'interfaccia per una regione come:

//represents any clickable area. 
public interface IButton{ 
    boolean contains(int x, int y); 
} 

Quindi, se si desidera una zona circolare sia cliccabile, definire una classe che controlla se x, y coordinate è entro una certa distanza di posizione.

public class CircleButton implements IButton{ 
    Point center; 
    double radius; 
    public CircleButton(int x, int y, double radius){ 
     this.center = new Point(x,y); 
     this.radius = radius; 
    } 
    //check if x,y coords are within a radius 
    //from the center of this circle button 
    public boolean contains(int x, int y){ 
     double dx = x-center.x; 
     double dy = y-center.y; 
     return (Math.sqrt(dx*dx+dy*dy) <= radius); 
    } 
} 

Creare un elenco di IButtons. Verrai ripetuto su questi per vedere se un utente ha fatto clic su uno dei tuoi pulsanti invisibili.

List<IButton> buttons = new List<IButton>(); 
buttons.add(new CircleButton(100,100,200); 

Quindi ogni volta che qualcuno fa clic sul fotogramma itera sui pulsanti invisibili utilizzando la posizione del clic del mouse.

public void mouseReleased(MouseEvent e){ 
    for(IButton b : buttons){ 
     if(b.contains(evt.getX(),e.getY()){ 
      //do something depending on what button was clicked. 
     } 
    } 
} 

Si può facilmente vedere come si potrebbe definire rettangolo pulsanti invisibili come questo, o anche forme poligonali irregolari. Dovresti solo implementare correttamente il metodo contains.

2

E voglio che ogni volta che alcuni clic su un oggetto diverso nell'immagine, agirà come un pulsante e fare qualcosa.

È possibile creare una lista di elementi di Shape. Quindi aggiungi un MouseListener al componente che contiene l'immagine. Ogni volta che viene generato un evento mousePressed, si esegue un ciclo attraverso ArrayList e si utilizza il metodo containts (...) del componente per determinare se l'utente fa clic su un oggetto si corregge.

Check out Playing With Shapes. Il codice non aiuterà con il tuo problema immediato, ma ti darà un'idea del tipo di Shapes che puoi definire.

3

Concetto: pulsanti invisibili con aree di spedizione circolari e poligonali

In primo luogo, si vorrà una classe che definisce un pulsante invisibile, estendendo javax.swing.AbstractButton in modo che sia ancora un pulsante completamente funzionale che è possibile aggiungere ascoltatori.

public abstract class InvisibleButton extends AbstractButton { 

    public abstract boolean contains(Point point); 

    @Override 
    public boolean isVisible() { 
     return false; 
    } 
} 

Quindi, ovviamente, vorrai implementazioni di quella classe.Ecco due esempi: uno che usa un poligono per forme complesse, uno che usa un cerchio.

public class PolygonalButton extends InvisibleButton { 

    private Polygon area = null; 

    public PolygonalButton(Polygon area) { 
     this.area = area; 
    } 

    @Override 
    public boolean contains(Point point) { 
     return area.contains(point); 
    } 
} 

public class CircularButton extends InvisibleButton { 

    private int x; 
    private int y; 
    private double radius; 

    public CircularButton(int x, int y, double radius) { 
     this.x = x; 
     this.y = y; 
     this.radius = radius; 
    } 

    @Override 
    public boolean contains(Point point) { 
     double dx = x - point.x; 
     double dy = y - point.y; 
     return Math.sqrt(dx * dx + dy * dy) <= radius; 
    } 
} 

Infine, è necessario implementare un contenitore che gestisce tutti questi pulsanti, ma è necessario utilizzare un pannello al posto di una cornice. Piuttosto che agganciare ogni singolo listener, puoi semplicemente sovrascrivere i processori degli eventi del frame e passarli ai pulsanti necessari.

public class InvisibleButtonImagePanel extends JPanel { 

    private BufferedImage image = null; 
    private List<InvisibleButton> buttons = new ArrayList<>(); 

    public InvisibleButtonImagePanel(BufferedImage image) { 
     this.image = image; 
    } 

    public void add(InvisibleButton button) { 
     buttons.add(button); 
    } 

    public void remove(InvisibleButton button) { 
     buttons.remove(button); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(image.getWidth(), image.getHeight()); 
    } 

    @Override 
    public void processKeyEvent(KeyEvent event) { 
     for (InvisibleButton button : buttons) { 
      if (button.isFocusOwner()) { 
       button.dispatchEvent(event); 
      } 
     } 
     super.processKeyEvent(event); 
    } 

    @Override 
    public void processMouseEvent(MouseEvent event) { 
     for (InvisibleButton button : buttons) { 
      if (button.contains(event.getPoint())) { 
       button.dispatchEvent(event); 
      } 
     } 
     super.processMouseEvent(event); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     g.drawImage(image, 0, 0, null); 
     super.paintComponent(g); 
    } 
} 

probabilmente si vorrà per rinominare il pannello a qualcosa di meno ingombrante, e magari implementare il proprio codice avanzata delle immagini, ma questa è l'idea di base dietro di esso.

+0

Buona risposta, sebbene avvertissi l'OP di non utilizzare i componenti java.awt a favore di Swing. –

+0

Oh wow, ho completamente perso il fatto che la domanda fosse contrassegnata da 'swing'. Riscriverò questa risposta. – Vulcan

+0

haha, facile da trascurare. Buona risposta, +1 –