2010-09-30 8 views
5

Bär mit mir ... Ich denke nicht, dass dies zu subjektiv ist, aber vielleicht liege ich falsch.Ist das idomatic Java?

Kürzlich wollte ich einen sich wiederholenden Code herausrechnen, der einen benutzerdefinierten Bitmap-Hintergrund auf unserer BlackBerry App gezeichnet hat.

(Diese Frage ist nicht wirklich über Blackberry obwohl, so dass ich einige Details hier über den BB-GUI zur Verfügung stellen, so dass nicht-BB Java Menschen in wiegen ...)

Die Klasse Fullscreen von der ist BB API - es hat eine Methode paint (Graphics), die das Framework aufruft, um den Bildschirm und alle hinzugefügten Komponenten zu zeichnen. Es ist möglich, dies zu überschreiben, um eine benutzerdefinierte Bemalung zu erstellen - z. B. einen Bitmap-Hintergrund zu zeichnen, bevor ein anderes Bild entsteht (neuere BB-APIs bieten eine Hintergrundklasse, aber unsere App muss auf älteren Telefonen funktionieren).

ich ein paar Bildschirme alle mit dem gleichen Hintergrund, die jeweils tat irgendeine Art von Custom Painting ... hier ist, was ich kam mit haben wollte:

abstract public class BGFullScreen extends FullScreen { 
    Bitmap bg; 

    public BGFullScreen(Manager mgr, long style) { 
     super(mgr, style); 
     bg = Bitmap.getBitmapResource("bg.jpg"); 
    } 

    abstract protected void innerPaint(Graphics g); 

    protected void paint(Graphics g) { 
     g.drawBitmap(new XYRect(0, 0, bg.getWidth(), bg.getHeight()), bg, 0, 0); 

     innerPaint(g); 

     super.paint(g); 
    } 
} 

Jeder Bildschirm wird dann eine Unterklasse diese abstrakte Klasse und implementieren Sie innerPaint(). Wenn das BB-Framework die paint() -Methode aufruft, können auf jedem Bildschirm benutzerdefinierte Malvorlagen nach dem Zeichnen des Hintergrunds (also jedes Mal über dem Hintergrund) angezeigt werden, aber BEVOR die Komponenten des Bildschirms gezeichnet werden, wenn FullScreen angezeigt wird. paint() wird aufgerufen.

(ich kam mit dieser, weil ich zu Hause Common Lisp studiert, und es fiel mich ein, dass so etwas wie die verschachtelte Methodenkombination in CLOS, was ich tun wollte, war)

Hier ist eine Beispielimplementierung oberhalb der abstrakten Klasse:

public class MainAppScreen extends BGFullScreen { 

    public MainAppScreen() { 
     super(new VerticalFieldManager(), 0); 
     // add some components to the screen: 
     add(new ButtonField(...)); 
     add(...) 
    } 

    protected void innerPaint(Graphics g) { 
     // stuff drawn will be on top of background and under buttons 
     g.draw(...) 
    } 
} 

Grundsätzlich möchte ich ein Kind Klasse eine Methode wird aufgerufen, in-zwischen seinen Eltern Umsetzung und seine Großeltern eltern~~POS=HEADCOMP Umsetzung derselben Methode zu implementieren. Ich konnte keine andere Möglichkeit finden, dies in Java zu tun ...

Ist das idomatic Java? Ist das wirklich wirklich üblich und es ist eine dumme Frage? Ist das wirklich schreckliches Design? (BB Experten, wie kann ich das anders machen?)

Bearbeitet um hinzuzufügen: Dies funktioniert wie beschrieben - die Zeichnung passiert in der Reihenfolge, die ich will.

+0

wahrscheinlich (ohne etwas über BB api zu wissen), könnten Sie 'super.paint' aufrufen, vorher, innere Farbe – OscarRyz

+0

Wenn ich die abstrakte Klasse ändern, um super.paint vor innerPaint zu nennen, dann werden die Dinge in innerPaint darüber gezogen die Knöpfe, usw. – spacemanaki

+3

Nur eine kleine Ergänzung zu den Antworten, die korrekt sagen, dass dies in Ordnung ist und als Template-Methode bekannt ist: Vielleicht möchten Sie paint() final machen, damit Clients (konkrete Unterklassen) nicht versehentlich damit herumhantieren und brechen können das Rendern –

Antwort

5

Ja, und nicht nur idiomatische Java, aber OO, im Allgemeinen. Es heißt template method

+0

Danke! Vielleicht ist es eine dumme Frage ...Ich bin definitiv nur ein Anfänger. – spacemanaki

+0

nahhh, von Zeit zu Zeit tendieren wir dazu, bereits erfundene Muster zu erfinden. Es ist gut zu fragen und dann herauszufinden, dass es schon existiert hat. Von nun an kannst du sagen * hey, wir benutzen nicht einfach das Template-Methodenmuster für dieses * etc.;) – OscarRyz

+0

Nun, ich habe eigentlich nicht viel über Muster gelesen, obwohl das GoF-Buch auf meiner To-Read-Liste steht . – spacemanaki

2

Das ist fast genau wie Swing funktioniert - siehe JComponent.paintComponent Methode. Die Paint-Methode ruft paintBorder, paintComponent und paintChildren auf, und Sie können paintComponent überschreiben, um Ihre eigene Zeichnung zu implementieren, ohne die Swing-Standardkomponenten zu beeinträchtigen.

+0

Interessant - ich habe Swing schon lange nicht mehr benutzt und auch damals war es nur eine kurze Klasse im Undergrad. Vielen Dank! – spacemanaki

0

Willkommen im Designmuster: Was Sie entdeckt haben, heißt Template Method.

Verwandte Themen