2009-12-12 12 views
5

Me pregunto acerca de la práctica estándar con clases internas (en Java, pero supongo que se aplica a todos los lenguajes OO). Así que tengo una subclase JFrame ControllerWindow que contiene una subclase JPanel MapPanel que dibujo (por lo que necesita sobrescribir el método paintComponent) y que necesita implementar un detector de mouse. Mi solución actual que funciona es tener MapPanel en una clase separada implementando MouseListener, pero cuando le mostré esto al chico que dirige mi curso el otro día pareció pensar (tenemos un poco de barrera de idioma) esto debería ser en un interior clase en ControllerWindow o al menos el MouseListener debe ser una clase interna.Estándares para usar clases internas para GUI?

Así que mi pregunta es, ¿cuál sería la solución estándar aquí, para poner un MouseListener en la clase interna, el JPanel en una clase interna diferente o todavía en su clase separada? ¿JPanel implementa MouseListener en una clase interna? ¿Y por qué?

Lo más importante para mí es que funciona, pero me gustaría conocer y entender las prácticas estándar detrás de estas cosas si es posible.

EDITAR: Versión muy simplificada del código actual a continuación.

class ControllerWindow extends JFrame{ 
    ... 
    MapPanel drawPanel = new MapPanel(); 
    ... 
} 

y una clase separada:

class MapPanel extends JPanel implements MouseListener{ 

    ... 

    public void paintComponent(Graphics g){ 
     ...//fillRects etc. 
    } 

    //MouseListener methods 
    public void mouseReleased(MouseEvent e){ 
     requestFocus(); 
     ... 
     repaint() 
     ... 
    } 
    public void mousePressed(MouseEvent e){} 
    public void mouseEntered(MouseEvent e){} 
    public void mouseExited(MouseEvent e){} 
    public void mouseClicked(MouseEvent e){} 
} 

también podría ser esto una situación en la que sería aceptable para poner las dos clases en el mismo archivo? No preveo usar MapPanel para nada que no sea ControllerWindow.

+2

La práctica estándar para el código GUI es una gran bola de barro. –

+0

¿Podría proporcionar algún código? Simplificado si es necesario. – amorfis

Respuesta

4

Creo que es algo arbitrario cómo hacerlo (como comentó Tom Hawtin, estándares GUI = barro), ya que está intercambiando complejidad en el número de clases frente a la complejidad en una sola clase. Si desea producir código simplemente para una demostración, un solo archivo podría ser más fácil. Si quiere código que va a poner en producción y modificar/mantener a lo largo del tiempo, es casi seguro que desea abstraerlo en diferentes clases.

Por ejemplo, si incorpora MapPanel como una clase interna en ControllerWindow, y luego desea reemplazarlo con un tipo diferente de MapPanel, tiene una actualización masiva de ControllerWindow en lugar de simplemente cambiar MapPanel por una diferente tipo de componente

Con el MouseListener, me inclino a incluirlo en MapPanel si se trata de eventos específicos para ese componente (es decir, si solo el MapPanel "sabe" lo que significa un clic, debe ser el que procese ese hacer clic). Definitivamente no lo pondría en ControllerWindow, desde entonces estás "filtrando" detalles de implementación de MapPanel.(El único caso en el que puedo pensar: además de tu MapPanel, tienes varios tipos de paneles que necesitan responder a los clics de la misma manera, así que en lugar de implementarlo en cada panel, puedes hacer que lo haga ControllerWindow. , No estoy seguro de que el código deba estar en ControllerWindow).

Si el detector de mouse de MapPanel es una implementación de clase interna de MouseListener, o si MapPanel lo implementa (como en el código anterior), probablemente se deba a una cuestión de qué estilo prefiere.

7

Es común usar clases internas anónimas como detectores de eventos porque el código suele ser bastante simple (por lo que una clase separada puede ser excesiva) y mantener el código del manejador "cerca" del código que registra al oyente puede mejorar la legibilidad de personas que intentan comprender su código, ya que todo el código relacionado con el evento está en un solo lugar.

EDITAR: Esto es particularmente cierto para las clases que implementan solo un método de escucha. Tal vez sea menos cierto para interfaces multiproceso como MouseListener, ya que una clase que implemente la interfaz completa será más detallada.

+2

Para interfaces como 'MouseListener' hay clases como' MouseAdapter' que le permiten anular solo los métodos que realmente le interesan. – Bombe

+1

Sí, y esto también se puede hacer como una clase interna anónima. Todos ganan. –

0

Debido a requisitos de manejo de eventos múltiples se requieren clases internas anónimas. La clase anónima se puede escribir en cualquier lugar como en una clase, en un método, en el argumento. Por lo tanto, abstenerse de crear muchas clases para cada oyente es preferible.

1

clase interna sería mejor si tiene una sintaxis más simple.

button1.click(function(event){ do something x... }); 
button2.click(function(event){ do something y... }); 
radio2.check (function(event){ do something z... }); 

java 7 puede darnos algo así y cambiar toda la situación. como está ahora, usar muchas clases internas anónimas puede estropear el código e imposibilitar su lectura. debe elegir cualquier estilo que haga que su código sea hermoso y legible.

Cuestiones relacionadas