2013-08-08 10 views
6

Mam ramkę z obrazem, który ją zakrywa, I chcę, aby za każdym razem, gdy ktoś kliknie na inny obiekt na obrazku, zadziała jako przycisk i zrobi coś.
Problem polega na tym, że obiekty te nie są prostymi kształtami, więc zastanawiałem się nad rysowaniem własnych niewidzialnych przycisków w kształcie tych obiektów.Jak mogę utworzyć złożony kształt przycisku?

Czy to możliwe? lub jaki byłby lepszy sposób na osiągnięcie czegoś takiego?

-Dziękuję

+1

Będzie śledzić to. Próbowałem czegoś bardzo podobnego na Androidzie, a skończyło się na tym, że zadowalałem się niewidzialnymi przyciskami nad dziwnymi kształtami :) – sealz

+0

to będzie działać jak przycisk i coś zrobić. to na przykład coś takiego jak wirtualny pilot do telewizora – mKorbel

+1

Zobacz także przedstawione podejście [tutaj] (http://stackoverflow.com/q/10861852/230513). – trashgod

Odpowiedz

2

można śledzić pozycję użytkownicy myszy za pomocą współrzędnych?

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

Teraz umieść metodę ActionPerformed i sprawdź, czy x i y = np. 200, 300 zrób to. W ten sposób, gdy użytkownik kliknie na miejscu (twój cel dla obszaru) przekieruje go do metody.

3

zdefiniować interfejs dla regionu jak:

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

Następnie, jeśli chcesz kolisty obszar klikalny, zdefiniowanie klasy, która sprawdza czy x, współrzędna y jest w pewnej odległości od pozycji.

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

Utwórz listę IButtonów. Wykonasz iterację, aby sprawdzić, czy użytkownik kliknął jeden z niewidzialnych przycisków.

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

Potem za każdym razem, gdy ktoś kliknie w ramce iteracyjne nad swoimi niewidzialnych przycisków przy użyciu lokalizacji tego kliknięcia myszy.

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

Możesz łatwo zobaczyć, jak zdefiniować niewidoczne przyciski prostokątne, takie jak ten, a nawet nieregularne kształty wielokątów. Po prostu trzeba poprawnie wdrożyć metodę contains.

2

Chcę, aby za każdym razem, gdy ktoś kliknie na inny obiekt na obrazku, zadziała jako przycisk i zrobi coś.

Można utworzyć obiekty ArrayList obiektów Shape. Następnie dodajesz MouseListener do komponentu zawierającego obraz. Za każdym razem, gdy generowane jest zdarzenie mousePressed, przechodzisz przez ArrayList i używasz metody containts (...) komponentu, aby określić, czy użytkownik kliknie na Corapes.

Zapoznaj się z Playing With Shapes. Kod nie pomoże w twoim bezpośrednim problemie, ale da ci pojęcie o typie Shapes, który możesz zdefiniować.

3

Concept: niewidzialne przyciski z okrągłych i wielokątnych obszarów wysyłkowych

Po pierwsze, będziemy chcieli klasa definiując niewidzialny przycisk, rozszerzając javax.swing.AbstractButton tak, to jeszcze w pełni funkcjonalny przycisk, który można dodać słuchaczy do.

public abstract class InvisibleButton extends AbstractButton { 

    public abstract boolean contains(Point point); 

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

Następnie, oczywiście, będziesz potrzebować implementacji tej klasy.Oto dwa przykłady: jeden używający wielokąta dla złożonych kształtów, jeden używający koła.

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

Wreszcie, trzeba zaimplementować kontener, który obsługuje wszystkie z tych przycisków, ale należy użyć panelu zamiast ramce. Zamiast podpinania każdego pojedynczego detektora, można po prostu przesłonić procesory zdarzeń ramy i przekazać je do wymaganych przycisków.

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

prawdopodobnie będziesz chciał zmienić nazwę panelu do czegoś mniej nieporęczne, a może zaimplementować własną zaawansowaną kod obrazka, ale to podstawowa idea za nim.

+0

Dobra odpowiedź, chociaż ostrzegam OP przed użyciem komponentów java.awt na rzecz Swing. –

+0

Och, wow, zupełnie pominąłem, że pytanie zostało oznaczone jako "swing". Napiszę tę odpowiedź. – Vulcan

+0

haha, łatwo przeoczyć. Dobra odpowiedź, +1 –

Powiązane problemy