GilgaLab

13Sep/0910

Construindo um editor de texto com Java + Swing – Parte 1

É, eu sei que faz tempo que não escrevo. Faltou paciência/tempo/paciência/inspiração/paciência e por ai vai...
Bom, estou de volta e atualmente brincando um pouco com Java para construir GUIs (Graphical User Interfaces). Num tutorial que terá sabe-se lá quantas partes vou abordar como criar um editor de texto simples em Java. Esse editor de texto se propõe (pelo menos por enquanto) a possuir as seguintes funcionalidades:

  • Edição de arquivos em abas
  • Salvar documentos
  • Copiar texto através de um menu
  • Colar texto através de um menu
  • Mostrar uma caixinha de "Sobre o Editor"

É possível que conforme eu vá mexendo no editor e aprendendo truques novos eu adicione coisas novas.
Nessa primeira parte do tutorial irei mostrar os seguintes conceitos:

  • Como criar uma janela com Swing
  • Como adicionar componentes a janela
  • Como criar um menu para a janela
  • Como tratar eventos no seu menu
  • Como criar um painel com abas

Wow! Não imaginei que eram tantos assuntos hehehe. Bom, a intenção aqui é de ser mais um guia e não uma referência completa. Conforme discuto cada assunto, colocarei informações básicas e links apontando para lugares onde pode-se obter maiores informações (basicamente para a Javadoc).
Tendo escrito tanto, hora de ir para a parte interessante da coisa... a programação!

Como criar uma janela com Swing
Rapidamente antes de começar, preciso dizer uma coisinha. Eu estou assumindo que você, leitor, tem ao menos um leve conhecimento de Java (sintaxe e um pouquinho de nada de orientação a objetos). Caso não tenha, pode seguir em frente, mas recomendo ler algum material falando um pouco sobre a linguagem.

import javax.swing.JFrame;
 
public class JanelaSimples extends JFrame {
 
	public JanelaSimples() {
		this.setTitle("Minha primeira janela");
		this.setSize(640,480);
		this.setVisible(true);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
 
	public static void main(String[] args) {
		new JanelaSimples();
	}
}

[JanelaSimples.java]

Para compilar:
javac JanelaSimples.java

Para executar:
java JanelaSimples

Não coloque a extensão .class ou .java quando for executar a aplicação pois não irá funcionar.

Deu pra ver que é uma janela bastante útil. Você consegue redimensionar, fechar e... e é isso :)
Mesmo não servindo para muita coisa já deu um gostinho, então vamos as partes desse programa.

	public class JanelaSimples extends JFrame {

Aqui estamos criando a nossa classe JanelaSimples e herdando toda a funcionalidade de JFrame, que é a classe responsável pelos métodos que criam a nossa janela.

	public JanelaSimples() {
		this.setTitle("Minha primeira janela");
		this.setSize(640,480);
		this.setVisible(true);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

Em primeiro lugar, todas os métodos que estão sendo invocados foram herdados da classe JFrame, e é por isso que eu os chamo com 'this.'.
O que estes métodos estão fazendo? Na respectiva sequencia:
Definindo o titulo da janela para "Minha primeira janela"
Definindo o tamanho da janela para 640x480
Definindo que a janela deve ser exibida
Definindo que a operação padrão para quando você fechar a janela é a de que o programa deve terminar

Tudo muito simples.

	public static void main(String[] args) {
		new JanelaSimples();
	}

Como esse é o nosso programa principal ele precisa de uma função main que serve de ponto de entrada para ele. Nossa função main simplesmente instancia a classe JanelaSimples. Quando a instancia é criada, o construtor (explicado logo acima) é chamado e a nossa janela se faz visível.

Como adicionar componentes a janela

Agora que já sabemos criar a janela, vamos adicionar uma caixa de texto a ela. Para isso, usaremos o mesmo código da JanelaSimples.java e adicionaremos alguns comandos no construtor da classe. O construtora ficará da seguinte maneira:

import javax.swing.JFrame;
import javax.swing.JTextPane;
 
public class JanelaSimples extends JFrame {
 
	public JanelaSimples() {
		JTextPane texto = new JTextPane();
 
		this.setTitle("Minha primeira janela");
		this.setSize(640,480);
		this.add(texto);
		this.setVisible(true);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
 
	public static void main(String[] args) {
		new JanelaSimples();
	}
}

[JanelaSimples-2.java]

Se quiser compilar este exemplo, renomeie o arquivo para JanelaSimples.java e use as instruções fornecidas acima.
Daqui pra frente eu evitarei re-escrever todo o código o tempo todo e colarei apenas as novas partes que foram adicionadas. Para acessar o código todo, por favor use os arquivos que estão linkados em cada seção :)
Este novo código não mudou muito. As novidades aqui são:

import javax.swing.JTextPane;
...
		JTextPane texto = new JTextPane();
		...
		this.add(texto);

Adicionei o import referente a classe JTextPane que nos fornece uma caixa de texto. Dentro do construtor eu simplesmente crio uma instancia da class JTextPane e adiciono essa instancia a minha janela. O método 'add()' também foi herdado de JFrame.
Você vai perceber que o componente está usando a janela toda. Isso pode ser mudado, e será discutido quando estivermos falando de layouts da janela.
Todo componente que você desejar criar, basta instancia-lo e então adiciona-lo a janela utilizando o método 'add()'.
Se você deseja maiores informações sobre os métodos que a classe JFrame implementa e seus respectivos protótipos, de uma olhada na documentação do JFrame

Como criar um menu para a janela

Até então tudo muito interessante. Vamos adicionar um pouco de emoção agora e criar um menu para a nossa linda janela que não faz muita coisa.

import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
...
 
	public JanelaSimples() {
		JMenuBar barra = new JMenuBar();
		JMenu menuArquivo = new JMenu("Arquivo");
		JMenuItem arqSair = new JMenuItem("Sair");
 
		menuArquivo.add(arqSair);
		barra.add(menuArquivo);
		this.setJMenuBar(barra);
		...
	}
 
}

[JanelaSimples-3.java]

E o nosso programa está crescendo!
Só para esclarecer; um menu é feito de basicamente três partes:
A barra de menus
Os menus
Os items dos menus
Como pode-se perceber nós adicionamos três novos imports em nosso código que se referem a cada um desses items. Em nosso construtor então nós instanciamos uma barra de menu (JMenuBar), instanciamos um menu (JMenu) e finalmente instanciamos um item para o menu (JMenuItem). Depois de cada um dos items instanciados e configurados conforme desejamos, basta associa-los conforme feito no código.
Adicionamos o item 'arqSair' dentro do menu 'menuArquivo'. Adicionamos o menu 'menuArquivo' a barra de menu 'barra' e por fim chamamos o método setJMenuBar para adicionar o menu a nossa janela.
Para adicionar o menu nós utilizamos o método especial setJMenuBar pois ele já configura o nosso menu para ser mostrado da maneira esperada no topo da janela.

Como tratar eventos no seu menu

Eu estou achando esse programa cada vez mais empolgante! :D (espero que vocês também)
Como deu pra notar, o nosso menu 'Sair' não faz absolutamente nada :(
Iremos abordar agora um tipo simples de evento, e falar um pouquinho sobre alguns tipos de eventos que existem. Ao longo dos próximos tutoriais de como criar o nosso editor de texto iremos falando mais sobre esse assunto e explorando novos eventos.
Vamos então colocar uma funcionalidade nesse item 'Sair' para que ele faça aquilo que ele promete :)

...
 
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
 
...
 
		JMenuItem arqSair = new JMenuItem("Sair");
 
		arqSair.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
 
		menuArquivo.add(arqSair);
		barra.add(menuArquivo);
		this.setJMenuBar(barra);
 
...

[JanelaSimples-4.java]

Mais dois imports para nos auxiliar e um trecho de código um tanto quanto diferente. Deixe-me falar um pouco sobre eventos e listeners e especialmente sobre o ActionListener e o ActionEvent.
Eventos, como o nome sugere, são coisas que acontecem ao seu programa. Quando o usuário interage com o programa ao clicar em algo, digitar algo, movimentar o mouse ou coisas do genêro, um evento está acontecendo. O nosso programa sabe desses eventos através do chamamos de Listeners.
Os Listeners ficam 'ouvindo' o programa por eventos que aconteçam. Quando um evento acontece, o Listener invoca o método associado ao tipo de evento.
O ActionListener é um Listener para os eventos mais comums, como um clique ou como quando o usuário pressiona Enter ou Space. O evento que é lido por um ActionListener é um ActionEvent. Quando você tem um item em seu menu e clica com o botão direito ou esquerdo nele você gerou um ActionEvent. Se voce selectionar o menu e apertar Enter, você gerou um ActionEvent nele.
Possuindo essa noção de Listener e Event, vamos reanalizar o código acima.

	arqSair.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
	});

O componente JMenuItem possui um método que nos permite associar a instancia de uma classe que trata eventos do tipo ActionEvent ao seu ActionListener.
Sempre que um ActionEvent acontecer o método 'actionPerformed' dessa instancia será chamado para tratar do evento.
No nosso caso, para não precisarmos escrever toda uma classe para isso, nós criamos uma instancia anonima de ActionListener explicitando o nosso método actionPerfomed. Quando a ação ocorrer, esse método será executado e em nosso caso irá fazer com que a aplicação encerre.
O parametro que o método recebe contém informações sobre o evento, tais como: De onde veio o evento, quando o evento aconteceu, quais teclas estavam pressionadas quando o evento occoreu e etc... Para maiores informações sobre o que se pode tirar do ActionEvent, acesse esse link
Com isso, encerramos a breve introdução a eventos. Se ficaram algumas dúvidas, não se preocupe pois iremos falar mais sobre eles no futuro.

Como criar um painel com abas

Nosso editor de texto já está ganhando forma e agora é hora de dar a ele a primeira funcionalidade prometida: Abas!
Vamos criar então um painel de abas onde cada aba será uma caixa de texto diferente para escrevermos.

import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
 
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
 
// JTabbedPane para nosso painel de abas!
import javax.swing.JTabbedPane;
 
public class JanelaSimples extends JFrame {
 
	public JanelaSimples() {
		JMenuBar barra = new JMenuBar();
		JMenu menuArquivo = new JMenu("Arquivo");
		JMenuItem arqSair = new JMenuItem("Sair");
 
		arqSair.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
 
		menuArquivo.add(arqSair);
		barra.add(menuArquivo);
		this.setJMenuBar(barra);
 
		JTextPane texto = new JTextPane();
 
		this.setTitle("Minha primeira janela");
		this.setSize(640,480);
 
		/**
		 * A caixa de texto não é mais adicionada a janela
		 * e sim ao painel de abas
		 */
		//this.add(texto); <--- comentado!
 
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
 
		/**
		 * Criar o painel e adiciona-lo a janela
		 */
		JTabbedPane painel = new JTabbedPane();
		painel.addTab("Aba 1", texto);
		this.add(painel);
 
		this.setVisible(true);
 
	}
 
	public static void main(String[] args) {
		new JanelaSimples();
	}
}

[JanelaSimples-5.java]

Coloquei o código completo para não nos perdermos. As partes novas estão comentadas para serem mais facilmente identificadas.

...
 
		//this.add(texto); <--- comentado!
 
		...
 
		/**
		 * Criar o painel e adiciona-lo a janela
		 */
		JTabbedPane painel = new JTabbedPane();
		painel.addTab("Aba 1", texto);
		this.add(painel);
		...

Até aqui, bastante simples. Criamos um JTabbedPane, que é o nosso painel com abas e adicionamos uma aba com o título "Aba 1" e o componente que ela irá exibir é a nossa caixa de texto. Adicionamos então o painel a janela. Vejam que comentei a linha que adicionava a caixa de texto a janela já que agora a caixa de texto faz parte do painel de abas.

Próximo episódio

Bem pessoal, por hoje é só :)
Na próxima parte iremos abordar os seguintes temas:

  • Criação do menu 'Novo'
  • Criação do menu 'Salvar'
  • Criação do menu 'Salvar Como'
  • Criação do menu 'Sobre'

Talvez eu aborde mais coisas, mas não sei ainda.
Até a próxima :)

Posted by Henrique

Comments (10) Trackbacks (1)
  1. Parabens cara! vc me ajudo muito ^^

  2. Só esperando mais uma publicação! Muito bom o tutorial, parabéns mesmo.

  3. Bom mesmo! Detalhado! Excelente! Mastigadíssimo! :)
    Aguardo o próximo… merece ser continuado!

  4. Muito bom, finalmente começo a entender como trabalhar com swing sem ficar dependendo de alguma ferramenta. Fico no aguardo de como melhorar o layout das telas ^^

  5. po maneiro velho como coloca cor na janela ???

  6. Meu Caro,
    Muito bom mesmo,
    Procuro o restante para terminar, onde encontro ?

  7. ótimo tutorial . parabéns . se puder me enviar materias de java, inclusive da classe Swing, eu agradeço ! richardprogram@gmail.com

  8. Otimo tuto!
    vai rolar continuação?

  9. Parabens!!!
    muiiito booom!!!
    cara você explica mil vezes melhor doque meu professor de orientação a objeto.

  10. Qualidade megaboga,
    muito bom mesmo, poste mais sobre swing e essas coisas.
    Obrigado!!!


Leave a comment

(required)