[JAVA] Vreemd probleem mbt focus en drawing

Pagina: 1
Acties:

  • ravenger
  • Registratie: Juli 2001
  • Laatst online: 03-02 15:35
Ben bezig met een programmaatje wat dingen op het scherm (een JPanel) moet tekenen aan de hand van keyinput. Hierbij doet zich een vreemd probleem voor; wanneer iets word getekend, en ik minimaliseer het venster, en maximaliseer het venster vervolgens, dan is het getekende verdwenen. Mkay zou je zeggen, laat het scherm focusListener implementen en roep een draw aan op het moment dat ie de focus weer gained in de focusGained(FocusEvent e) methode. Helaas werkt dat niet, ondanks dat het venster wel de focus weer terugkrijgt wanneer ik maximaliseer.

Overigens maak ik geen gebruik van de repaint() methode, omdat ik zelf wil controleren wanneer er iets getekend moet worden (setIgnoreRepaint(true)). Wanneer de window focus gained, dan gebeurt dit ook niet (gecontroleerd door de repaint method te overriden en een message naar console te sturen).

Wat zou hier aan de hand kunnen zijn?

  • martennis
  • Registratie: Juli 2005
  • Laatst online: 16-01 14:17
kun je misschien wat relevante code plaatsen van het tekenen op de JPanel?

  • ravenger
  • Registratie: Juli 2001
  • Laatst online: 03-02 15:35
sure;
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class EditorView extends JPanel implements Observer, FocusListener {
    
    private ColumnGlyph glyphModel;
    
    public EditorView(ColumnGlyph glyphModel) {
        this.glyphModel = glyphModel;
        this.setBackground(Color.WHITE);
        this.setIgnoreRepaint(true);
        this.addFocusListener(this);
        this.setDoubleBuffered(true);
    }
    
    public void draw() {
        try { 
            Graphics g = this.getGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0,0,(int)this.getSize().getWidth(),(int)this.getSize().getHeight());
            g.setColor(Color.BLACK);
            glyphModel.draw(g,glyphModel.getPoint().getX(),glyphModel.getPoint().getY());
            g.dispose();
        } catch (Exception e) {
            System.out.println("Graphics context error: " + e);  
        }
    }

    public void update(Observable o, Object arg) {
        ColumnGlyph glyphModel = (ColumnGlyph) o;
        this.draw();
    }
    
    public void setListener(KeyListener listener) {
        this.addKeyListener(listener);
    }

    public void focusGained(FocusEvent e) {
        this.draw();
    }

    public void focusLost(FocusEvent e) {
        System.out.println("lost Focus");
    }
}

Ik heb voor het leesgemak maar ff focuslistener geimplementeerd in deze klasse.

  • martennis
  • Registratie: Juli 2005
  • Laatst online: 16-01 14:17
misschien als je een windowfocuslistener op je frame zet, en in die methode je repaint aanroept?
heb je dat al geprobeerd? want wanneer je window de focus weer krijgt, hoeft niet perse je panel de focus (weer) te krijgen

[ Voor 28% gewijzigd door martennis op 28-09-2006 22:17 ]


  • ravenger
  • Registratie: Juli 2001
  • Laatst online: 03-02 15:35
dat is waar, maar dat is wel wat er gebeurt, bij een maximalisatie krijgt dit JPanel de focus terug; ik neem tenminste aan dat focusGained niet reageert waneer een ander component dan de JPanel focus krijgt.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 12-02 15:05

Robtimus

me Robtimus no like you

ravenger schreef op donderdag 28 september 2006 @ 21:06:
Java:
1
2
3
4
5
6
    private ColumnGlyph glyphModel;
    
    public void update(Observable o, Object arg) {
        ColumnGlyph glyphModel = (ColumnGlyph) o;
        this.draw();
    }
Ik weet niet of dit ermee te maken heeft, maar je beseft dat je niks doet met je (lokale variabele) glyphModel in je update() method? Het lijkt me niet de bedoeling, anders had je het wel weggelaten.

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


  • ravenger
  • Registratie: Juli 2001
  • Laatst online: 03-02 15:35
mja nu pas eigenlijk, het is eigenlijk een overbodige regel; het heeft geen effect omdat de lokale glyphModel altijd dezelfde is als degene in de update functie, omdat de glyphModel in de constructor van de EditorView word meegegeven. Ik zou dit ook niet kunnen doen en puur op de update de glyphModel kunnen updaten, maar dat heeft verder geen invloed op het programma en de behaviour; het is misschien wel netter tho :)

  • ravenger
  • Registratie: Juli 2001
  • Laatst online: 03-02 15:35
Anyway ik heb het nog steeds niet opgelost, en het lijkt me toch niet een heel uitzonderlijk probleem; iemand die er misschien wat licht op kan laten schijnen ?

  • martennis
  • Registratie: Juli 2005
  • Laatst online: 16-01 14:17
kun je de methode draw niet vervangen door paint(Graphics)?
Misschien dat bij het heropenen het frame een repaint wil uitvoeren.

en probeer eens de dispose weg te laten. misschien dat ie daar op blijft haken.

[ Voor 24% gewijzigd door martennis op 02-10-2006 11:12 ]


  • azteke
  • Registratie: September 2002
  • Laatst online: 09-02 10:34

azteke

King

lijkt me toch dat je ergens een repaint() oid mist, maar kan het misschien ook aan de ColumnGlyph draw() methode liggen?

CMDR azteke || You never get a second chance to make a first impression...


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 15:45
Een JPanel krijgt sowieso niet automagisch de focus als je het JFrame dat het JPanel bevat activeert / selecteert. Dat moet handmatig met de requestFocus() / requestFocusinWindow() methode.

Edit: Gebruik van de requestFocusInWindow() methode heeft btw de voorkeur.

[ Voor 23% gewijzigd door Kwistnix op 02-10-2006 12:44 ]


  • ravenger
  • Registratie: Juli 2001
  • Laatst online: 03-02 15:35
martennis schreef op maandag 02 oktober 2006 @ 11:11:
kun je de methode draw niet vervangen door paint(Graphics)?
Misschien dat bij het heropenen het frame een repaint wil uitvoeren.

en probeer eens de dispose weg te laten. misschien dat ie daar op blijft haken.
Dispose is het zeker niet, dit zorgt slechts ervoor dat het graphics object direct word verwijderd door de garbagecollector wanneer het niet meer nodig is.
Azteke schreef op maandag 02 oktober 2006 @ 11:45:
lijkt me toch dat je ergens een repaint() oid mist, maar kan het misschien ook aan de ColumnGlyph draw() methode liggen?
Het ligt niet aan de draw() methode van ColumnGlyph; de graphicsobject van het JPanel word immers gewoon doorgegeven aan die methode.
FallenAngel666 schreef op maandag 02 oktober 2006 @ 12:39:
Een JPanel krijgt sowieso niet automagisch de focus als je het JFrame dat het JPanel bevat activeert / selecteert. Dat moet handmatig met de requestFocus() / requestFocusinWindow() methode.

Edit: Gebruik van de requestFocusInWindow() methode heeft btw de voorkeur.
Zoals al eerder gezegd, aan de focus zelf ligt het niet, want ik heb geconstateerd dat bij een minimaliseeractie focusLost() word aangeroepen, en bij een maximaliseeractie focusGained() van de JPanel waar ik op aan het werk ben.

Anyway, wat mijn gedachtengang was;
- First, is dat draw() sneller is dan wanneer ik repaint() doe, omdat ik dan geen delay heb in het painten (repaint() is namelijk een request voor het verversen en niet een demand) en dat ik bij het aanslaan van heel veel keys tegelijk dus geen last krijg van flickering en objecten die niet op de juiste positie worden getekend. Daarom heb ik setIgnoreRepaint(true), dus je zou zeggen dat ie niet op repaint() zou moeten reageren, echter wanneer ik zelf een repaint() aanroep, dan geeft ie daar toch gehoor aan, iets wat ik vrij merkwaardig vind, maar het blijkt zo te zijn dat hij dan alleen repaints van de OS ignored.
- Second, mijn conclusie was dat het graphicsobject van de JPanel wat ik opvraag door this.getGraphics() niet volgens doublebuffering werkt terwijl ik aan het JPanel wel meegeef dat ik dat wil gebruiken, en dat ik dus gebruik moet maken van een VolatileImage om zelf een doublebuffer te maken.
- Third, wanneer ik this.getGraphics() aanroep zou je verwachten dat hij de graphics van het JPanel op vraagt en geen problemen zou moeten hebben met het tekenen wanneer bij een focusGained() de draw word aangeroepen. Blijkbaar is dat dus niet zo, en heb ik het verkeerd.
Pagina: 1