quinta-feira, 12 de fevereiro de 2009

Artigo: Classes Genéricas

Quem ja tem um pouco mais de experiência em JAVA sabe que existem determinadas classes que você pode trabalhar com qualquer tipo. Nesse artigo mostrarei como criar uma própria classe genérica.

Tudo que você deve fazer é iniciar sua Classe com class MinhaClasse<E>, agora você pode usar o E como um tipo. Quando um usuário da sua classe necessitar usar ela por exemplo com inteiros basta ele declarar uma variável dessa maneira <em>MinhaClasse<int> m = new MinhaClasse<int>.

Abaixo o exemplo completo:

public class MinhaClasse<E extends Comparable> {
private E valor1;
private E valor2;

public MinhaClasse() {
}

public MinhaClasse(E valor1, E valor2) {
this.valor1 = valor1;
this.valor2 = valor2;
}

public E getValor1() {
return valor1;
}

public void setValor1(E valor1) {
this.valor1 = valor1;
}

public E getValor2() {
return valor2;
}

public void setValor2(E valor2) {
this.valor2 = valor2;
}

public void maior() {
if(valor1.compareTo(valor2) > 0)
System.out.println("O maior valor e: " + valor1);
else if(valor2.compareTo(valor1) > 0)
System.out.println("O maior valor e: " + valor2);

System.out.println("Sao iguais");
}

public boolean iguais()
{
return valor1.equals(valor2);
}

public void menor()
{
if(valor1.compareTo(valor2) < 0)
System.out.println("O menor valor e: " + valor1);
else if(valor2.compareTo(valor1) < 0)
System.out.println("O menor valor e: " + valor2);

System.out.println("Sao iguais");
}
}

Declaramos uma classe que aceitrá qualquer tipo que tenha sido derivada da classe Comparable. Isso servirá para podermos utilizar a função compareTo(object o), esta função compara o valor da esquerda com o valor da direita e retorna -1 se o valor da esquerda for menor, 1 caso seja maior e 0 se forem iguais. Poderíamos usar diretamente os operadores < e > porém isso não é aconselhável com String. Todos os tipos primitivos já são derivados dessa classe ou tem implementado as funções da interface IComparable.
Para comparar se são iguais utilizamos a função já definida pelo JAVA equals(object o) que retorna true caso sejam iguais.

Agora é só utilizarmos nossa nova classe:

public class Main {

public static void main(String[] args) {
// declara uma variavel que so aceitara inteiros
MinhaClasse<Integer> mi = new MinhaClasse<Integer>(34, 12);

mi.maior();
mi.menor();

if(mi.iguais())
System.out.println("Sao iguais");

// declara uma varivel que so aceitara strings
MinhaClasse<String> ms = new MinhaClasse("Palavra1", "Palavra2");

ms.maior();
ms.menor();

if(ms.iguais())
System.out.println("Sao iguais");

// declara uma variavel que aceitara qualquer tipo
MinhaClasse mg = new MinhaClasse();

mg.setValor1(34.5);
mg.setValor2(34.5);

mg.maior();
mg.menor();

if(mg.iguais())
System.out.println("Sao iguais");
}

}

Nossa primeira variável trabalhará apenas com inteiros, repare que declaramos Integer e não int isso porque é a classe Integer que é derivada da classe Comparable. Nossa segunda variável poderá apenas trabalhar com String.
Ja nossa terceira variável poderá trabalhar com qualquer tipo, isso é permitido, chamamos isso de tipo bruto, isto é, não sabemos quais são os tipos que está armazenado seja na variável valor1 ou na variável valor2. Deve-se tomar muito cuidado quando se trabalhar com tipos brutos, por exemplo, mude qualquer uma da atribuição de um valor para string setValor1("Palavra"); e veja o que acontece. Para evitar esta excessão sua classe deve evitar essa comparação, essa é uma das prioridades quando se quer criar uma classe genérica. Faça isso como exercício, compare os tipos e permita ou não a utilização da função compareTo(object o) entre eles.

Você viu como é simples criar uma classe genérica em JAVA, e também que se deve ter alguns cuidados quando criá-la, espero que tenha entendido o conceito.

Boa sorte.

terça-feira, 10 de fevereiro de 2009

Artigo: Múltiplos layouts em um JFrame.

Muitas vezes queremos fazer um JFrame com diferentes layouts, e não apenas com uma forma só de apresentar os objetos. Uma solução para isso é adicionar Panel de diferentes layouts em diferentes posições do JFrame.

Entre os vários layouts estão:

BorderLayout: você pode adicionar os objetos na posição norte, sul, leste, oeste e centro.

FlowLayout: adiciona os objetos linearmente, e quando ultrapassa o tamanho do frame ele quebra a linha, pode-se escolher se quer da esquerda pra direita, da direita pra esquerda ou centro, o padrão é esquerda-direita.

GridLayout: especifica-se o total de linhas e colunas, os objetos são adicionados até preencher todas as colunas da primeira linha, depois todas as colunas da segunda linha e assim sucessivamente.

Apesar de apenas ter comentado esses, que são os que eu vou usar nesse artigo, possui muitos outros como GridBagLayout que você determina o tanto de colunas e linhas que o componente irá utilizar.

Vamos ao exemplo:
Pra começar precisamos importar:

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;

O JFrame para nossa classe que será a janela estender, JButton para adicionar botões, o JPanel para podermos criar os painéis, e os layouts que utilizaremos.

Criando a nossa janela:

public class Janela extends JFrame{
// botoes que serao inseridos no panelNorte que possui FlowLayout
private JButton button1Norte;
private JButton button2Norte;
private JButton button3Norte;
private JButton button4Norte;

// botoes que serao inseridos no panelSul que possui GridLayout
private JButton button1Sul;
private JButton button2Sul;
private JButton button3Sul;
private JButton button4Sul;

//panel com FlowLayout
private JPanel panelNorte;
private JPanel panelSul;

public Janela()
{
super("Janela com multiplos layouts");
this.Init();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(500, 500);
this.setVisible(true);
}

private void Init()
{
//inicializa os botoes
this.button1Norte = new JButton("Botao1Norte");
this.button1Sul = new JButton("Botao1Sul");
this.button2Norte = new JButton("Botao2Norte");
this.button2Sul = new JButton("Botao2Sul");
this.button3Norte = new JButton("Botao3Norte");
this.button3Sul = new JButton("Botao3Sul");
this.button4Norte = new JButton("Botao4Norte");
this.button4Sul = new JButton("Botao4Sul");

// inicializa os JPanels com os layouts
this.panelNorte = new JPanel(new FlowLayout());

//GridLyout com duas linhas e duas colunas
this.panelSul = new JPanel(new GridLayout(2, 2));

//insere os botoes na panelNorte, por ser FlowLayout sera inserido da esquerda para a direita
this.panelNorte.add(this.button1Norte);
this.panelNorte.add(this.button2Norte);
this.panelNorte.add(this.button3Norte);
this.panelNorte.add(this.button4Norte);

//insere os botoes no panelSul, por ser GridLayout ele preenche a primeira linha, depois a
// segunda
// e assim por diante
this.panelSul.add(this.button1Sul);
this.panelSul.add(this.button2Sul);
this.panelSul.add(this.button3Sul);
this.panelSul.add(this.button4Sul);
//insere os panels na janela, o BorderLayout indica a posicao podendo ser
//norte, sul, leste, oeste ou centro
this.add(this.panelNorte, BorderLayout.NORTH);
this.add(this.panelSul ,BorderLayout.SOUTH);
}
}

As primeiras linhas eu declaro os botoes e os painéis onde os botões serão adicionados.

Na função Init() eu inicializo todos os botões, a string no construtor será o text mostrado em cada botão. Cada Panel é inicializado com um tipo de layout. Feito isso adiciono cada botão em seu determinado Panel.

Pronto agora é só adicionar cada Panel em seu lugar no Frame.

Iniciamos então a nossa classe Janela no Main:
public class Main {
public static void main(String[] args) {
new Janela();
}
}

O resultado:



A tela não terá funcioinalidade pois não adicionei eventos, use a imaginação e até a próxima.

Deixe suas dúvidas.

Pessoal é só vocês postarem suas dúvidas que responderemos. Este blog será destinado a Java. Temos também o os blogs destinados a C# http://csharpprogramando.blogspot.com/ e a C e C++ http://cprogramando.blogspot.com/.
Bom pra começar é isso, colocaremos artigos também, e caso tenha curiosidade nós atualizaremos o blog todos os dias, respondendo as dúvidas sequencialmente.