Download Manejo básico de Menús

Document related concepts
no text concepts found
Transcript
Menús
No hay ningún método para diseñar un buen interfaz de usuario, todo depende del programador. Los
Menús son siempre el centro de la aplicación, porque son el medio de que el usuario interactúe con esa
aplicación. La diferencia entre una aplicación útil y otra que es totalmente frustrante radica en la
organización de los menús, pero eso, las reglas del diseño de un buen árbol de menús, no están claras. Así
que, se va a explicar lo básico, sin que se deba tomar como dogma de fe, para que luego cada uno haga lo
que mejor le parezca.
En Java, la jerarquía de clases que intervienen en la construcción y manipulación de menús es la que se
muestra en la lista siguiente:
java.lang.Object
MenuShorcut
java.awt.MenuComponent
java.awt.MenuBar
java.awt.MenuItem
java.awt.Menu
java.awt.CheckboxMenuItem
java.awt.PopMenu
MenuComponent, es la superclase de todos los Componentes relacionados con menús.
MenuShortcut, representa el acelerador de teclado, o la combinación de teclas rápidas, para acceder a un
MenuItem.
MenuItem, representa una opción en un menú.
Menu, es un Componente de una barra de menú.
MenuBar, encapsula el concepto de una barra de menú en un Frame.
PopupMenu, implementa un menú que puede ser presentado dinámicamente dentro de un Componente.
CheckboxMenuItem, genera una caja de selección que representa una opción en un menú.
A continuación se exploran una a una las clases que se acaban de citar.
Clase MenuComponent
Esta clase no contiene campos, solamente tiene un constructor y dispone de una docena de métodos que
están accesibles a todas sus subclases.
Clase Menu
Esta es la clase que se utiliza para construir los menús que se manejan habitualmente, conocidos como
menús de persiana (o pull-down). Dispone de varios constructores para poder, entre otras cosas, crear los
menús con o sin etiqueta. No tiene campos y proporciona varios métodos que se pueden utilizar para crear
y mantener los menús en tiempo de ejecución. En el programa de ejemplo java1317.java, se usarán
algunos de ellos.
Constructores:
new Menu();
new Menu(“etiqueta”);
new Menu(“etiqueta”, boolean); // true se vuelve flotante el menú, false permanece fijo en la barra
Métodos:
add(obj MenuItem);
add(obj CheckboxMenuItem);
add(obj Menu); // el menú añadido se convierte en submenú
addSeparator();// agrega una línea divisora entre las opciones del menú
getItem();// regresa el objeto MenuItem correspondiente a la opción seleccionada
getItemCount();// regresa el número de elementos de ese menú
insert(obj MenuItem, posicion); // inserta la opción en el menú en la posición especificada
Clase MenuItem
Esta clase se emplea para instanciar los objetos que constituirán los elementos seleccionables del menú.
Kena Puga Nathal
Página 1
09/08/2017
1
Constructores;
new MenuItem();
new MenuItem(“etiqueta”);
new MenuItem( “etiqueta”, obj MenuShortcut );
Metodos:
addActionListener( ActionListener );
setEnabled( boolean); //true habilita la opción
isEnabled(); // regresa true si esta habilitada la opción
setLabel(“etiqueta”); // poner o cambiar etiqueta de la opción
getLabel(); // regresa una cadena que representa la etiqueta de la opción
setShortcut(obj MenuShortcut);
getShortcut(); // regresa un objeto de la clase MenuShortcut
Cuando se selecciona una opción de un menú, bien a través del ratón o por la combinación rápida de
teclas, se genera un evento de tipo ActionEvent. Para que la selección de la opción en un menú ejecute
una determinada acción, se ha de instanciar y registrar un objeto ActionListener que contenga el método
actionPerformed() sobreescrito para producir la acción deseada. En el ejemplo java1317.java, solamente
se presenta en pantalla la identificación de la opción de menú que se ha seleccionado; en un programa
realmente útil, la acción seguramente que deberá realizar algo más interesante que eso.
Clase MenuShortcut
Esta clase se utiliza para instanciar un objeto que representa un acelerador de teclado, o una combinación
de teclas rápidas, para un determinado MenuItem. Aparentemente, casi todas las teclas rápidas consisten
en mantener pulsada la tecla Control a la vez que se pulsa cualquier otra tecla.
Constructores:
MenuShortcut(int); //virtual keyCode proporcionado por la clase KeyEvent
MenuShortcut(int, boolean ); //true agrega shift, false solo control + tecla
KeyEvent.VK_tecla
Dispone de un segundo parámetro que indica si el usuario ha de mantener también pulsada la tecla de
cambio a mayúsculas (Shift). El primer parámetro es el código de la tecla, que es el mismo que se
devuelve en el campo keyCode del evento KeyEvent, cuando se pulsa una tecla.
La clase KeyEvent define varias constantes simbólicas para estos códigos de teclas, como son: VK_8,
VK_9, VK_A, VK_B.
Letras: VK_A a la VK_Z
Dígitos: VK_0 a la VK_9
Funciones: VK_F1 a la VK_F12
Especiales: VK_ALT, VK_ALT_GRAPH, VK_BACK_SLASH, VK_SLASH, ..,
Para mayor información consultar la clase KeyEvent en el API de java.
Podemos crear de dos maneras los objetos:
MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A, false);
o alternativamente
MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('A'), false);
Clase MenuBar
Sólo tiene un constructor público, y es la clase que representa el concepto que todo usuario tiene de la
barra de menú que está presente en la mayoría de las aplicaciones gráficas basadas en ventanas.
Constructor:
new MenuBar();
Métodos:
add(obj Menu);
getMenuCount(); //regresa la cantidad de menús asociados a esa barra de menús
Kena Puga Nathal
Página 2
09/08/2017
2
En el programa java1317.java, ilustra algunos de los aspectos que intervienen en los menús. Es una
aplicación que coloca dos menús sobre un objeto Frame. Uno de los menús tiene dos opciones y el otro,
tres. La primera opción del primer menú también tiene asignada una combinación de teclas rápidas:
Ctrl+Shift+K.
Cuando se selecciona un elemento del menú, éste genera un evento de tipo ActionEvent, que presenta
una línea de texto en pantalla indicando cuál ha sido el elemento del menú que se ha seleccionado, por
ejemplo:
% java java1317
java.awt.MenuItem[menuitem0,label=Primer Elemento del Menu A, shortcut=Ctrl+Shift+K]
java.awt.MenuItem[menuitem1,label=Segundo Elemento del Menu A]
java.awt.MenuItem[menuitem0,label=Primer Elemento del Menu A, shortcut=Ctrl+Shift+K]
java.awt.MenuItem[menuitem3,label=Segundo Elemento del Menu B]
También se instancia y registra un objeto receptor de eventos windowClosing() para terminar la ejecución
del programa cuando se cierra el Frame.
import java.awt.*;
import java.awt.event.*;
public class java1317 {
public static void main(String args[]){
IHM ihm = new IHM();
}
}
class IHM {
public IHM() {
// Se instancia un objeto de tipo Acelerador de Teclado
MenuShortcut miAcelerador = new MenuShortcut( KeyEvent.VK_K,true );
// Se instancian varios objetos de tipo Elementos de Menu
MenuItem primerElementoDeA = new MenuItem("Primer Elemento del Menu A",miAcelerador );
MenuItem segundoElementoDeA = new MenuItem("Segundo Elemento del Menu A" );
MenuItem primerElementoDeB = new MenuItem("Primer Elemento del Menu B" );
MenuItem segundoElementoDeB = new MenuItem("Segundo Elemento del Menu B" );
MenuItem tercerElementoDeB = new MenuItem("Tercer Elemento del Menu B" );
// Se instancia un objeto ActionListener y se registra sobre los
// objetos MenuItem
primerElementoDeA.addActionListener( new MiGestorDeMenu() );
segundoElementoDeA.addActionListener( new MiGestorDeMenu() );
primerElementoDeB.addActionListener( new MiGestorDeMenu() );
segundoElementoDeB.addActionListener( new MiGestorDeMenu() );
tercerElementoDeB.addActionListener( new MiGestorDeMenu() );
// Se instancian dos objetos de tipo Menu y se les añaden los
// objetos MenuItem
Menu menuA = new Menu( "Menu A" );
menuA.add( primerElementoDeA );
menuA.add( segundoElementoDeA );
Menu menuB = new Menu( "Menu B" );
menuB.add( primerElementoDeB );
menuB.add( segundoElementoDeB );
menuB.add( tercerElementoDeB );
Kena Puga Nathal
Página 3
09/08/2017
3
// Se instancia una Barra de Menu y se le añaden los Menus
MenuBar menuBar = new MenuBar();
menuBar.add( menuA );
menuBar.add( menuB );
// Se instancia un objeto Frame y se le asocia el objeto MenuBar.
// Observese que esta no es la tipico invocacion del metodo
// miFrame.add(), sino que es una forma especial de invocar
// al metodo necesaria para poder asociar un objeto Barra de Menu
// a un objeto Frame
Frame miFrame = new Frame( "Tutorial de Java, AWT" );
// Esto no es el metodo add(), como se podria esperar
miFrame.setMenuBar( menuBar );
miFrame.setSize( 250,100 );
miFrame.setVisible( true );
// Se instancia y registra un receptor de eventos de ventana para
// concluir el programa cuando se cierre el Farme
miFrame.addWindowListener( new Conclusion() );
}
}
// Clase para instanciar un objeto ActionListener que se registra
// sobre los elementos del menu
class MiGestorDeMenu implements ActionListener {
public void actionPerformed( ActionEvent evt ) {
// Presenta en pantalla el elemento que ha generado el evento
// de tipo Action
System.out.println( evt.getSource() );
}
}
class Conclusion extends WindowAdapter {
public void windowClosing( WindowEvent evt ) {
System.exit( 0 );
}
}
A continuación se revisan los fragmentos de código más interesantes del ejemplo, aunque en el programa
se puede observar que hay gran cantidad de código repetitivo, ya que esencialmente se necesitan las
mismas sentencias para crear cada opción del menú y registrar un objeto receptor de eventos sobre cada
una de ellas.
El programa genera dos menús separados con el mismo código básicamente. Quizá lo más interesante no
sea el código en sí mismo, sino el orden en que se realizan los diferentes pasos de la construcción del
menú.
La primera sentencia que merece la pena es la que instancia un objeto MenuShortcut, que se utilizará
posteriormente en la instanciación de un objeto MenuItem.
MenuShortcut miAcelerador = new MenuShortcut( KeyEvent.VK_K,true );
La lista de argumentos del constructor especifica la combinación de teclas que se van a utilizar y el
parámetro true, indica que es necesaria la tecla del cambio a mayúsculas (Shift) pulsada. El primer
parámetro es la constante simbólica que la clase KeyEvent define para la tecla K y, aparentemente, la
tecla Control siempre debe estar pulsada en este tipo de combinaciones para ser utilizadas las teclas
normales como aceleradores de teclado.
Cuando se utiliza este constructor, en el menú aparecerá la etiqueta asignada y a su derecha, la
combinación de teclas alternativas para activarla directamente.
Kena Puga Nathal
Página 4
09/08/2017
4
El siguiente fragmento de código que se puede ver es el típico de instanciación de objetos MenuItem,
que posteriormente se añadirán al objeto Menu para crear el menú. Se muestran dos tipos de
instrucciones, el primer estilo especifica un acelerador de teclado y el segundo no.
MenuItem primerElementoDeA = new MenuItem("Primer Elemento del Menu A",miAcelerador );
MenuItem segundoElementoDeA = new MenuItem("Segundo Elemento del Menu A" );
Ahora se encuentra el código que instancia y registra un objeto ActionListener sobre la opción del menú,
tal como se ha visto en ejemplos anteriores. Aquí solamente se incluye para ilustrar el hecho de que la
asociación de objetos ActionListener con opciones de un menú, no difiere en absoluto de la asociación
de objetos ActionListener con objetos Button, o cualquier otro tipo de objeto capaz de generar eventos
de tipo ActionEvent.
primerElementoDeA.addActionListener( new MiGestorDeMenu() );
Las sentencias que siguen son las ya vistas, y que aquí se emplean para instanciar cada uno de los dos
objetos Menu y añadirles las opciones existentes. Es la típica llamada al método Objeto.add() que se ha
utilizado en programas anteriores.
Menu menuA = new Menu( "Menu A" );
menuA.add( primerElementoDeA );
El siguiente fragmento de código instancia un objeto MenuBar y le añade los dos menús que se han
definido antes.
MenuBar menuBar = new MenuBar();
menuBar.add( menuA );
menuBar.add( menuB );
En este momento ya están creados los dos objetos Menu y colocados en un objeto MenuBar. Sin
embargo, no se ha dicho nada sobre el ensamblamiento del conjunto. Esto se hace en el momento de
asociar el objeto MenuBar con el objeto Frame. En este caso no se puede utilizar el método add(), sino
que se tiene que invocar a un método especial de la clase Frame que tiene la siguiente declaración:
public synchronized void setMenuBar( MenuBar mb )
y en este caso concreto se hace en las sentencias que se reproducen seguidamente:
Frame miFrame = new Frame( "Tutorial de Java, AWT" );
// Esto no es el metodo add(), como se podria esperar
miFrame.setMenuBar( menuBar );
Y hasta aquí lo más interesante del ejemplo, porque el código que resta es similar al que ya se ha visto y
descrito en otros ejemplos del Tutorial, y que el lector se habrá encontrado si ha seguido la lectura
secuencialmente.
Clase CheckboxMenuItem
Esta clase se utiliza para instanciar objetos que puedan utilizarse como opciones en un menú. Al contrario
que las opciones de menú que se han visto al hablar de objetos MenuItem, estas opciones tienen mucho
más parentesco con las cajas de selección, tal como se podrá comprobar a lo largo del ejemplo
java1318.java.
Esta clase proporciona tres constructores públicos, en donde se puede especificar el texto de la opción y el
estado en que se encuentra. Si no se indica nada, la opción estará deseleccionada, aunque hay un
constructor que permite indicar en un parámetro de tipo booleano, que la opción se encuentra
seleccionada, o marcada, indicando true en ese valor.
Constructores:
new CheckboxMenuItem();
new CheckboxMenuItem(“etiqueta”);
new CheckboxMenuItem(“etiqueta”, boolean); //true seleccionada la opción por omisión
Métodos:
Kena Puga Nathal
Página 5
09/08/2017
5
addItemListener( ItemListener );
getState(); //regresa true si esa opción esta seleccionada
setState(boolean); // true selecciona la opción
Cuando se selecciona una opción del menú, se genera un evento de tipo ItemEvent. Para que se produzca
la acción que se desea con esa selección, es necesario instanciar y registrar un objeto ItemListener que
contenga el método itemStateChanged() sobrescrito con la acción que se quiere. Por ejemplo, en el
programa que se presenta a continuación, la acción consistirá en presentar la identificación y estado de la
opción de menú que se haya seleccionado.
Cuando se ejecuta el programa java1318.java, aparece un menú sobre un objeto Frame. El menú contiene
tres opciones de tipo CheckboxMenuItem. Una opción de este tipo es semejante a cualquier otra, hasta
que se selecciona. Cuando se seleccione, aparecerá una marca, o cualquier otra identificación visual, para
saber que esa opción está seleccionada. Estas acciones hacen que el estado de la opción cambie, y ese
estado se puede conocer a través del método getState().
Cuando se selecciona una opción, se genera un evento de tipo ItemEvent, que contiene información del
nuevo estado, del texto de la opción y del nombre asignado a la opción. Estos datos pueden utilizarse para
identificar cuál de las opciones ha cambiado y, también, para implementar la acción requerida que, en este
caso del ejemplo siguiente, consiste en presentar una línea de texto en la pantalla con la información que
contiene el objeto ItemEvent, más o menos semejante a la que se reproduce a continuación:
% java java1318
java.awt.CheckboxMenuItem[chkmenuitem0,label=Primer Elemento,state=true]
java.awt.CheckboxMenuItem[chkmenuitem2,label=Terecer Elemento,state=true]
java.awt.CheckboxMenuItem[chkmenuitem0,label=Primer Elemento,state=false]
java.awt.CheckboxMenuItem[chkmenuitem1,label=Segundo Elemento,state=true]
java.awt.CheckboxMenuItem[chkmenuitem0,label=Primer Elemento,state=true]
Como siempre, se instancia y registra sobre el Frame un objeto receptor de eventos windowClosing()
para la conclusión del programa cuando se cierre el Frame.
import java.awt.*;
import java.awt.event.*;
public class java1318 {
public static void main( String args[] ) {
IHM ihm = new IHM();
}
}
class IHM {
public IHM() {
// Instancia objetos de tipo CheckboxMenuItem
CheckboxMenuItem primerElementoMenu = new CheckboxMenuItem( "Primer Elemento" );
CheckboxMenuItem segundoElementoMenu = new CheckboxMenuItem( "Segundo Elemento" );
CheckboxMenuItem tercerElementoMenu = new CheckboxMenuItem( "Tercer Elemento" );
// Instancia un objeto ItemListener y lo registra sobre los
// objetos CheckboxMenuItem, elementos del menu de seleccion
primerElementoMenu.addItemListener( new ControladorCheckBox() );
segundoElementoMenu.addItemListener( new ControladorCheckBox() );
tercerElementoMenu.addItemListener( new ControladorCheckBox() );
Kena Puga Nathal
Página 6
09/08/2017
6
// Instancia un objeto Menu y le añade los botones de la caja
// de seleccion
Menu menuA = new Menu( "Menu A" );
menuA.add( primerElementoMenu );
menuA.add( segundoElementoMenu );
menuA.add( tercerElementoMenu );
// Instancia un objeto MenuBar y le añade el objeto Menu
MenuBar barraMenu = new MenuBar();
barraMenu.add( menuA );
// Se instancia un objeto Frame y se le asocia el objeto MenuBar.
// Observese que esta no es la tipico invocacion del metodo
// miFrame.add(), sino que es una forma especial de invocar
// al metodo necesaria para poder asociar un objeto Barra de Menu
// a un objeto Frame
Frame miFrame = new Frame( "Tutorial de Java, AWT" );
// Esto no es el metodo add(), como se podria esperar
miFrame.setMenuBar( barraMenu );
miFrame.setSize( 250,100 );
miFrame.setVisible( true );
// Instancia y registra un receptor de eventos de ventana para
// concluir la ejecucion del programa cuando se cierra el Frame
miFrame.addWindowListener( new Conclusion() );
}
}
// Clase para instanciar un objeto ItemListener y registrarlo
// sobre los elementos del menu
class ControladorCheckBox implements ItemListener {
public void itemStateChanged( ItemEvent evt ) {
// Presenta en pantalla el elemento del menu que ha
// generado el evento
System.out.println( evt.getSource() );
}
}
class Conclusion extends WindowAdapter {
public void windowClosing( WindowEvent evt ) {
// Termina el programa cuando se cierra la ventana
System.exit( 0 );
}
}
Hay algunos trozos de código en el programa que resultan repetitivos, debido al hecho de que se utiliza
básicamente el mismo código para crear cada elemento del menú y registrar un objeto Listener sobre él.
El orden en que se instancian y asocian las opciones es importante. La primera sentencia de código
interesante es la que se utiliza para instanciar varios objetos CheckboxMenuItem que serán añadidos al
objeto Menu para producir un menú con varias opciones.
CheckboxMenuItem primerElementoMenu = new CheckboxMenuItem( "Primer Elemento" );
La sentencia que se reproduce ahora es interesante solamente por lo que tiene de novedad, porque hace
uso de un tipo de clase Listener que no se ha visto antes. La sentencia, por otro lado, es la típica que se
requiere para instanciar y registrar objetos ItemListener sobre cada CheckboxMenuItem.
primerElementoMenu.addItemListener( new ControladorCheckBox() );
A continuación se encuentra el código que instancia un objeto Menu y le añade los objetos
CheckboxMenuItem, que es semejante al utilizado en los menús normales. El siguiente código
interesante corresponde a la clase que implementa el interfaz ItemListener, que vuelve a resultar
interesante por lo novedoso.
Kena Puga Nathal
Página 7
09/08/2017
7
class ControladorCheckBox implements ItemListener {
public void itemStateChanged( ItemEvent evt ) {
// Presenta en pantalla el elemento del menu que ha
// generado el evento
System.out.println( evt.getSource() );
}
}
Y el resto del programa es similar al de ejemplos anteriores, así que no se vuelve más sobre él.
Clase PopupMenu
Esta clase se utiliza para instanciar objetos que funcionan como menús emergentes o pop-up. Una vez que
el menú aparece en pantalla, el procesado de las opciones es el mismo que en el caso de los menús de
persiana.
Esta clase proporciona un par de constructores y un par de métodos, de los cuales el más interesante es el
método show(), que permite mostrar el menú emergente en una posición relativa al Componente origen.
Este Componente origen debe estar contenido dentro de la jerarquía de padres de la clase PopupMenu.
Constructores:
new PopupMenu();
new PopupMenu(“etiqueta”);
Métodos:
show(contenedor, x, y); //muestra el menú pero para ello debe conocer el contenedor donde se va a
//mostrar y las posiciones sobre las cuales se visualizará
Para el manejo de este tipo de menús, en necesario también manejar eventos del ratón de manera que se
puedan obtener las coordenadas sobre las cuales se presentará el menú.
El programa siguiente, java1319.java, coloca un objeto PopupMenu sobre un objeto Frame. El menú
contiene tres opciones de tipo CheckboxMenuItem, y aparece cuando se pica dentro del Frame,
posicionando su esquina superior-izquierda en la posición en que se encontraba el ratón en el momento de
pulsar el botón.
El resto del funcionamiento es semejante al de los programas de ejemplo vistos en secciones anteriores
import java.awt.*;
import java.awt.event.*;
public class java1319 {
public static void main( String args[] ) {
IHM ihm = new IHM();
}
}
class IHM {
public IHM() {
// Instancia objetos CheckboxMenuItem
CheckboxMenuItem primerElementoMenu = new CheckboxMenuItem( "Primer Elemento" );
CheckboxMenuItem segundoElementoMenu = new CheckboxMenuItem( "Segundo Elemento" );
CheckboxMenuItem tercerElementoMenu = new CheckboxMenuItem( "Tercer Elemento" );
// Se instancia un objeto ItemListener y se registra sobre los
Kena Puga Nathal
Página 8
09/08/2017
8
// elementos de menu ya instanciados
primerElementoMenu.addItemListener( new ControladorCheckBox() );
segundoElementoMenu.addItemListener( new ControladorCheckBox() );
tercerElementoMenu.addItemListener( new ControladorCheckBox() );
// Instancia un objeto Menu de tipo PopUp y le añade los objetos
// CheckboxMenuItem
PopupMenu miMenuPopup = new PopupMenu( "Menu Popup" );
miMenuPopup.add( primerElementoMenu );
miMenuPopup.add( segundoElementoMenu );
miMenuPopup.add( tercerElementoMenu );
Frame miFrame = new Frame( "Tutorial de Java, AWT" );
miFrame.addMouseListener( new ControladorRaton(miFrame,miMenuPopup) );
// Aquí está la diferencia con los Menus de Barra
miFrame.add( miMenuPopup );
miFrame.setSize( 250,100 );
miFrame.setVisible( true );
// Instancia y registra un receptor de eventos de ventana para
// terminar el programa cuando se cierra el Frame
miFrame.addWindowListener( new Conclusion() );
}
}
// Clase para atrapar los eventos de pulsacion del raton y presentar
// en la pantalla el objeto menu Popup, en la posicion en que se
// encontraba el cursor
class ControladorRaton extends MouseAdapter{
Frame aFrame;
PopupMenu aMenuPopup;
// Constructor parametrizado
ControladorRaton( Frame frame,PopupMenu menuPopup ) {
aFrame = frame;
aMenuPopup = menuPopup;
}
public void mousePressed( MouseEvent evt ) {
// Presenta el menu PopUp sobre el Frame que se especifique
// y en las coordenadas determinadas por el click del raton,
// cuidando de que las coordenadas no se encuentren situadas
// sobre la barra de titulo, porque las coordenadas Y en
// esta zona son negativas
if( evt.getY() > 0 )
aMenuPopup.show( aFrame,evt.getX(),evt.getY() );
}
}
// Clase para instanciar un objeto receptor de eventos de los
// elementos del menu que sera registrado sobre estos elementos
class ControladorCheckBox implements ItemListener {
public void itemStateChanged( ItemEvent evt ) {
// Presenta en pantalla el elemento que ha generado el
// evento
System.out.println( evt.getSource() );
}
}
class Conclusion extends WindowAdapter {
public void windowClosing( WindowEvent evt ) {
// termina el programa cuando se cierra la ventana
System.exit( 0 );
}
Kena Puga Nathal
Página 9
09/08/2017
9
}
El programa es muy similar al de la sección anterior en que se utilizaban objetos CheckboxMenuItem en
un menú de persiana normal, así que solamente se verá el código que afecta al uso del objeto
PopupMenu.
El primer fragmento de código interesante es el que instancia un objeto PopupMenu y le incorpora tres
objetos CheckboxMenuItem.
PopupMenu miMenuPopup = new PopupMenu( "Menu Popup" );
miMenuPopup.add( primerElementoMenu );
miMenuPopup.add( segundoElementoMenu );
miMenuPopup.add( tercerElementoMenu );
El siguiente trozo de código es interesante porque el procedimiento en el caso de asociar un objeto
PopupMenu con el objeto Frame, es diferente a cuando se utiliza un objeto MenuBar. En el caso de la
barra de menú, se utiliza la llamada al método setMenuBar(), mientras que para asociar un menú
emergente a un objeto Frame, se utiliza la típica llamada de la forma Objeto.add(), que es el método
habitual de añadir muchos otros Componentes a un Contenedor.
Frame miFrame = new Frame( "Tutorial de Java, AWT" );
miFrame.addMouseListener( new ControladorRaton(miFrame,miMenuPopup) );
// Aquí está la diferencia con los Menus de Barra
miFrame.add( miMenuPopup );
El siguiente trozo de código interesante es el método sobrescrito mousePressed(), del interfaz
MouseListener, encapsulado aquí en la clase ControladorRaton. El propósito de esta clase es instanciar
un objeto receptor que atrapará eventos de pulsación del ratón sobre el objeto Frame, y mostrará el objeto
PopupMenu en la posición en que se encuentre el cursor del ratón en el momento de producirse el
evento.
public void mousePressed( MouseEvent evt ) {
// Presenta el menu PopUp sobre el Frame que se especifique
// y en las coordenadas determinadas por el click del raton,
// cuidando de que las coordenadas no se encuentren situadas
// sobre la barra de titulo, porque las coordenadas Y en
// esta zona son negativas
if( evt.getY() > 0 )
aMenuPopup.show( aFrame,evt.getX(),evt.getY() );
}
Como se puede observar, es lo típico, excepto el uso del método show() de la clase PopupMenu.
También se debe notar la referencia al objeto PopupMenu y otra al objeto Frame, que se pasan cuando
se instancia el objeto. Estas dos referencias son necesarias para la invocación del método show(), tal como
se muestra en el código anterior. La referencia al objeto Frame se utiliza para establecer la posición en
donde aparecerá el menú, y la referencia al objeto PopupMenu especifica el menú que se debe mostrar.
Otros ejemplos del manejo de menús:
import java.awt.*;
import java.awt.event.*;
public class ejem_menu extends Frame
{//creo barra de menus
MenuBar barra=new MenuBar();
//creo menus
Menu subm1=new Menu("menu1");
Menu subm2=new Menu("menu2");
Menu subm3=new Menu("menu3");
Menu subm4=new Menu ("submenu");
//creo opciones del menu
MenuItem op1=new MenuItem("op1");
Kena Puga Nathal
Página 10
09/08/2017
10
MenuItem op2=new MenuItem("op2");
MenuItem op3=new MenuItem("op3");
MenuItem op4=new MenuItem("op4");
MenuItem op5=new MenuItem("op5");
MenuItem op6=new MenuItem("op6");
MenuItem op7=new MenuItem("op7");
MenuItem op8=new MenuItem("op8");
MenuItem op9=new MenuItem("op9");
MenuItem op10=new MenuItem("op10");
MenuItem op11=new MenuItem("op11");
CheckboxMenuItem op12 = new CheckboxMenuItem("casilla de seleccion");
public ejem_menu()
{//agrego las opciones a cada menú, construyo cada menu
subm1.add(op1);
subm1.add(op2);
subm2.add(op3);
subm2.add(op4);
subm2.addSeparator(); // se agrega una linea de separacion en el menu 2
subm2.add(op5);
subm2.add(op6);
subm2.add(op7);
subm3.add(op8);
subm3.add(op9);
subm3.addSeparator();// se agrega una linea de separacion en el menu 3
subm4.add(op10);
subm4.add(op11);
subm4.addSeparator();// se agrega una linea de separacion en el menu 4
subm4.add(op12);
subm4.addSeparator();// se agrega una linea de separacion en el menu 4
subm3.add(subm4);
//construyo la barra de menús
barra.add(subm1);
barra.add(subm2);
barra.add(subm3);
//agrego la barra de menús al frame
setMenuBar(barra);
this.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e)
{System.exit(0);}});
}
public static void main(String arg[])
{ejem_menu em=new ejem_menu();
em.setSize(400,400);
em.setVisible(true);
}
}
*+*+*+*+*
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class emergente extends Applet implements ActionListener, MouseListener
{Label label;
PopupMenu pop=new PopupMenu("Menu emergente");
MenuItem op1=new MenuItem("opcion1");
MenuItem op2=new MenuItem("opcion2");
MenuItem op3=new MenuItem("opcion3");
MenuItem op4=new MenuItem("opcion4");
public void init()
{op1.addActionListener(this);
Kena Puga Nathal
Página 11
09/08/2017
11
op2.addActionListener(this);
op3.addActionListener(this);
op4.addActionListener(this);
pop.add(op1);
pop.addSeparator();
pop.add(op2);
pop.addSeparator();
pop.add(op3);
pop.addSeparator();
pop.add(op4);
pop.addSeparator();
add(pop);
label=new Label("hola hola!!!!");
add(label);
/* addMouseListener(new MouseAdapter() {public void mousePressed(MouseEvent e) {if
(e.getModifiers()!=0)
{pop.show(this,e.getX(),e.getY());} } });
*/
addMouseListener(this);
/* addWindowListener(new WindowAdapter () {public void windowClosing(WindowEvent e) {
setVisible(false);
System.exit(0);
} });
*/
}
public void mousePressed(MouseEvent e)
{if (e.getModifiers()!=0)
{pop.show(this,e.getX(),e.getY());}
}
public void mouseClicked(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void actionPerformed(ActionEvent e)
{if (e.getSource()==op1) label.setText("eligio opcion 1");
else if (e.getSource()==op2)
label.setText("se eligio opcion2");
else if (e.getSource()==op3)
label.setText("se eligio opcion3");
else if (e.getSource()==op4)
label.setText("se eligio opcion4");
}
/* public static void main(String arg [])
{emergente emer=new emergente();
emer.setSize(300,300);
emer.setVisible(true);
}
*/
}
/*
<html>
<applet code="emergente.class" width=500 height=400>
</applet>
</html>
*/
*+*+*+*+*
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
public class ejemMenu1 extends Frame implements ActionListener, ItemListener
{Color c;
CheckboxMenuItem esm_1=new CheckboxMenuItem("rojo");
CheckboxMenuItem esm_2=new CheckboxMenuItem("verde");
CheckboxMenuItem esm_3=new CheckboxMenuItem("azul");
Kena Puga Nathal
Página 12
09/08/2017
12
MenuItem em2_1=new MenuItem("opcion 21");
MenuItem em2_2=new MenuItem("opcion 22");
public ejemMenu1()
{setLayout(new FlowLayout());
MenuBar mb=new MenuBar();
Menu m1=new Menu("Menu 1");
Menu m2=new Menu("Menu 2");
Menu sm=new Menu("Submenu");
MenuItem em1_1=new MenuItem("opcion 1");
MenuItem em1_2=new MenuItem("opcion 2");
MenuItem em1_3=new MenuItem("opcion 3",new MenuShortcut(KeyEvent.VK_O, false));
em1_1.addActionListener(this);
em1_2.addActionListener(this);
em1_3.addActionListener(this);
em2_1.addActionListener(this);
em2_2.addActionListener(this);
esm_1.addItemListener(this);
esm_2.addItemListener(this);
esm_3.addItemListener(this);
setMenuBar(mb);
mb.add(m1);
mb.add(m2);
m1.add(em1_1);
m1.add(em1_2);
m1.add(em1_3);
m1.addSeparator();
m1.add(sm);
sm.add(esm_1);
sm.add(esm_2);
sm.add(esm_3);
m2.add(em2_1);
m2.add(em2_2);
em2_1.setEnabled(false);
}
public void actionPerformed(ActionEvent e)
{if ((String)e.getActionCommand()=="opcion 1")
{try{(Runtime.getRuntime()).exec("notepad.exe");}
catch(IOException ee){}
}else
if ((String)e.getActionCommand()=="opcion 2")
{try{(Runtime.getRuntime()).exec("java ejemMenu1");}
catch(IOException ee){}
}else
if ((String)e.getActionCommand()=="opcion 3")
{System.exit(0);}else
if ((String)e.getActionCommand()=="opcion 21")
{em2_1.setEnabled(false);
em2_2.setEnabled(true);
}else
if ((String)e.getActionCommand()=="opcion 22")
{em2_2.setEnabled(false);
em2_1.setEnabled(true);
}
}
public void itemStateChanged(ItemEvent e)
{if(e.getSource()==esm_1)
{if (esm_1.getState())
{c=new Color((int)(Math.random()*256),0,0);
esm_2.setState(false);
Kena Puga Nathal
Página 13
09/08/2017
13
esm_3.setState(false);
}} else
if(e.getSource()==esm_2)
{if(esm_2.getState())
{c=new Color(0,(int)(Math.random()*256),0);
esm_1.setState(false);
esm_3.setState(false);
}} else
if(e.getSource()==esm_3)
{if(esm_3.getState())
{c=new Color(0,0,(int)(Math.random()*256));
esm_1.setState(false);
esm_2.setState(false);
}}
repaint();
}
public void paint(Graphics g)
{g.setColor(c);
g.fillOval(20,200,50,50);
}
public static void main(String arg[])
{ejemMenu1 eje=new ejemMenu1();
eje.setSize(500,500);
eje.setVisible(true);
eje.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent
e){System.exit(0);}});
}
}
*+*+*+*+*+*+*+*
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
public class ejemMenu2 extends Frame implements ActionListener//, MouseListener
{ PopupMenu m1=new PopupMenu("Menu 1");
public ejemMenu2()
{setLayout(new FlowLayout());
Menu sm=new Menu("Submenu");
MenuItem em1_1=new MenuItem("opcion 1");
MenuItem em1_2=new MenuItem("opcion 2");
MenuItem em1_3=new MenuItem("opcion 3",new MenuShortcut(KeyEvent.VK_O, false));
em1_1.addActionListener(this);
em1_2.addActionListener(this);
em1_3.addActionListener(this);
m1.add(em1_1);
m1.add(em1_2);
m1.addSeparator();
sm.add(em1_3);
m1.add(sm);
add(m1);
setFont(new Font("",0,24));
add((new Label("ejemplo de un menu emergente")));
// addMouseListener(this);
addMouseListener(new Posicion(this,m1));
}
public void actionPerformed(ActionEvent e)
{if ((String)e.getActionCommand()=="opcion 1")
{try{(Runtime.getRuntime()).exec("notepad.exe");}
catch(IOException ee){}
Kena Puga Nathal
Página 14
09/08/2017
14
}else
if ((String)e.getActionCommand()=="opcion 2")
{try{(Runtime.getRuntime()).exec("java ejemMenu1");}
catch(IOException ee){}
}else
if ((String)e.getActionCommand()=="opcion 3")
{System.exit(0);}//else
}
/* public void mousePressed(MouseEvent e)
{m1.show(this,e.getX(),e.getY());}
public void mouseExited(MouseEvent e)
{}
public void mouseReleased(MouseEvent e)
{}
public void mouseEntered(MouseEvent e)
{}
public void mouseClicked(MouseEvent e)
{}
*/
public static void main(String arg[])
{ejemMenu2 eje=new ejemMenu2();
eje.setSize(500,500);
eje.setVisible(true);
eje.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent
e){System.exit(0);}});
}
class Posicion extends MouseAdapter
{private Frame f;
private PopupMenu pm;
public Posicion(Frame f, PopupMenu pm)
{this.f=f;
this.pm=pm;
}
public void mousePressed(MouseEvent e)
{pm.show(f,e.getX(),e.getY());}
}
}
*+*+*+*+*+*+*+*+*
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
public class ejemMenu3 extends Frame implements ActionListener, MouseListener
{PopupMenu m1=new PopupMenu("Menu 1");
public ejemMenu3()
{setLayout(new FlowLayout());
Menu sm=new Menu("Submenu");
MenuItem em1_1=new MenuItem("opcion 1");
MenuItem em1_2=new MenuItem("opcion 2");
MenuItem em1_3=new MenuItem("opcion 3",new MenuShortcut(KeyEvent.VK_O, false));
em1_1.addActionListener(this);
em1_2.addActionListener(this);
em1_3.addActionListener(this);
m1.add(em1_1);
m1.add(em1_2);
m1.addSeparator();
sm.add(em1_3);
m1.add(sm);
add(m1);
setFont(new Font("",0,24));
Kena Puga Nathal
Página 15
09/08/2017
15
add((new Label("ejemplo de un menu emergente")));
addMouseListener(this);
// addMouseListener(new Posicion(this,m1));
}
public void actionPerformed(ActionEvent e)
{if ((String)e.getActionCommand()=="opcion 1")
{try{(Runtime.getRuntime()).exec("notepad.exe");}
catch(IOException ee){}
}else
if ((String)e.getActionCommand()=="opcion 2")
{try{(Runtime.getRuntime()).exec("java ejemMenu1");}
catch(IOException ee){}
}else
if ((String)e.getActionCommand()=="opcion 3")
{System.exit(0);}
}
public void mousePressed(MouseEvent e)
{m1.show(this,e.getX(),e.getY());}
public void mouseExited(MouseEvent e)
{}
public void mouseReleased(MouseEvent e)
{}
public void mouseEntered(MouseEvent e)
{}
public void mouseClicked(MouseEvent e)
{}
public static void main(String arg[])
{ejemMenu2 eje=new ejemMenu2();
eje.setSize(500,500);
eje.setVisible(true);
eje.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent
e){System.exit(0);}});
}
/* class Posicion extends MouseAdapter
{private Frame f;
private PopupMenu pm;
public Posicion(Frame f, PopupMenu pm)
{this.f=f;
this.pm=pm;
}
public void mousePressed(MouseEvent e)
{pm.show(f,e.getX(),e.getY());}
}
*/
}
*+*+*+*+*+*+*+*+*
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
public class ejemMenu5 extends Frame implements ActionListener
{PopupMenu m1=new PopupMenu("Menu 1");
PopupMenu sm=new PopupMenu("Menu 2");
MenuItem em1_1=new MenuItem("Bloc de notas");
MenuItem em1_2=new MenuItem("Menu 1");
MenuItem em1_3=new MenuItem("Salir",new MenuShortcut(KeyEvent.VK_S, false));
public ejemMenu5()
{setLayout(new FlowLayout());
em1_1.addActionListener(this);
em1_2.addActionListener(this);
Kena Puga Nathal
Página 16
09/08/2017
16
em1_3.addActionListener(this);
m1.add(em1_1);
m1.addSeparator();
m1.add(em1_2);
sm.add(em1_3);
add(sm);
add(m1);
setFont(new Font("",0,24));
add((new Label("ejemplo de un menu emergente")));
addMouseListener(new Posicion(this,m1));
addMouseListener(new Posicion(this,sm));
}
public void actionPerformed(ActionEvent e)
{if (e.getSource()==em1_1)
{try{(Runtime.getRuntime()).exec("notepad.exe");}
catch(IOException ee){}
}else
if (e.getSource()==em1_2)
{try{(Runtime.getRuntime()).exec("java ejemMenu1");}
catch(IOException ee){}
}else
if (e.getSource()==em1_3)
{System.exit(0);}
}
public static void main(String arg[])
{ejemMenu5 eje=new ejemMenu5();
eje.setSize(500,500);
eje.setVisible(true);
eje.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent
e){System.exit(0);}});
}
class Posicion extends MouseAdapter
{private Frame f;
private PopupMenu pm;
public Posicion(Frame f, PopupMenu pm)
{this.f=f;
this.pm=pm;
}
public void mousePressed(MouseEvent e)
{//System.out.println(e.getButton());
if(((pm.getLabel().equals("Menu
1"))&&(e.getButton()==MouseEvent.BUTTON1))||((pm.getLabel().equals("Menu
2"))&&(e.getButton()==MouseEvent.BUTTON3)))
{pm.show(f,e.getX(),e.getY());}
}
}
}
*+*+*+*+*+*+*+*+*+*+*+*
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class ejemMenu4 extends Frame implements ActionListener, ItemListener
{Color c;
Button b1;
Button b2;
Button b3;
CheckboxMenuItem esm_1=new CheckboxMenuItem("rojo");
CheckboxMenuItem esm_2=new CheckboxMenuItem("verde");
CheckboxMenuItem esm_3=new CheckboxMenuItem("azul");
Kena Puga Nathal
Página 17
09/08/2017
17
PopupMenu emergente=new PopupMenu("Menu emergente");
MenuItem em2_1=new MenuItem("opcion 21");
MenuItem em2_2=new MenuItem("opcion 22");
public ejemMenu4()
{setLayout(new FlowLayout());
MenuBar mb=new MenuBar();
Menu m1=new Menu("Menu 1");
Menu m2=new Menu("Menu 2");
Menu sm=new Menu("Submenu");
MenuItem em1_1=new MenuItem("opcion 1");
MenuItem em1_2=new MenuItem("opcion 2");
MenuItem em1_3=new MenuItem("opcion 3",new MenuShortcut(KeyEvent.VK_O, false));
b1=new Button("Opcion 1");
b2=new Button("Opcion 2");
b3=new Button("Opcion 3");
em1_1.addActionListener(this);
em1_2.addActionListener(this);
em1_3.addActionListener(this);
em2_1.addActionListener(this);
em2_2.addActionListener(this);
esm_1.addItemListener(this);
esm_2.addItemListener(this);
esm_3.addItemListener(this);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
setMenuBar(mb);
mb.add(m1);
mb.add(m2);
m1.add(em1_1);
m1.add(em1_2);
m1.add(em1_3);
m1.addSeparator();
m1.add(sm);
sm.add(esm_1);
sm.add(esm_2);
sm.add(esm_3);
m2.add(em2_1);
m2.add(em2_2);
em2_1.setEnabled(false);
emergente.add(m1);
emergente.addSeparator();
emergente.add(em2_1);
emergente.add(em2_2);
add(emergente);
addMouseListener(new Posicion(this, emergente));
add(b1);
add(b2);
add(b3);
}
public void actionPerformed(ActionEvent e)
{if ((String)e.getActionCommand()=="opcion 1" || e.getSource()==b1)
{try{(Runtime.getRuntime()).exec("C:\\Archivos de programa\\Internet Explorer\\Iexplore.exe "+new
URL("file:"+(new File("CGraficos.html")).getAbsolutePath()));}
catch(IOException ee){}
}else
if ((String)e.getActionCommand()=="opcion 2" || e.getSource()==b2)
{try{(Runtime.getRuntime()).exec("animacion1");}
catch(IOException ee){}
}else
Kena Puga Nathal
Página 18
09/08/2017
18
if ((String)e.getActionCommand()=="opcion 3" || e.getSource()==b3)
{System.exit(0);}else
if ((String)e.getActionCommand()=="opcion 21")
{em2_1.setEnabled(false);
em2_2.setEnabled(true);
}else
if ((String)e.getActionCommand()=="opcion 22")
{em2_2.setEnabled(false);
em2_1.setEnabled(true);
}
}
public void itemStateChanged(ItemEvent e)
{if(e.getSource()==esm_1)
{if (esm_1.getState())
{c=new Color((int)(Math.random()*256),0,0);
esm_2.setState(false);
esm_3.setState(false);
}} else
if(e.getSource()==esm_2)
{if(esm_2.getState())
{c=new Color(0,(int)(Math.random()*256),0);
esm_1.setState(false);
esm_3.setState(false);
}} else
if(e.getSource()==esm_3)
{if(esm_3.getState())
{c=new Color(0,0,(int)(Math.random()*256));
esm_1.setState(false);
esm_2.setState(false);
}}
repaint();
}
public void paint(Graphics g)
{g.setColor(c);
g.fillOval(20,200,50,50);
}
public static void main(String arg[])
{ejemMenu4 eje=new ejemMenu4();
eje.setSize(500,500);
eje.setVisible(true);
eje.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent
e){System.exit(0);}});
}
}
class Posicion extends MouseAdapter
{private Frame f;
private PopupMenu pm;
public Posicion(Frame f, PopupMenu pm)
{this.f=f;
this.pm=pm;
}
public void mousePressed(MouseEvent e)
{pm.show(f,e.getX(),e.getY());}
}
Informacion tomada del tutorial de la pagina: http://dis.um.es/~bmoros/Tutorial/parte13/cap13-6.html
Kena Puga Nathal
Página 19
09/08/2017
19