Assunto Aleatorio

Um pouco de tudo….coisas de computeiro…politica….livros

JFreeChart: Evolução das equipes de Formula 1

Posted by admin on November 17th, 2008

A algum (muito) tempo atras, eu fiz um post sobre o JFreeChart, e algumas dicas de personalização dos gráficos gerados. A minha idéia era fazer mais alguns posts, mas eu achei que aqueles gráficos com dados fake ficaram tão fraquinhos que eu coloquei os outros posts na geladeira por um tempo.

Agora eu resolvi por uma abordagem diferente. Eu achei um conjunto de dados interessante, e resolvi fazer um gráfico com ele, mostrando os passos pra se chegar no resultado final.

Chega de enrolação e vamos direto ao que interessa:

Evolução das equipes de Formula 1 de 1998 a 2008:

Evolucao equipes formula 1

Agora vamos ao passo a passo pra construir esse gráfico:

Primeiramente o código básico pra gerar o gráfico. O tipo de gráfico que faz mais sentido pra esse caso é um TimeSeries, já que nós estamos representando a variação de alguma coisa (classificação das equipes) ao longo do tempo (em cada ano).

public class Charts extends ApplicationFrame {

public static void main( String[] args ) {
Charts chart = new Charts(“Teste Bar Chart”);
chart.pack();
chart.setVisible(true);
}

public static JFreeChart getTimeSerie() {
JFreeChart chart = ChartFactory.createTimeSeriesChart(“Historico F-1 - Construtores”, “Ano”, “Equipe”,
getTimeSet(), true, false, false);
}

public static TimeSeriesCollection getTimeSet() {
TimeSeriesCollection ts = new TimeSeriesCollection();
//Um monte de código pra inserir o resultado final de todos os anos no TimeSeriesCollection
return ts;
}
}

Com esse código nos conseguimos o gráfico a seguir:

Evolucao equipes formula 1 - primeiro passo

Da pra ver alguns defeitos nesse gráfico:

  • O primeiro colocado está na parte de baixo do gráfico e o último na parte de cima
  • A escala das posições está de 0,5 em 0,5. Alguém já viu uma equipe ficar na posição 2,5?
  • O gráfico está colado nos eixos, o que deixa a visualização ruim

Vamos então resolver esses problemas e ver como é que fica o nosso gráfico:

chart.getXYPlot().getRangeAxis().setInverted(true);
chart.getXYPlot().getRangeAxis().setRange(0, 12);
chart.getXYPlot().getDomainAxis().setRange(new Year(1997).getMiddleMillisecond(), new Year(2009).getFirstMillisecond());
chart.getXYPlot().getRangeAxis().setStandardTickUnits(new TickUnitSource() {
@Override
public TickUnit getCeilingTickUnit(TickUnit arg0) {
return new NumberTickUnit(1);
}

@Override
public TickUnit getCeilingTickUnit(double arg0) {
return new NumberTickUnit(1);
}

@Override
public TickUnit getLargerTickUnit(TickUnit arg0) {
return new NumberTickUnit(1);
}

});

A primeira linha resolve o primeiro problema. Definindo o Range Axis como inverted, ele passa a começar com o menor valor em cima.

As duas linhas seguintes resolvem o problema do gráfico sem espaços. Definindo o range como 0 a 12 e Year(1997) a Year(2009), nós colocamos um espaço antes e depois de cada dimensão do gráfico.

As linhas seguintes definem que o gráfico vai ter exatamente uma unidade entre cada valor das linhas do Range. Deve existir uma maneira mais fácil de fazer isso, mas eu não consegui achar.

Corrigidos os primeiros defeitos, eis o nosso gráfico:

Evolucao equipes formula 1 - segundo passo

Melhorzinho, mas ainda não está bom.

  • Onde estão a Stewart, a Benetton, a Jaguar e as outras equipes que participaram dos anos anteriores
  • O que aconteceu com a McLaren em 2007

Pra responder essas perguntas vamos colocar anotações no gráfico:

XYPlot plot = chart.getXYPlot();
plot.addAnnotation(getAnnotation(“Tyrrel”, new Year(1998).getFirstMillisecond(), 10));
plot.addAnnotation(getAnnotation(“Stewart”, new Year(1999).getFirstMillisecond(), 4));
plot.addAnnotation(getAnnotation(“Benneton”, new Year(2001).getFirstMillisecond(), 7));
plot.addAnnotation(getAnnotation(“Jaguar”, new Year(2004).getFirstMillisecond(), 7));
plot.addAnnotation(getAnnotation(“BAR”, new Year(2005).getFirstMillisecond(), 7));
plot.addAnnotation(getAnnotation(“Sauber”, new Year(2005).getFirstMillisecond(), 8));
plot.addAnnotation(getAnnotation(“Jordan”, new Year(2005).getFirstMillisecond(), 9));
plot.addAnnotation(getAnnotation(“Minardi”, new Year(2005).getFirstMillisecond(), 10));
plot.addAnnotation(getAnnotation(“MF1″, new Year(2006).getFirstMillisecond(), 10));
plot.addAnnotation(getAnnotation(“Spyker”, new Year(2007).getFirstMillisecond(), 10));

plot.addAnnotation(getAnnotation(“Saiu”, new Year(2001).getFirstMillisecond(), 9, Color.RED));
plot.addAnnotation(getAnnotation(“Saiu”, new Year(2002).getFirstMillisecond(), 9, Color.RED));
plot.addAnnotation(getAnnotation(“Perdeu Pontos”, new Year(2007).getFirstMillisecond(), 11, Color.RED));
plot.addAnnotation(getAnnotation(“Saiu”, new Year(2008).getFirstMillisecond(), 11, Color.RED));

/*…*/

public static XYTextAnnotation getAnnotation(String text, double x, double y, Color color) {
XYTextAnnotation cta = new XYTextAnnotation(text, x, y);
Font font = new Font(Font.SANS_SERIF, Font.BOLD, 12);
cta.setFont(font);
cta.setPaint(color);
return cta;
}

public static XYTextAnnotation getAnnotation(String text, double x, double y) {
return getAnnotation(text, x, y, Color.DARK_GRAY);
}

E agora o resultado:

Evolucao equipes formula 1 - terceiro passo

Agora da pra saber que até 2001 a Renault chamava Benneton, que em 2007 a McLaren perdeu os pontos do campeonato, e que as linhas que não têm continuidade foram equipes que saíram da Formula 1.

Mas… ainda não é o gráfico que foi visto ali em cima. Esse ta com as linhas muito finas, e as cores da linhas não estão legais. Ferrari representada por uma linha azul e McLaren por uma vermelha. Não tem associação nenhuma com as cores das equipes!

Vamos então aos ajustes finais do gráfico. Agora é só pra ficar mais bonitinho:

plot.getRenderer().setSeriesPaint(0, Color.DARK_GRAY);
plot.getRenderer().setSeriesPaint(1, Color.RED);
plot.getRenderer().setSeriesPaint(2, Color.BLUE);
plot.getRenderer().setSeriesPaint(3, Color.ORANGE);
plot.getRenderer().setSeriesPaint(4, Color.YELLOW);
plot.getRenderer().setSeriesPaint(5, Color.BLUE.darker());
plot.getRenderer().setSeriesPaint(6, Color.PINK);
plot.getRenderer().setSeriesPaint(7, Color.MAGENTA.darker());
plot.getRenderer().setSeriesPaint(8, Color.GREEN);
plot.getRenderer().setSeriesPaint(9, Color.GREEN.darker());
plot.getRenderer().setSeriesPaint(10, Color.RED.darker());
plot.getRenderer().setSeriesPaint(11, Color.CYAN);
plot.getRenderer().setSeriesPaint(12, Color.GRAY);

for (int i = 0 ; i <= 12 ; i++) {
plot.getRenderer().setSeriesStroke(i, new BasicStroke(3f));
}

Agora sim temos o gráfico que pode ser visto lá em cima.

O código fonte completo pra gerar os gráficos você encontra aqui.

Você vai precisar do jar do JFreeChart e do jCommons(que vem no zip do JFreeChart)

Posted in Coisas de Computeiro, Java Básico, O mundo a nossa volta | 1 Comment »

Voucher para Certificação Java com desconto e retake

Posted by admin on November 10th, 2008

Recebi por e-mail e estou postado pra quem tiver interesse:

Campanha de Retake via Web - Certifcação Java

Posted in Coisas de Computeiro, Java Básico, Java Web | No Comments »

Java Web - Interfaces Listener

Posted by admin on October 27th, 2008

Isso não era nem pra virar post mas eu achei interessante e resovi postar.

Eu estou estudando pra certificação SCWCD (Sun Certified Web Component Developer) e um dos tópicos que da prova são as interfaces Listener. Como os nomes dos listeners são meio parecidos entre eles, os nomes dos métodos podem causar confusão e o nome dos eventos associados também são parecidos, eu resolvi fazer um resumo pra mim. O resumo só em texto tava ficando difícil de ler, então eu coloquei tags html pra melhorar. Daí pra virar post foi um pulinho.

Apesar do nome do exame carregar o número 5, essa prova é baseada na versão 1.4 do Java EE, então os links abaixo apontam para a api dessa versão.

Vamos aos listeners:

ServletContextListener

Recebe notificações quando o ServletContext e inicializado e destruído. Deve ser configurado no deployment descriptor.

contextInitialized

Notifica a inicialização do ServletContext. É notificado antes da inicialização dos filtros e servlets.

contextDestroyed

Notifica que o ServletContext está a ponto de ser desativado. É notificado após a desativação dos filtros e servlets.

Evento associado: ServletContextEvent

  • getServletContext - Retorna o ServletContext da aplicação.

ServletContextAttributeListener

É notificado a respeito de modificações na lista de atributos do ServletContext. Deve ser configurado no deployment descriptor.

attributeAdded

Notifica que um atributo foi adicionado ao servlet context. Chamado após a adição do atributo.

attributeRemoved

Notifica da remoção de um atributo do servlet context. Chamado após a remoção do atributo.

attributeReplaced

Notifica que um atributo foi substituído no servlet context. Chamado após a substituição do atributo.

Evento associado: ServletContextAttributeEvent

Essa classe estende ServletContextEvent, portanto, tem acesso ao ServletContext. Além disso tem os seguintes métodos:

  • getName - retorna o nome do atributo que foi modificado no servlet context.
  • getValue - retorna o valor do atributo que modificou a lista de atributos do servlet context. Se o atributo foi adicionado ou removido, é o valor do atributo. Se for substituído, é o valor antigo do atributo.

ServletRequestListener

Notifica quando uma request está iniciando e depois que ela terminou. Deve ser configurado no deployment descriptor.

requestInitialized

O request está pra entrar no escopo da aplicação.

requestDestroyed

O request está para sair de escopo na aplicação.

Evento associado: ServletRequestEvent

  • getServletContext - Auto-explicativo.
  • getServletRequest - Auto-explicativo.

ServletRequestAttributeListener

Notifica quando ha mudanças nos atributos do request. Deve ser configurado no deployment descriptor.

attributeAdded

Notifica que um atributo foi adicionado ao request. Chamado depois da adição do atributo.

attributeRemoved

Notifica que um atributo foi removido do request. Chamado depois da remoção do atributo.

attributeReplaced

Notifica que um atributo foi substituído no request. Chamado apos a substituição do atributo.

Evento associado: ServletRequestAttributeEvent

Essa classe estende ServletRequestEvent, portando tem acesso aos métodos getServletContext e getServletRequest. Além disso, tem os seguintes métodos:

  • getName - nome do atributo que foi modificado.
  • getValue - valor do atributo que foi modificado. Se o atributo foi adicionado ou removido, retorna o valor do atributo. Se foi modificado, retorna o valor antigo do atributo.

HttpSessionListener

Notifica sobre mudança na lista de sessões na aplicação. Deve ser configurado no deployment descriptor.

sessionCreated

Notifica que uma sessão foi criada.

sessionDestroyed

Notifica que uma sessão está pra ser destruída.

Evento associado: HttpSessionEvent

  • getSession - A sessão que está sendo criada ou destruida.

HttpSessionActivationListener

Usado para notifica objetos que estão associados à sessão de que ela vai ser ativada ou passivada (não gostei dessa palavra, mas não achei outra melhor).

sessionDidActivate

Notifica que a sessão acabou de ser ativada.

sessionWillPassivate

Notifica que a sessão está pra ser passivada.

Evento associado: HttpSessionEvent

  • getSession - A sessão que está sendo ativada ou passivada.

HttpSessionAttributeListener

Notifica a respeito de alterações na lista de atributos de uma sessão. Deve ser configurado no deployment descriptor.

attributeAdded

Notifica que um atributo foi adicionado à sessão. Chamado após a inserção do atributo.

attributeRemoved

Notifica sobre a remoção de um atributo da sessão. Chamado após a remoção do atributo.

attributeReplaced

Notifica sobre a substituiçãoo de um atributo na sessão. Chamado após o atributo ser substituído.

Evento associado: HttpSessionBindingEvent

Essa classe foge um pouco do padrão de nomenclatura visto até agora. O natural seria que ela se chamasse HttpSessionAttributeEvent, mas ela também é usada pelo próximo listener, que chama HttpSessionBindingListener, o que deve ter originado o nome desse event.

Essa classe estende HttpSessionEvent, portanto tem acesso ao método getSession. Além disso ela define os seguintes métodos:

  • getName - o nome do atributo que está modificando a lista de atributos da sessão.
  • getValue - o valor do atributo que está modificando a sessão. Se o atributo está sendo adicionado ou removido, esse é o valor do atributo. Se o valor esta sendo substituído, é o valor antigo do atributo.

HttpSessionBindingListener

Notifica ao objeto que representa o atributo que ele esta sendo vinculado ou desvinculado da sessão.

valueBound

Notifica o objeto de que ele está sendo vinculado à sessão.

valueUnbound

Notifica o objeto de que ele está sendo desvinculado da sessão.

Evento associado: HttpSessionBindingEvent

Essa classe estende HttpSessionEvent, portanto tem acesso ao método getSession. Além disso ela define os seguintes métodos:

  • getName - o nome do atributo que está sendo vinculado ou desvinculado.
  • getValue - o valor do atributo que está sendo vinculado ou desvinculado da sessão.

Posted in Coisas de Computeiro, Java Web | No Comments »

O google acha que voce acha aqui - volume 2

Posted by admin on October 22nd, 2008

Mais uma lista de termos que o google achou que alguém achava aqui, mas não acha (Não achava, porque agora eu pesquisei e/ou resolvi escrever, então agora acha). :-D

“alterar tag de erro para warning no eclipse”

Vá ao menu Window -> Preferences. Na janela de preferências vá até a opção Java -> Compiler -> Errors/Warnings. Você vai ter uma lista com vários possíveis problemas, e um combo box pra setar o nível que você quer pra cada um deles (Error/Warning/Ignore). É só alterar o que você desejar, mas faça isso com responsabilidade.

“plugin para identação no eclipse”

Não precisa de plugin, basta selecionar tudo (Ctrl + a), ou a parte do código que deseja indentar, e pressionar (Ctrl + i);

“f”

pode ser muita coisa, mas a wikipedia sabe: f

“Sorte numero aleatorio Java”

Se vai te dar sorte ou não eu não sei, mas pra gerar um numero aleatório em JAva é fácil:

Random r = new Random();

//O mais básico:

r.nextInt();

// Se quiser limitar o valor a MAX_VALUE-1:

r.nextInt(MAX_VALUE);

//Se precisar de um numero aleatorio maior que um int

r.nextLong();

/*Se precisar chutar entre 0 e 1, true e false, preto e branco, yin e yang, Brasil e Argentina, loira e morena, etc…*/

r.nextBoolean();

//Se precisar um numero aleatorio não inteiro

r.nextDouble();

Posted in Aleatorio, Coisas de Computeiro | No Comments »

Java Básico - Leitura de Arquivos

Posted by admin on October 21st, 2008

Depois das explicações sobre o objeto File, agora vamos ver os objetos Reader, mais especificamente sobre FileReader e BufferedReader.

É claro que antes eu vou ter que tirar as teias de aranha do blog, porque faz muito tempo que eu não posto! :D

Primeiro uma explicação: porque usar um Reader e não um InputStream?

Basicamente é porque os Readers são recomendados para a leitura de arquivos de texto, enquanto os InputStream são recomendados para a leitura de dados binários. Como eu pretendo usar arquivos texto nos exemplos, nós vamos de Reader.

File Reader

É a classe mais básica para a leitura de arquivos de texto.

Existem três formas de instanciar um FileReader:

File file = new File(“C:/tmp/fileTests/testFile1.txt”);

try {

FileReader fileReader1 = new FileReader(file);

FileReader fileReader2 = new FileReader(“C:/tmp/fileTests/testFile1.txt”);

} catch (FileNotFoundException e) {

e.printStackTrace();

}

//Não é o foco, está aqui só pra ilustrar

FileReader fileReader3 = new FileReader(new FileDescriptor());

O fileReader1 é instanciado a partir de um objeto File, o fileReader2 é instanciado a partir de um caminho para um arquivo. Ambos podem lançar uma FileNotFoundException caso o arquivo indicado pelo objeto File ou pelo path não exista. Já a terceira forma utiliza um FileDescriptor como argumento. Como esse forma não é tão comum de ser usada, ela não vai ser abordada. Um detalhe, essa terceira forma não lança FileNotFoundException, pois se você tem um FileDescriptor válido, é porque o arquivo deve existir.

Instanciado o FileReader, é hora de ler os dados. Existem quatro métodos read diferentes para isso na classe fileReader:

  • int read() - lê um único caracter e retorna como um int. Retorna -1 caso tenha chegado ao fim do arquivo
  • int read(char[] cbuf) - lê quantos caracteres forem possíveis para dentro do array de char. Retorna o número de caracteres lidos ou -1 caso tenha chegado ao fim do arquivo
  • int read(char[] cbuf, int off, int len) - lê len caracteres para dentro do array de char, escrevendo à partir da posição indicada por off. Retorna o número de caracteres lidos ou -1 caso tenha chegado ao fim do arquivo
  • int read(CharBuffer target) - le os dados do arquivo para o CharBuffer e retorna o número de caracteres lidos, ou -1 caso tenha chegado ao fim

Todas as formas lançam IOExeption em caso de problemas durante a leitura.

int read1 = fileReader1.read();

char[] buff = new char[10];

int read2 = fileReader1.read(buff);

int read3 = fileReader1.read(buff, 2, 2);

CharBuffer buff2 = CharBuffer.allocate(10);

int read4 = fileReader1.read(buff2);

Com esses métodos já é possível ler todo o conteúdo de um arquivo, mas não é a melhor forma. Alguém viu um readline por ai? Não né! Então esse é um bom motivo pra não parar por aqui e estudar a próxima classe.

BufferedReader

O BufferedReader é melhor que o FileReader, e não é só porque ele tem um método readline() que retorna uma String com uma linha do arquivo, independente do tipo de quebra de linha do sistema operacional, ele é melhor porque diferentemente do FileReader, que acessa o arquivo a cada chamada read(…) que você faz, o BufferedReader faz uma leitura de uma grande quantidade de dados (atualmente na minha JVM são 8192, mas isso pode variar), e vai entregando aos pouquinhos, conforme o usuário vai pedindo. E como todo bom computeiro deve saber, umas das coisas mais lentas que um computador faz é acesso ao disco, então esse buffer tem o potencial de economizam um monte de millisegundos.

Exemplos são mais legais que bla bla bla, então:

/* Instanciando um BufferedReader. Pra isso você precisa de um outro Reader já instanciado, como um dos FileReader acima.*/

BufferedReader br = new BufferedReader(fileReader1);

/* Existe também um construtor que recebe o tamanho do buffer, mas eu prefiro confiar na implementação e ficar com o tamanho default*/

//BufferedReader br1 = new BufferedReader(fileReader1, 9999);

/*Pra ler a linhas do arquivo ficou fácil*/

String line = null;

while ((line=br.readLine()) != null) {

System.out.println(line);

}

A única coisa nova é o método readline(), que retorna uma String com uma linha do arquivo lido, ou null se tiver chegado ao fim.

Os outros métodos read(…) também estão presentes no BufferedReader, sendo que os métodos int read() e int read(char cbuf[], int off, int len) foram sobrescritos para utilizar o buffer.

Existe uma coisa que não pode ser esquecida, tanto para o FileReader quanto para o BufferedReader, que é chamar o método close() ao fim do uso, a fim de liberar o arquivo e os recursos do sistema operacional.

À respeito dos Readers era só isso. É claro que tem muito mais na api do Java e em todo o resto da internet, esperando pra ser lido, então vá em frente.

Posted in Coisas de Computeiro, Java Básico | No Comments »

O Goolge acha que você acha aqui

Posted by admin on October 7th, 2008

Seguindo uma idéia que eu vi pela primeira vez no infopod quando ele ainda era infoblog, Segue uma lista de termos que alguém procurou no google e acabou caindo aqui, mesmo sem o assunto aleatório ter essa informação.
Os textos das buscas estão exatamente como a pessoa que estava procurando digitou.

calvin haroldo yukon rapidshare

Não achou aqui, e tomara que não tenha achado em lugar nenhum.
O livro é bom e ta barato, da última vez que eu vi, tava R$ 18,80 no submarino. O livro tem 128 páginas de quadrinhos, o que da menos de R$ 0,15 por página. Então, vê se tira o escorpião do bolso e compra.

Calvin - Yukon He!

Gráficos de biocombustível no Brasil

Não sei se tem o gráfico que essa pessoa estava querendo, mas nessa página tem um monte de dados estatísticos atualizados sobre a produção, distribuição e consumo de combustíveis no Brasil.

“regulamentação” + “horas semanais” + “analista de sistemas”

Não existe uma regulamentação pra isso ainda, apenas uma proposta tramitando no senado que fala em 40 horas semanais. Enquanto essa proposta não for aprovada por todas as comissões e assembléias possíveis, continuam valendo as 44 horas semanais da CLT, a menos que a empresa tenha uma política própria de menos horas.

preciso pagar para usar gprs da tim?

Sim, a menos que você tenha um plano que inclua isso, ou um plano exclusivo de dados, você vai ter que pagar pelo uso do gprs.

projetos de quintal com cachorro

Isso deve depender do tamanho do cachorro. Segundo pesquisa com alguns cachorros, eles dizem que deve ter espaço, uma área coberta e protegida do vento e uma área de terra/grama para necessidades fisiológicas.

java remover duplicados list

Pra esse caso, a melhor coisa a se fazer é utilizar um HashSet. Mas não se esqueça de sobrescrever o equals e o hashCode do seu objeto pra diferenciar os objetos corretamente.

marcas de carros em ordem alfabetica

Essas são as que constam na busca da fipe
Acura
Agrale
Alfa Romeo
AM Gen
Asia Motors
Audi
BMW
BRM
Buggy
Bugre
Cadillac
CBT Jipe
CHANA
Chrysler
Citroën
Cross Lander
Daewoo
Daihatsu
Dodge
EFFA
Engesa
Envemo
Ferrari
Fiat
Fibravan
Ford
GM - Chevrolet
Gurgel
Honda
Hyundai
Isuzu
Jaguar
Jeep
JPX
Kia Motors
Lada
Land Rover
Lexus
LOBINI
Lotus
Mahindra
Maserati
Matra
Mazda
Mercedes-Benz
Mercury
Mitsubishi
Miura
Nissan
Peugeot
Plymouth
Pontiac
Porsche
Renault
Rover
Saab
Saturn
Seat
SSANGYONG
Subaru
Suzuki
Toyota
Troller
Volvo
VW - VolksWagen
Walk

Posted in Aleatorio, Coisas de Computeiro | No Comments »

Java Básico: Navegação, Leitura e Escrita em Arquivos (mas não tudo de uma vez)

Posted by admin on September 29th, 2008

É muito comum em projetos - do menor sistema de locadora ao mais complexo sistema de gerenciamento de sistemas de gerenciamento de redes sociais integradas - a necessidade de leitura e escrita em arquivos.
Em Java, como era de se prever, existe um vasto suporte a essas tarefas, e como também era de se prever, ele está distribuído em várias classes diferentes - é claro.

A maioria, se não totalidade, das classes para leitura e escrita em arquivos encontra-se no pacote java.io. A primeira e mais importante delas e a classe File.
O objeto do tipo File é a representação de um arquivo ou diretório. E não, definitivamente não, você não pode ler ou escrever dados diretamente em um File.
Mas então WTF é um File, e pra que eu preciso dele? Simples, você precisa dele para manipulação de arquivos e diretórios, coisas como criar, renomear, apagar, verificar algumas propriedades, e no caso de diretórios, navegar.

Agora vamos direto ao ponto:

Instanciando um File

Existem 4 construtores de file:

File file1 = new File(“C:/tmp/fileTests/test1″);

File file2 = new File(“C:/tmp/fileTests/test1″,“C:/tmp/fileTests/test2/testFile1.txt”);

File file3 = new File(file1, “testFile2.txt”);

File file4 = new File(“C:/tmp/fileTests/test1/testFile3.txt”);

//Esse não é nosso foco, fica aqui só como ilustração
//File file4 = new File(new URI(…));

Então, agora que eu já instanciei meu File, meu arquivo/diretório já deve estar criado no meu sistema operacional?
Não
Se o arquivo ou diretorio já existir no sistema operacional, então o seu objeto File estará apontando para ele, mas se ele não existir, a simples instanciação não vai criá-lo.
Para criar efetivamente o arquivo ou diretório não basta apenas instanciar, ou seja, vamos para o próximo passo:

Criar Arquivo ou Diretório

Pra fazer com que um arquivo ou diretório seja efetivamente criado, devemos proceder da seguinte forma:

if (file1.mkdir()) {
System.out.println(“Created file1 with mkdir”);
} else if (file1.mkdirs()) {
System.out.println(“Created file1 with mkdirs”);
}
if (file2.createNewFile()) {
System.out.println(“Created file2″);
}

if (file3.createNewFile()) {
System.out.println(“Created file3″);
}

if (file4.createNewFile()) {
System.out.println(“Created file4″);
}

Pra criar diretórios, você deve usar mkdir ou mkdirs. A diferença entre eles é que o primeiro só vai criar o diretório indicado pelo path completo, no caso, ‘test1′, e se os diretórios anteriores a ele não existirem, ele não vai criar diretório nenhum e vai retornar false (ou seja, não vai criar o seu diretório). Já o mkdirs vai criar o diretório indicado pelo path completo, e se estiver faltando algém pelo caminho, como o diretório ‘fileTests’, ele vai criar também.
Para a criação de arquivos, existe apenas um comando, createNewFile, que vai criar o arquivo no diretório especificado caso o diretório exista, ou vai criar no diretório corrente, caso o diretório não tenha sido especificado. Se o diretório não existir você ganha inteiramente ‘di gratis’ uma Exception.

Renomear um arquivo

Não, não dá pra apertar F2.
Você pode usar o método renameTo para renomear um arquivo, renomear um diretório, ou mover um arquivo. É mais fácil dar exemplo do que explicar, então segue:

if (file3.renameTo(new File(file1, “testFile4.txt”))) {
System.out.println(“Renamed file3 to 4″);
}

if (file2.renameTo(new File(“C:/tmp/fileTests”, “testFile1.txt”))) {
System.out.println(“Renamed and moved a file”);
}

if (file1.renameTo(new File(“C:/tmp/fileTests/test2″))) {
System.out.println(“Renamed a dir”);
}

Apagando arquivos e diretórios

Agora que a gente já fez um monte de bagunça criando e renomeando arquivo e diretórios, está na hora de apagar um pouco dessa bagunça, a idéia é simples, ache o arquivo ou diretório que você quer apagar, e chame o método delete nele.

/*
* Depois das chamadas a renameTo, os objetos já não apontam mais pra onde deveriam
*/
file1 = new File(“C:/tmp/fileTests/test2″);
file3 = new File(“C:/tmp/fileTests/test2/testFile4.txt”);

if (file1.delete()) {
System.out.println(“Deleted a dir with a file into it”);
} else {
if (file3.delete()) {
System.out.println(“I had to delete the file first”);
if (file1.delete()) {
System.out.println(“To finally delete the dir”);
} else {
System.out.println(“cant delete file1″);
System.out.println(file1.getAbsolutePath());
}
} else {
System.out.println(“Cant delete file3″);
System.out.println(file3.getAbsolutePath());
}
}

Se você executou o código, a primeira coisa que vai perceber é que depois de chamar os renameTo, nossas variáveis já não apontam para os arquivos e diretórios válidos.
Depois você vai descobrir que para deletar um diretório, é necessário apagar todos os arquivos que estão dentro dele antes.

Verificando propriedades

Existem várias propriedades que se pode verificar em um arquivo/diretório. Eu não vou dar exemplo de todas, mas sim listar as opções existentes, pois acho que isso deve ser mais útil:

  • canExecute - diz se o arquivo/diretório em questão é ou não executável
  • canRead - diz se o arquivo/diretório em questão é ou não disponível pra leitura
  • canWrite - diz se o arquivo/diretório em questão é ou não disponivel pra escrita
  • exist - diz se o arquivo ou diretório já/ainda existe
  • getAbsolutePath - retorna o caminho absoluto do File
  • getParent/getParentFile - retorna o Parent do File
  • isDirectory - diz se o file é um diretório
  • isFile - diz se o file é um arquivo
  • isHidden - diz se o arquivo/diretório é oculto
  • lastModified - retorna um long com a data da última modificação

Navegando na estrutura de diretórios

Para o final (deste post) a parte mais divertida: Navegar pelas estruturas de diretório - eu sei….não tem graça.
Vamos direto ao código:

File homeDir = new File(“C:/tmp”);
if (homeDir.isDirectory()) {
File[] childs = homeDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
// Nesse caso eu so quero os diretórios
return pathname.isDirectory();
}

});
for (File child : childs) {
//Pra ir navegando voce deve chamar listFiles recursivamente para cada um dos diretorios filhos
}
}

Aqui o principal a se destacar é o metodo listFiles, nesse caso recebendo um FileFilter para retornar apenas os diretórios. Esse método retorna um objeto File para cada Arquivo/Diretório, que seja aceito pelo FileFilter, existente no diretorio referenciado pela variável em que o método foi chamado.

Com isso completa o que eu queria falar sobre o objeto File, mas ainda falta muita coisa.

Posted in Coisas de Computeiro, Java Básico | 1 Comment »

iPhone: status ou burrice

Posted by admin on September 26th, 2008

Eu tinha um monte de coisas pra falar sobre a estréia do iPhone 3G, mas como essa me deixou besta, eu só vou falar dela:

Quem na Claro decidiu que o iPhone é um aparelho para falar e não para navegar?

Vocês já viram os planos para iPhone:

  • 200 minutos (180 pra Claro + 20 pra fixo) + 100 SMS + 100MB de dados
  • 300 minutos (270 pra Claro + 30 pra fixo) + 150 SMS + 150MB de dados
  • 400 minutos (360 pra Claro + 40 pra fixo) + 200 SMS + 200MB de dados

Considerando só o menor plano, e nem entrando na questão dos preços, é de se esperar que:

  • Eles vão convencer todos os contatos de quem comprar um iPhone a se mudar pra Claro, só assim faz sentido um plano com essa distribuição para o uso dos minutos
  • 100 SMS são suficientes para um ano inteiro para a maioria das pessoas que já saiu do colegial
  • 100MB de dados em um smartphone é tão inteligente quanto limitar a velocidade uma Ferrari a 20km/h
  • 200MB de dados (considerando o plano de 400 minutos) em um smartphone também é tão inteligente quanto limitar a velocidade uma Ferrari a 20km/h

No mundo inteiro um iPhone e sinal de status, com uns planos desses, no Brasil um iPhone vai ser sinal de burrice.

Posted in Coisas de Computeiro, O mundo a nossa volta | 3 Comments »

Justiça eleitoral determina o bloqueio do Twitter - Sorte do Twitter

Posted by admin on September 11th, 2008

Não, eu não achei certa essa decisão da Justiça eleitoral, mas eu me explico:

Na época em que um juiz determinou o bloqueio do youtube, porque uma certa pessoa famosa decidiu satisfazer uma das necessidades básicas do ser humano em um lugar público, e foi filmada, o tal serviço de vídeos era pouco utilizado pelos brasileiros em geral. Eram poucas pessoas que tinham o costume de perder alguns minutos/horas do seu dia procurando vídeos interessantes no youtube.

Depois da publicação do tal vídeo e seguinte proibição, o youtube ganhou uma enorme quantidade de propaganda gratuita nos mais diversos meios de informação, desde os jornais mais importantes do país até as programas matinais de fofoca(esse mais pelo conteúdo do vídeo do que pela atitude chinesa de proibição).

É logico que o twitter não vai ter ao seu lado os programas de fofoca, ou as rodinhas de bar para estimular a divulgação da medida, mas a blogosfera, e os meios de comunicação sérios têm quase que obrigação de divulgar o assunto (Na blogosfera eu já vi grande repercussão, nos meios jurássicos tradicionais de comunicação, nem tanto).

Ah claro, não podemos esquecer do blog TwitterBrasil que foi, até agora, a única vítima real desse episódio. Eles foram bloqueados só porque o seu domínio lembra o nome do serviço que era alvo da censura. Pela burrada, eles mereciam um pedido oficial de desculpas e uma indenização por perdas e danos, mas pelo menos eles ganharam um pouco de divulgação junto com as notícias.

Se você chegou até aqui, e não ta sabendo de nada desse assunto:, Parabéns pela persistência na leitura, mas em que mundo você vive? Mais a respeito desse absurdo aqui

Posted in Coisas de Computeiro, O mundo a nossa volta | No Comments »

Fail - Test Site Inexistente, Rss Protegido

Posted by admin on September 9th, 2008

Certificação Java em Sorocaba

Eu, um pobre mortal, computeiro que usa a linguagem Java pra trabalhar, estou tentando tirar minha primeira certificação, SCJP. Comprei o voucher como todo candidato deve fazer, comprei o livro da Kathy Sierra como todo candidato deveria fazer, estudei, fiz os simulados, e então, quando eu achava que tinha estudado o suficiente para não perder os 330 reais passar no exame, eu entro no site da prometric e marco o meu exame.
Por comodidade, eu resolvi marcar em Sorocaba, a mesma cidade em que eu trabalho, pra não perder tanto tempo com deslocamento. Quatro dias antes da prova resolvo ligar no número indicado no site da prometric para confirmar o meu exame, e qual não é minha surpresa. “Esse telefone não existe”.
Entro em contato com a prometric, e dois dias depois, já na véspera do exame, eles me informam que realmente aquele test site não existe mais, e que eu devo remarcar para uma outra cidade se eu quiser fazer.
Muito bem. Duas semanas depois entro eu no mesmo site da prometric para ver os horários em outra cidade para eu fazer a minha prova, e que cidade eu encontro na lista? Sim, o maldito test site que não existe ainda consta na lista. De certo é pra enganar outro otário que acha que vai conseguir fazer a prova na mesma cidade em que mora.

Conteúdo protegido em feed

Que as empresas da era pré-internet não saibam usar convenientemente os novos meios de comunicação e informação trazidos pela internet é aceitável, sofrível, mas aceitável. Agora que empresas que nasceram na internet e para a internet não saberem utilizar essas ferramentas, já é um insulto aos usuários.
Pois regularmente eu me deparo com feeds rss que exibem apenas o link para a página da notícia (até ai, nada de errado), e que ao clicar nesse link mostram que o conteúdo é protegido apenas para assinantes do serviço.
O campeão dessa modalidade é o UOL, só tenho o feed do uol música, porque ainda não achei outro melhor com esse tipo de conteúdo, mas quase todo dia, clico em um item, e este me leva a uma página de autenticação.
Outro que as vezes pisa na bola é o IDGNow, que pede que eu me cadastre no site para poder ler a notícia. Oras, eu uso rss porque eu não quero ter o trabalho de ficar acessando sites, lembrando de senhas, e ele vem me pedir cadastro???
Pro inferno.

Posted in Coisas de Computeiro, O mundo a nossa volta | No Comments »