2010-09-30 10 views
5

Tenga paciencia conmigo ... No creo que esto sea demasiado subjetivo, pero tal vez estoy equivocado.¿Es esta Java idónea?

Recientemente quise factorizar un código repetitivo que dibujó un fondo de mapa de bits personalizado en nuestra aplicación BlackBerry.

(Esta pregunta no es realmente acerca de BlackBerry embargo, así que va a proporcionar algunos detalles aquí acerca de la interfaz gráfica de usuario de BB para que la gente no BB Java pueden pesar en ...)

La pantalla completa es de la clase BB API: tiene un método paint (Graphics) que el framework llama para dibujar la pantalla y cualquier componente que se le agregue. Es posible anular esto para hacer una pintura personalizada, como dibujar un fondo de mapa de bits antes de que ocurra otra pintura (las nuevas API de BB proporcionan una clase de fondo pero nuestra aplicación tiene que funcionar en teléfonos más antiguos).

quería tener un montón de pantallas de todos con el mismo fondo, que cada uno hizo una especie de pintura personalizada ... Esto es lo que ocurrió:

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

Cada pantalla a continuación, se subclase este resumen clasifique e implemente innerPaint(). De esta forma, cuando el framework BB llama al método paint(), cada pantalla puede tener material de pintura personalizado DESPUÉS de que se dibuje el fondo (para que cualquier pintura se coloque encima del fondo) pero ANTES de dibujar los componentes de la pantalla, cuando FullScreen. paint() se llama.

(me ocurrió esto porque he estado estudiando Common Lisp en casa, y se me ocurrió que lo que quería hacer era algo así como la combinación método de entrelazado en CLOS)

He aquí un ejemplo de implementación de la clase abstracta arriba:

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(...) 
    } 
} 

Básicamente quiero una clase secundaria para implementar un método es llamado en el medio de la ejecución de su padre y la ejecución de su abuelo del mismo método. No pude encontrar ninguna otra forma de hacer esto en Java ...

¿Es esta Java idónea? ¿Es esto realmente muy común y es una pregunta tonta? ¿Es esto realmente horrible diseño? (Expertos de BB, ¿cómo puedo hacer esto de otra manera?)

Editado para agregar: Esto funciona como se describe: el dibujo ocurre en el orden que deseo.

+0

probablemente (sin saber nada de BB api), podría llamar a 'super.paint', antes, pintura interior – OscarRyz

+0

Si cambio la clase abstracta para llamar a super.paint antes de innerPaint, entonces las cosas en innerPaint se dibujan encima de los botones, etc. – spacemanaki

+3

Solo una pequeña adición a las respuestas que dicen correctamente que esto está bien y se conoce como Método de plantilla: es posible que desee hacer paint() final, para que los clientes (subclases concretas) no puedan confundirlo y romperlo inadvertidamente la representación. –

Respuesta

5

Sí, y no solo idiomático Java, sino OO, en general. Se llama template method

+0

¡Gracias! Tal vez es una pregunta tonta ...Definitivamente soy solo un principiante. – spacemanaki

+0

nahhh, de vez en cuando tendemos a inventar patrones ya inventados. Es bueno preguntar, y luego descubrir que ya existió. A partir de ahora, puede decir * hey, no solo utiliza el patrón de método de plantilla para ese * etc.;) – OscarRyz

+0

Bueno, en realidad no he leído mucho sobre patrones aunque el libro de GoF está en mi lista de lectura . – spacemanaki

2

Esto es casi exactamente como funciona Swing - vea el método JComponent.paintComponent. El método de pintura llama a paintBorder, paintComponent y paintChildren, y puede anular paintComponent para implementar su propio dibujo sin interferir con los componentes estándar de Swing.

+0

Interesante - No he usado Swing en mucho tiempo y aun así era solo una clase corta en pregrado. ¡Gracias! – spacemanaki

0

Bienvenido al patrón de diseño: Lo que ha descubierto se llama Template Method.