El código fuente está aquí.
El siguiente diagrama sirve para comprender mejor el ejemplo
El main de la aplicación sigue el patrón que utiliza la herramienta IBM Visual Age for Java 3.5:
public static void main(java.lang.String[] args) { Edit aplication = new Edit("Editor simple"); aplication.initialize(); aplication.initConnections(); aplication.pack(); aplication.setSize(500, 400); aplication.setLocation(100, 100); aplication.setVisible(true); }
public void initialize() { //Define que el Layout del contenedor sea de tipo BorderLayout this.getContentPane().setLayout(new BorderLayout()); // Clase anonima para que la aplicacion se cierre al apretar la X (boton esquina superior derecha) this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { if (!isSaved && !editPane.getText().equals("")) askSave(); System.exit(0); } }); /*****JMenuBar*****/ menuBar = new JMenuBar(); fileMenu = new JMenu("Archivo"); newMenu = new JMenuItem("Nuevo"); openMenu = new JMenuItem("Abrir"); saveMenu = new JMenuItem("Guardar"); exitMenu = new JMenuItem("Salir"); //Agrega los items al menu fileMenu.add(newMenu); fileMenu.add(openMenu); fileMenu.add(saveMenu); fileMenu.addSeparator(); fileMenu.add(exitMenu); //Agrega el menu a la barra de menu menuBar.add(fileMenu); //Setea esa bara de menu para el frame this.setJMenuBar(menuBar); /*****JToolBar*****/ toolBar = new JToolBar(); //Crea los botones asignando sendas imágenes y los agrega al toolbar openButton = new JButton(); openButton.setIcon(new ImageIcon(getClass().getResource("/open.gif"))); openButton.setMargin(new Insets(0, 0, 0, 0)); toolBar.add(openButton); saveButton = new JButton(); saveButton.setIcon(new ImageIcon(getClass().getResource("/save.gif"))); saveButton.setMargin(new Insets(0, 0, 0, 0)); toolBar.add(saveButton); //agrega un separador en la toolbar toolBar.addSeparator(); copyButton = new JButton(); copyButton.setIcon(new ImageIcon(getClass().getResource("/copy.gif"))); copyButton.setMargin(new Insets(0, 0, 0, 0)); toolBar.add(copyButton); cutButton = new javax.swing.JButton(); cutButton.setIcon(new ImageIcon(getClass().getResource("/cut.gif"))); cutButton.setMargin(new Insets(0, 0, 0, 0)); toolBar.add(cutButton); pasteButton = new javax.swing.JButton(); pasteButton.setIcon(new ImageIcon(getClass().getResource("/paste.gif"))); pasteButton.setMargin(new Insets(0, 0, 0, 0)); toolBar.add(pasteButton); //Agrega el toolbar en el norte del contenedor this.getContentPane().add(toolBar, BorderLayout.NORTH); /*****Status bar*****/ statusPanel = new JPanel(); statusPanel.setLayout(new BorderLayout()); //crea las etiquetas para la barra de estado statusMsg1 = new JLabel("Estado: "); statusMsg2 = new JLabel(); statusPanel.add(statusMsg1, BorderLayout.WEST); statusPanel.add(statusMsg2, BorderLayout.CENTER); //Agrega el panel de satus al sur del contenedor this.getContentPane().add(statusPanel, BorderLayout.SOUTH); /*****Text Editor*****/ editPane = new JEditorPane(); editPane.setText(""); scrollPaneRight = new JScrollPane(editPane); /*****List*****/ list=new JList(); scrollPaneLeft=new JScrollPane(list); openSelectedButton=new JButton("Abrir"); /*****leftPanel*****/ leftPanel=new JPanel(new BorderLayout()); leftPanel.add(scrollPaneLeft,BorderLayout.CENTER); leftPanel.add(openSelectedButton,BorderLayout.SOUTH); /*****Split Panel*****/ //Define un contenedor con division izq-der splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); splitPane.setRightComponent(scrollPaneRight); splitPane.setLeftComponent(leftPanel); this.getContentPane().add(splitPane, BorderLayout.CENTER); }
public void initConnections() { //se suscriben todas las componentes que quieren escuchar los eventos newMenu.addActionListener(eventHandler); openMenu.addActionListener(eventHandler); saveMenu.addActionListener(eventHandler); exitMenu.addActionListener(eventHandler); openButton.addActionListener(eventHandler); saveButton.addActionListener(eventHandler); copyButton.addActionListener(eventHandler); cutButton.addActionListener(eventHandler); pasteButton.addActionListener(eventHandler); openSelectedButton.addActionListener(eventHandler); }
En la clase Edit se define la clase interna EventHandler que implementa java.awt.event.ActionListener
Cuando se gatilla un evento, se le pregunta el source, es decir, en qué componente se generó, y dependiendo de la respuesta se ejecuta la acción correspondiente.
... class EventHandler implements ActionListener { public void actionPerformed(ActionEvent e) { //Si se elige salir en el menu if (e.getSource() == exitMenu) { //Si el archivo abierto no esta en blanco y no esta guardado if (!isSaved && !editPane.getText().equals("")) askSave(); System.exit(0); } //Si se elige abrir un archivo en el menu o con el boton de abrir en el toolbar if (e.getSource() == openMenu || e.getSource() == openButton) { if (!isSaved && !editPane.getText().equals("")) askSave(); openFile(); } //Si se elige en el menu editar un archivo en blanco if (e.getSource() == newMenu) { if (!isSaved && !editPane.getText().equals("")) askSave(); newFile(); } //Si se elige guardar en el menu o en el toolbar if (e.getSource() == saveMenu || e.getSource() == saveButton) saveFile(); //copy if (e.getSource() == copyButton) editPane.copy(); //cut if (e.getSource() == cutButton) editPane.cut(); //paste if (e.getSource() == pasteButton) editPane.paste(); //Si se elige el boton abrir la lista del lado izquierdo if (e.getSource() == openSelectedButton) openSelectedFile(); }; }; //se crea un objeto ActionListener que capturará todos los eventos de tipo acción ActionListener eventHandler = new EventHandler(); ...
Al invocar el método openFile() se ejecuta el siguiente código:
public void openFile() { //Si no existe el file chooser, crea uno if (fileChooser == null) { fileChooser = new JFileChooser(); } //Valor que retorna al elegir una opcion en el file chooser int retVal = fileChooser.showOpenDialog(this); //Si se escogio Ok, (o abrir) if (retVal == fileChooser.APPROVE_OPTION) { //El path absoluto del archivo elegido fileName = fileChooser.getSelectedFile().getAbsolutePath(); try { //Pasa el nombre del archivo a URL java.net.URL url = fileChooser.getSelectedFile().toURL(); statusMsg2.setText("abriendo " + fileName); //Abre el archivo elegido en el panel de texto editPane.setPage(url); isSaved = false; //Se agrega el archivo abierto a la lista de la izquierda agregaLista("" + fileName); } catch (Exception ioe) { statusMsg2.setText(ioe.getMessage()); } } }
El método saveFile() es similar, abriendo, en vez de un diálogo de apertura de archivos uno de guardado
public void saveFile() { //Si no existe, crea uno if (fileChooser == null) { fileChooser = new JFileChooser(); } //Abre un diálogo de guardado de archivos int retVal = fileChooser.showSaveDialog(this); if (retVal == fileChooser.APPROVE_OPTION) { fileName = fileChooser.getSelectedFile().getAbsolutePath(); try { statusMsg2.setText("Guardando "+fileName); //Toma el texto que hay en el panel de texto String text=editPane.getText(); java.io.FileWriter fileWriter=new java.io.FileWriter(fileName); java.io.BufferedWriter br = new java.io.BufferedWriter(fileWriter); br.write(text); br.close(); isSaved=true; //Agrega el archivo a la lista de la izquierda agregaLista(""+fileName); } catch (Exception ioe) { statusMsg2.setText(ioe.getMessage()); } } }
El método agregaLista(String fileName) agrega una archivo a la lista de archivos abiertos
public void agregaLista(String file) { if (fileVector.contains(file)) return; fileVector.add(file); Collections.sort(fileVector); list.setListData(fileVector); }
Y el método askSave() abre una ventana modal que le pregunta al usuario si quiere guardar el archivo abierto (se llama cuando el usuario no ha grabado el archivo y quiere abrir otro, cerrar la aplicación o escribir uno nuevo.
public void askSave() { //Componente que muestra ventanas de opciones JOptionPane optionPane=new JOptionPane(); Object[] opciones={"Sí","No"}; //Dialogo modal SI_NO int ret=optionPane.showOptionDialog(this,"Desea guardar? ","Pregunta",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null,opciones,opciones[0]); //Si la opcion escogida es Si if(ret==JOptionPane.YES_OPTION) saveFile(); }
Para compilar y probar el ejemplo se debe tener la JDK1.2+ y seguir los siguientes pasos
El código fuente está aquí