[Java] onzichbare EN klikbare container met components

Pagina: 1
Acties:

  • Kman
  • Registratie: April 2000
  • Laatst online: 21-01 15:40
Ik ben momenteel bezig met een applet waarin ik rond bewegende animaties en plaatjes direct op een Graphics object teken (middels drawImage). Nu moeten een aantal van die plaatjes klikbaar zijn. Omdat ik niet de standaard Containers en Components zullen mouseEvents niet worden geregisteerd.

Waar ik aan zat te denken is om een soort onzichtbare container gevuld met andere containers en components te plaatsen over het oppervlak waarop getekend wordt, waarin de locatie van de klikbare plaatjes overeenkomt met een aantal dummy components binnen die container. Probleem is alleen dat wanneer een container of component een setLocation opdracht krijgt dit een repaint triggert, waardoor de container over het oppervlakte gaat tekenen en je daardoor vervelend geknipper krijgt. Het grafische oppervlak en de container gaan dan namelijk door elkaar tekenen waardoor er een onrustig beeld onstaat.

Om de container onzichtbaar te maken heb ik de setVisible(false) methode gebruikt, maar dit zorgt ervoor dat alle mouseEvents niet meer geregistreerd worden door de container. Ik heb ook geprobeerd een custom container te maken waarin ik alle met paint gerelateerde methodes (paint, repaint, update, paintComponents) override en leeg laat, maar dan tekent de container alsnog pixels over het oppervlak heen. setOpaque(false) heeft hetzelfde effect..

Dus m'n vraag is: is er een manier om een doorzichtige container te maken waarin ik andere components en containers kan plaatsen waarop MouseEvents worden geregisteerd, zonder dat de container gaat tekenen op het beeld bij verplaatsing van een component/container?

[ Voor 5% gewijzigd door Kman op 21-05-2005 17:21 . Reden: wat grammatica en spelling verbeterd ]


  • nxt
  • Registratie: November 2001
  • Laatst online: 04-02 09:36

nxt

waarom plaats je die plaatjes niet in een Canvas voor awt, of een JPanel voor swing
als je een van die 2 extend en daarin tekent heb je volgens mij geen probleem met het opvangen van die events

edit: en vervang dan bij de canvas de paint(Graphics g) method, en bij de JPanel de paintComponent(Graphics g)
als je een JPanel gebruikt kun je ook nog setOpague(false) aanroepen om de achtergrond transparant te maken.

[ Voor 25% gewijzigd door nxt op 21-05-2005 17:34 ]


  • Kman
  • Registratie: April 2000
  • Laatst online: 21-01 15:40
Het gaat om een aantal plaatjes en animaties waarvan de weergave en beweging zo snel en soepel mogelijk moet verlopen. Door dit te doen dmv het schuiven met grafische components zal het lang niet zo soepel en snel gaan dan als je de grafische data direct in een Graphics object van een enkele JPanel (of iets anders) schrijft. Probleem bij die aanpak is dan wel dat mouse input een stuk minder vanzelfsprekend gaat. Vandaar dat ik een manier zoek om volledig onzichtbare containers en components over de oppervlakte van dat Graphics object te plaatsen om zo de mouse input via lege dummy components te kunnen doen.

[ Voor 4% gewijzigd door Kman op 21-05-2005 17:44 ]


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19:18

Robtimus

me Robtimus no like you

Waarom gebruik je geen JLabel icm een (Image)Icon? Ipv zelf te tekenen voeg je een JLabel toe zonder tekst maar met alleen een (Image)Icon, dan is dat grafisch gezien ook niet meer dan een plaatje. Het heeft dan wel als voordeel dat je er een MouseListener aan kan hangen.

Wat het rondbewegen betreft: als je geen LayoutManager gebruikt (setLayout(null)) en dan setLocation van de JLabels gebruikt kun je ze ook neerzetten waar je wilt.
Als je zelf een LayoutManager implementeert die een lege layoutContainer method heeft (die zet normaal de componenten op hun plek), en waarbij de preferredLayoutSize zodanig geimplementeerd is dat de preferredsize van je panel net groot genoeg is om alle labels te laten zien, dan werkt het ook meteen perfect in scrollpanes.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public Dimension preferredLayoutSize(Container parent)
    {
        synchronized (parent.getTreeLock())
        {
            Insets insets = parent.getInsets();
            Component[] comps = parent.getComponents();
            int width = 0;
            int height = 0;
            for (int i = 0; i < comps.length; i++)
            {
                Dimension d = comps[i].getPreferredSize();
                int x = comps[i].getX();
                int y = comps[i].getY();
                width = Math.max(width, x + d.width);
                height = Math.max(height, y + d.height);
            }
            return new Dimension(
                insets.left + insets.right + width,
                insets.top + insets.bottom + height
            );
        }
    }

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Kman
  • Registratie: April 2000
  • Laatst online: 21-01 15:40
Bedankt voor je suggestie, maar zoals ik in een eerdere reply al had vermeldt is de performance van ruindschuivende grafische components niet zo hoog als dat je de plaatjes en animaties direct tekent
in een Graphics object van bijvoorbeeld een JPanel.

Om het gebrek aan mouse input handling dan op te vangen wilde ik volledig doorzichtige dummy container en components gebruiken die ongezien over het grafische oppervlak bewegen. Maar bij setLocation calls gaan die containers en components zich weer painten waardoor het tekenen van het grafische oppervlak verstoord wordt.

Weet iemand een manier waarop een container en/of component volledig onzichbaar blijft EN de mogelijkheden behoudt om mousekliks te kunnen registreren (en doorgeven aan mouse listeners)? In de topic start had ik al wat niet werkende methoden genoemd.. iemand nog andere suggesties?

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 19:18

Robtimus

me Robtimus no like you

1 mouselistener op de container waarop je tekent, die dan moet bepalen op welk plaatje (if any) geklikt was.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Kman
  • Registratie: April 2000
  • Laatst online: 21-01 15:40
En hoe komt die mouselistener er dan achter om elk plaatje het gaat?

Kan op zich gedaan worden door een array bij te houden van posities van plaatjes en daaruit te filteren op welk plaatje er geklikt wordt. Dit wordt echter een vervelender (en prestatie-verminderend) verhaal wanneer je mouseEnter en mouseLeave events wil simuleren.

Daarnaast bestaat er al een uitgebreid event systeem in Java en lijkt het mij zonde van tijd en moeite om dat wiel opnieuw uit te vinden.

Is er dan echt geen manier om components en containers volledig onzichtbaar te maken maar dan wel de mouse events ervan te kunnen ontvangen?

  • nxt
  • Registratie: November 2001
  • Laatst online: 04-02 09:36

nxt

Misschien is het handig om handig om het probleem nog een keer duidelijk neer te zetten.
Want ik denk zelf namelijk dat het niet zoveel uitmaakt qua performance of je
situatie a
- alle plaatjes zelf tekend
- voor elk plaatje dat op de muis moet reageren een invisible component hebt dat op exact dezelfde plaats staat als dat plaatje.

of situatie b
- voor elk plaatje dat op de muis moet reageren dat tekent in een JPanel.
- en de rest v/d plaatjes wel zelf tekent.

in situatie a moet je net zoals in situatie b ervoor zorgen dat de components op de juiste grootte & locatie hebben.
in situatie a hoeft de paint / paintComponent method van het component niet aangeroepen te worden, maar daar staat tegenover dat je dan wel weer moet uitvogelen welke component bij welk plaatje hoort (en ik vraag me af of 't verschil in performance groot genoeg is om te meten).

Als het alleen gaat om 't knipperen van tijdens een repaint, zou ik eens zoeken op double buffering. Dat knipperen wordt namelijk veroorzaakt door dat standaard bij een repaint eerst 't volledige scherm gewist wordt en daarna elke component apart getekend wordt.
Pagina: 1