sexta-feira, 27 de novembro de 2009

DATA no SQL


Muitos sistemas fazem várias pesquisas e cálculos utilizando datas e horas. Existem várias formas de fazer isso em delphi, Java e outras linguagens, mas a melhor forma ainda é, no caso de uma adição fixa, fazer isso no SQL. Vou colocar aqui alguns exemplos de funções específicas para DATA e HORA que o firebird possui.


DATEADD()

Available in: DSQL, PSQL
Added in: 2.1
Description: Adds the specified number of years, months, days, hours, minutes, seconds or milliseconds to a date/time value.
Result type: DATE, TIME or TIMESTAMP
Syntax: 
DATEADD ()
 
args      ::=    TO 
                 | , , 
 
amount    ::=  an integer expression (negative to subtract)
unit      ::=  YEAR | MONTH | DAY
                   | HOUR | MINUTE | SECOND | MILLISECOND
datetime  ::=  a DATE, TIME or TIMESTAMP expression
·         The result type is determined by the third argument.
·         With DATE arguments, only YEAR, MONTH and DAY can be used.
·         With TIME arguments, only HOUR, MINUTE, SECOND and MILLISECOND can be used.
Examples: 
dateadd (28 day to current_date)
dateadd (-6 hour to current_time)
dateadd (month, 9, DateOfConception)
dateadd (minute, 90, time 'now')
dateadd (? year to date '11-Sep-1973')





DATEDIFF()

Available in: DSQL, PSQL
Added in: 2.1
Description: Returns the number of years, months, days, hours, minutes, seconds or milliseconds elapsed between two date/time values.
Result type: BIGINT
Syntax: 
DATEDIFF ()
 
     ::=   FROM  TO 
                | , , 
 
     ::=  YEAR | MONTH | DAY
                  | HOUR | MINUTE | SECOND | MILLISECOND
  ::=  a DATE, TIME or TIMESTAMP expression
·        DATE and TIMESTAMP arguments can be combined. No other mixes are allowed.
·        With DATE arguments, only YEAR, MONTH and DAY can be used.
·        With TIME arguments, only HOUR, MINUTE, SECOND and MILLISECOND can be used.
Computation: 
·         DATEDIFF doesn't look at any smaller units than the one specified in the first argument. As a result,
o        datediff (year, date '1-Jan-2009', date '31-Dec-2009')” returns 0, but
o        datediff (year, date '31-Dec-2009', date '1-Jan-2010')” returns 1
·         It does look, however, at all the bigger units. So:
o        datediff (day, date '26-Jun-1908', date '11-Sep-1973')” returns 23818
·         A negative return value indicates that moment2 lies before moment1.
Examples: 
datediff (hour from current_timestamp to timestamp '12-Jun-2059 06:00')
datediff (minute from time '0:00' to current_time)
datediff (month, current_date, date '1-1-1900')
datediff (day from current_date to cast(? as date))






http://www.firebirdsql.org/


terça-feira, 27 de outubro de 2009

Comando QuotedStr do Delphi

Um problema que temos no Delphi é colocar strings entre aspas, isso ocorre em vários momentos no desenvolvimento. Para isso foi ele fornece um metodo chamado QuotedStr:

procedure TForm1.Button1Click(Sender: TObject);
begin
        edit1.Text :=  QuotedStr('teste')+' isso';
end;

Usando a instrução continue em laços FOR

A instrução continue é usada para abandonarmos a iteração atual em um laço for ou while. Isso bem útil em determinadas situações, um exemplo bem claro disso, é um for onde você obtem um erro q deve ser tratado e deve pular a iteração atual e ir para a proxima iteração.

public class minha{
  public static void main(String[] args){
for(Tobjeto ob :listobj){
try{
ob.getfazalgumacoisa; 
} catch (Exception e) {
              system.out.println("Erro na iteração "+ob.toString);
              continue;
           } 
if(ob.seila!=null){
ob.fazseila(); 
} 
}
}
} 

No exemplo caso ocorra algum erro não ira continuar na iteração atual e chamar o metodo fazseila(). Um exemplo para testar o continue, vem do site www.arquivodecodigos.net:


public class Estudos{
  public static void main(String[] args){
    for(int i = 0; i < 20; i++){
      if(i % 2 == 0)
        continue;

      System.out.println(i); 
    } 
  }
}

terça-feira, 29 de setembro de 2009

DecimalFormat

Estive trabalhando com DecimalFormat e achei este exemplo do Handerson Ferreira Gomes na devmedia.com.br, facilitou muito o trabalho, então resolvi postar.

/**
* Exemplo de utilizacao da classe DecimalFormat para formatacao de
numeros.
*
* @author Handerson Ferreira Gomes
* @created June 11, 2002
*/
public class DecimalFormatExample {

/**
* Metodo de execucao da classe DecimalFormatExample
* @param args Um modelo de formatacao para ser utilizado pela
aplicacao
*/

public static void main(String[] args) {
Locale locale = Locale.getDefault();
System.out.println("Este Sistema Operacional usa atualmente as
seguintes Configuracoes (Default):");
System.out.println("Pais : " + locale.getDisplayCountry());
System.out.println("Lingua/Teclado : " +
locale.getDisplayLanguage() + " - " + locale.getDisplayName());
System.out.println("");

DecimalFormat formatador = new DecimalFormat();
double valor1 = 235040.30;
float valor2 = -235040.30f;
int valor3 = 235040;
String valor4 = "235040.30";

System.out.println("Numeros sem formatacao:");
System.out.println("Valor 1 : " + valor1);
System.out.println("Valor 2 : " + valor2);
System.out.println("Valor 3 : " + valor3);
System.out.println("Valor 4 : " + valor4);
System.out.println();

System.out.println("Numeros utilizando a formatacao Default:");
System.out.println("Valor 1 : " + formatador.format(valor1));
System.out.println("Valor 2 : " + formatador.format(valor2));
System.out.println("Valor 3 : " + formatador.format(valor3));
System.out.println("Valor 4 : " + formatador.format(new
java.math.BigDecimal(valor4)));
System.out.println();

System.out.println("Utilizando o Pattern: R$ 000,000.00;R$
(000,000.00)");
formatador.applyPattern("R$ 000,000.00;R$ (000,000.00)");
System.out.println("Valor 1 : " + formatador.format(valor1));
System.out.println("Valor 2 : " + formatador.format(valor2));
System.out.println("Valor 3 : " + formatador.format(valor3));
System.out.println("Valor 4 : " + formatador.format(new
java.math.BigDecimal(valor4)));
System.out.println();

if (args.length > 0) {
String pattern = "";
for (int i = 0; i < args.length; i++) { 

pattern += args[i] + " "; 

pattern = pattern.trim(); 
System.out.println("Utilizando o Pattern: " + pattern); 
try { 
formatador.applyPattern(pattern);
System.out.println("Valor 1 : " + formatador.format(valor1));
System.out.println("Valor 2 : " + formatador.format(valor2));
System.out.println("Valor 3 : " + formatador.format(valor3)); 
System.out.println("Valor 4 : " + formatador.format(new java.math.BigDecimal(valor4))); 
} catch (IllegalArgumentException e) { 
System.out.println("ERRO: Pattern invalido.");
System.out.println(e.getMessage()); }
} else { 
System.out.println("Voce pode enviar um pattern como argumento para a aplicacao. Ex:"); System.out.println("java DecimalFormatExample U$ 000.00");
}
}
}

quinta-feira, 24 de setembro de 2009

Bibliotecas e docs no Netbeans

Estava eu instalando o jCalendar no netbeans quando me deparei com um problema. Quando criei a biblioteca onde iria colocar o jCalendar fui colocar os docs e na janela que abriu somente teria a opção de selecionar e mostrar arquivos .jar e .zip. Como o jCalendar disponibilizava os docs em html (“como na maioria dos projetos”), os arquivos docs não podiam ser selecionados, então resolvi postar uma pergunta num fórum, pois provavelmente a IDE(Netbeans 6.7), deveria ter uma opção para adicionar os docs em formato html. Não demorou 5 minutos para obter a resposta, na janela onde somente podem ser selecionados arquivos jar ou zip, selecione o diretório, isso mesmo, somente o diretório onde estão os arquivos html. Abaixo uma imagem da tela do Netbeans onde gerenciamos as bibliotecas:



sexta-feira, 11 de setembro de 2009

Criar serviço do MYSQL no windows

Essa pequena classe cria um novo serviço no windows com o nome "mysqymeu" e starta o mesmo. Não irei explicar o código pois e de fácil entendimento. Criei um tópico no GUJ, com dúvidas de como executar um comando no cmd do Windows caso alguém queira dar uma olhada.

Consumo de Memória

Estive observando um sistema que estou desenvolvendo através do sistema Visual VM.

Para quem não sabe VisualVM é uma ferramenta para observar aplicações Java, ele se encontra dentro da JDK\bin\, e disponibiliza várias informações, classes, objetos, memória, etc.

Bom, com ele eu me deparei com um suposto problema, no qual meu software estava cada vez mais aumentando o consumo de memória, e o GC não estava dando conta de liberar os recursos utilizados pelo sistema. Postei a dúvida em fóruns, procurei no código referências a objetos que não estava mais utilizando, etc etc etc. Como não obtive sucesso resolvi fazer mais alguns testes no Visual VM pois tinha notado que meu código não poderia estar errado. Para esse novo teste resolvi estipular a quantidade de memória que o meu sistema ira utilizar.

Para fazer isso utilizando o Netbeans fiz da seguinte forma:

1 – Clique invertido sobre o seu projeto;

2 – Clique em propriedades;

3 – Em categorias selecione “executar”;

4 – No campo Opções da VM coloque “-Xms64m –Xmx128m”;

Pronto!

Seu sistema estará alocando no mínimo 64 e no Maximo 128 megas de memória;

Xms - size initial Java heap size

Xmx - set maximum Java heap size

Fazendo isso percebi que o GC trabalhava muito mais do que antes, mas não deu estouro de memória, isso porque o GC é mais esperto do que eu pensava, e na realidade ele vai limpando a memória de acordo com a necessidade.

Links.:

http://java.sun.com/javase/6/docs/technotes/guides/visualvm/index.html

https://visualvm.dev.java.net/

http://blogs.sun.com/watt/resource/jvm-options-list.html

terça-feira, 8 de setembro de 2009

LER e ESCREVER em .properties

Estava eu desenvolvendo um sistema onde cada usuário poderá customizar alguns detalhes isso significa que deveria salvar algumas informações para cada usuário, não querendo salvar esse tipo de informação no banco de dados resolvi utilizar os arquivos properties.

Quem nunca teve contato com um arquivo “propertie” de uma procurada no oráculo google e veja q são muito simples e muito utilizados. Trata-se de um arquivo texto que contem uma estrutura similar a isso:

Nome1 = Rodrigo

Idade1 = 99

Nome2 = Mabel

Idade2 = 99

Assim nós podemos localizar facilmente a Idade2 ou outras propriedades quaisquer que estejam salvos no arquivo.

Para isso criei um arquivo denominado “configuracao.properties” e coloquei direto na pasta raiz do meu sistema, junto com outros arquivos como os logs de erros que costumo colocar ali.

Crie um File para apontar para o arquivo:

private File file = new File("configuracao.properties");

Crie um método que escreva no arquivo as propriedades que você quer salvar:

public void UpdateDados(){

try {

Properties props = new Properties();

FileOutputStream fis = new FileOutputStream(file);

props.setProperty("Nome1",”Rodrigo”);

props.setProperty("Idade1",String.valueOf(99));

props.store(fis, null);

fis.close();

} catch (IOException ex) {

logger.error("Problemas ao salvar dados no arquivo", ex);

}

}

E agora vamos criar um método para ler o arquivo e recuperar as informações gravadas:

public Boolean LoadDados() {

try {

Properties props = new Properties();

System.out.println(file.getAbsolutePath());

FileInputStream fis = new FileInputStream(file);

props.load(fis);

System.out.println(props.getProperty("Nome1"));

System.out.println(props.getProperty("Idade1"));

fis.close();

return true;

} catch (IOException ex) {

logger.error("Problemas ao selecionar dados do arquivo.", ex);

return false;

}

}

Esta aí um exemplo bem simples mas funcional.

quarta-feira, 15 de julho de 2009

Pegar clique e setas do teclado na jTable

Para nós podermos pegar ambos os comandos tanto de teclado como de mouse, já vi várias implementações, mas a melhor que eu achei é essa:

gridproduto.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) {
if (gridproduto.getSelectedRow() != -1) {
prod = modelo.getTprodutos(gridproduto.getSelectedRow());
System.out.println(prod.getNome());
}
});

Pelo simples fato desse método ser chamado somente quando a seleção mudar na jTable. Mas como nada é perfeito temos um probleminha nessa implementação, quando é utilizado o mouse para selecionar outra célula da jTable o código é executado duas vezes.

quinta-feira, 18 de junho de 2009

Carregando um Look and Feel

Quando estamos desenvolvendo sistemas desktops podemos utilizar diferentes L&F, por isto estarei postando aqui um código de como carregar um L&F de maneira bem simples e mostrando para quem nunca trabalhou com isso, uma forma simples e rápida de listar todos os L&F existentes na versão do Java existente em seu computador:

try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,
"Problems to change L&F. "+ex,
"ERRO",
JOptionPane.ERROR_MESSAGE);
}

Neste exemplo eu faço um laço passando por todos os L&F, caso possua o L&F Nimbus eu seto ele e caio fora do laço.

quinta-feira, 2 de abril de 2009

jTextfield receber so números

Uma boa pratica é fazer a verificação dos dados já na view. Isso deixa o processo mais rápido, pois o usuário já esta vendo o que esta fazendo de errado, ou se esta esquecendo de alguma coisa. Nesse pequeno código estamos testando se o usuário está digitando a coisa correta caso contrario não permitimos a escrita. Criamos um addKeyListener, (keyTyped):

private void txtsenhaKeyTyped(java.awt.event.KeyEvent evt) {

char c = evt.getKeyChar() ;

if (! ((c==KeyEvent.VK_BACK_SPACE) ||

(c==KeyEvent.VK_DELETE) || (c== KeyEvent.VK_ENTER) ||

(c == KeyEvent.VK_TAB) || (Character.isDigit(c)))) {

evt.consume() ;

}

}

quinta-feira, 19 de março de 2009

Efeitos em jLabel

Não gosto muito dos jButtons do swing, então resolvi utilizar as jLabels como botões, para isso criei alguns efeitos nas jLabels, achei melhor criar uma única classe, para que ao alterar a mesma todos os meus botões sofressem a mudança. Para isso criei uma classe bem simples e estou postando aqui caso alguém também resolva fazer algum efeito em jLabels, eu altero a cora da fonte a cor do fundo e a borda da jLabel.

import java.awt.Color;
import java.awt.Cursor;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.border.Border;

/**
*
* @author homisinho
*/
public class EfeitosV {
//Cor da fonte quando entra em botao
protected static Color fonteButtonEntered = new Color(0, 0, 0);
//Cor da fonte quando sai em botao
protected static Color fonteButtonExited = new Color(3, 103, 213);
//Cor do background entra em botao
protected static Color BackgButtonEntered = new Color(204, 204, 204);
//Cor do background sai em botao
protected static Color BackgButtonExited = new Color(214, 217, 223);
//Borda entra botao
protected static Border BordaButtonEntered = BorderFactory.createLineBorder(new Color(0,0,0));
//Borda sai botao
protected static Border BordaButtonExited = BorderFactory.createLineBorder(new Color(214,217,223));


public static JLabel getButtonEfectEntered(JLabel lbl){
if (lbl.isEnabled()) {
lbl.setForeground(fonteButtonEntered);
lbl.setBackground(BackgButtonEntered);
lbl.setBorder(BordaButtonEntered);
}
return lbl;
}

public static JLabel getButtonEfectExited(JLabel lbl){
if (lbl.isEnabled()) {
lbl.setForeground(fonteButtonExited);
lbl.setBackground(BackgButtonExited);
lbl.setBorder(BordaButtonExited);
}
return lbl;
}


}

Mascara para IP (com ER)

Estava eu procurando uma forma de criar uma mascara em um jtextfield, para certificar que o usuário digitou um IP válido. Depois de muita procura no google, encontrei um exemplo que utiliza expressões regulares para testar o valor digitado pelo usuário.
Para isso coloque um jFormattedTextfield em um jFrame qualquer crie a seguinte classe:

import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.text.DefaultFormatter;

/**
*
* @author homisinho
*/
public class RegexFormatter extends DefaultFormatter {
private Pattern pattern;
private Matcher matcher;

public RegexFormatter() {
super();
}

public RegexFormatter(String pattern) throws PatternSyntaxException {
this();
setPattern(Pattern.compile(pattern));
}

public RegexFormatter(Pattern pattern) {
this();
setPattern(pattern);
}

public void setPattern(Pattern pattern) {
this.pattern = pattern;
}

public Pattern getPattern() {
return pattern;
}

protected void setMatcher(Matcher matcher) {
this.matcher = matcher;
}

protected Matcher getMatcher() {
return matcher;
}

@Override
public Object stringToValue(String text) throws ParseException {
Pattern pattern = getPattern();

if (pattern != null) {
Matcher matcher = pattern.matcher(text);

if (matcher.matches()) {
setMatcher(matcher);
return super.stringToValue(text);
}
throw new ParseException("Pattern did not match", 0);
}
return text;
}

}


E coloque o seguinte código em seu jFrame para utilizar a expressão regular:

///expressão regular para controlar o IP valido
String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
Pattern p = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$");
RegexFormatter ipFormatter = new RegexFormatter(p);
txtip.setFormatterFactory(new DefaultFormatterFactory(ipFormatter));
/////////////////////////////////////////


No lugar de “txtip” coloque o nome do seu jFormattedTextfield. Encontrei esse exemplo no site http://www.gamedev.net, caso tenha dúvidas com expressões regulares de uma procurada no google.

quinta-feira, 15 de janeiro de 2009

Fabrica de sessoes do hibernate

Me deparei com um problema de como alterar a configuração do hibernate em run, pois o usuário terá a opção de escolher o caminho de instalação do software. Para resolver isso utilizei o arquivo hibernate.cfg.xml somente configuro o path do arquivo do banco de dados em run time. Segue a classe que criei, a fabrica de sessões do hibernate:

public class HibernateUtil {
private static final AnnotationConfiguration cfg =
new AnnotationConfiguration();
private static Session session;

static {
try {
cfg.configure("hibernate.cfg.xml");
File arquiv = new File(cfg.getProperty("nome.banco"));
cfg.setProperty("hibernate.connection.url","jdbc:firebirdsql:localhost/3050:"+arquiv.getAbsolutePath());
session = cfg.buildSessionFactory().openSession();
} catch (Throwable ex) {
System.out.println(ex.getMessage());
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static Session getSession(){

if (session == null) {
try {
cfg.configure("hibernate.cfg.xml");
File arquiv = new File(cfg.getProperty("nome.banco"));
cfg.setProperty("hibernate.connection.url","jdbc:firebirdsql:localhost/3050:"+arquiv.getAbsolutePath());
session = cfg.buildSessionFactory().openSession();
}
catch (Exception e) {
System.err.println("Initial SessionFactory creation failed." + e);
throw new ExceptionInInitializerError(e);
}

}
return session;
}
}

Opções da jTable

Vou colocar algumas opções importantes da jTable.
Vamos começar com a largura das células, pra terminar com os ... no final das strings, pelo menos da maioria, pois caso a string seja grande mesmo, com múltiplas linhas, seria necessário a utilização de html ou implementar um jTextArea. Essa linha simplesmente possibilita a alteração da largura da coluna:

jTable1.getColumnModel().getColumn(n).setPreferredWidth(m);

n = coluna da tabela ‘inicia em 0 ’;
m = largura em px da coluna;

Também podemos configurar a altura das linhas da tabela:

jTable1.setRowHeight(m);

m= altura em px das linhas;

Outra opção importante é a reordenação das colunas, caso você tenha implementado um renderer e no mesmo você utilizou a variável column a reordenação feita pelo usuário se tornaria um problema. Podemos bloquear a reordenação das colunas:

jTable1.getTableHeader().setReorderingAllowed(false);


Também podemos bloquear a alteração da largura das colunas:

jTable1.getTableHeader().setResizingAllowed(false);

quinta-feira, 8 de janeiro de 2009

Utilizando jxTable do swingx



Após instalar os componentes do swingx fiz alguns testes, e fiquei quebrando a cabeça na utilização do jxTaskpane e jxTable.

São componentes visuais muito legais e que já facilitam um pouco a vida do programador.

Criei uma classe modeloTabUsuario que extendia AbstractTableModel, o problema que mais demorei pra resolver foi uma falha de digitação no método que sobrescrevia getColumnName, pois os nomes das colunas da minha jxtable ficava com as letras do alfabeto. Segue a classe de teste criada por mim:



public class modeloTabUsuario extends AbstractTableModel{

private ArrayList datalist = new ArrayList();

private String[] columns = {"Nome","Login","Tipo"};

public modeloTabUsuario(Collection l){

datalist.addAll(l);

}

public modeloTabUsuario(){

}

public void addUsuarios(Usuarios usu){

datalist.add(usu);

fireTableDataChanged();

}

public void addListUsuarios(Collection list){

datalist.addAll(list);

fireTableDataChanged();

}

public Usuarios getUsuario(int rows){

if (getRowCount() >= rows ){

return (Usuarios) datalist.get(rows);

}else return null;

}

@Override

public String getColumnName(int col){

return columns[col];

}

public String[] getColumns(){

return columns;

}

@Override

public Class getColumnClass(int c) {

return getValueAt(0, c).getClass();

}

public int getRowCount() {

return datalist.size();

}

public int getColumnCount() {

return columns.length;

}

public Object getValueAt(int rowIndex, int columnIndex) {

Usuarios usu = getUsuario(rowIndex);

switch (columnIndex) {

case 0:

return usu.getNome();

case 1:

return usu.getLogin();

case 2:

int tp = usu.getTipo();

if(tp == 0){

return new String("Restrito");

}

if(tp == 1){

return new String("Normal");

}

if(tp == 2){

return new String("Supervisor");

}

if(tp == 3){

return new String("Empresa");

}

default:

return null;

}

}

}

Nos testes ate agora tudo certo com o swingx, acredito que irei utilizar o mesmo nas minhas aplicações futuras.