Jan 10

2009′un ilk günlerinde biz yazılımcılar yazılım dünyasında ne gelişmeler olacağını merak ediyoruz. Bunun için 2008′e şöyle bir bakmak gerek. Biraz 2008′de uğraştığım teknolojiler,okuduğum makaleler, biraz da Devoxx 2008′de izlediğim sunumların etkisiyle 2008′de gözde olan teknolojilerin, 2009′da neler olacağının muhabbetini yapmak istedim.

1.OSGi

OSGi yeni bir teknoloji değil. Ancak son yıllarda özellikle popüler olmuş durumda. Eclipse ‘in alt yapısını oluşturan Eclipse Equinox frameworkunun OSGi implementasyonu olması OSGi ‘nin java uygulama geliştirenler açısından ne kadar önemsendiğini gösteren sebeplerden sadece biri. Ama OSGi 2009 listeme almamdaki asıl sebep OSGi ‘nin uygulama sunucularında yaygın olarak kullanılması ile iteratif yazılım geliştirme süresini önemli ölçüde azaltacak olması.SpringSource dm Server bu iddayla yola cıkan ilk uygulama sunucusu olarak Ağustos ayında uygulama sunucusu dünyasına giriş yaptı. Uygulama sunucusu dünyasının “baba” larından JBoss ve Sun da bu yönde yenilikler yaptı. GlassFish v3 Prelude OSGi tabanlı yazıldı. JBoss cephesinde ise JBoss AS 5.0.0 GA kendi component mimarisinin yanında OSGi destekleyecek şekilde yakın zamanda çıktı.

2.RESTful web services

2008′de Service Oriented Architecture yanında Resource Oriented Architecture da konuşulur oldu.JAX-RS: Java API for RESTful Web Services (JSR-311) RESTful web servisleri konusunda çalışan JSR.  Bense Devoxx 2008′de izlediğim Kauri frameworkunden bahsetmek istiyorum biraz. Kauri, Restlet, Spring, Maven and jQuery i kullanan ve RESTful web servisleri, web uygulamaları geliştirmeye yarayan bir framework.  Resource lar URL ‘ler şeklinde sunuluyor. Gerçekleştirilen her bir modul maven repository sinde bir jar olarak install ediliyor, ve daha sonraki web uygulamalarında kolaylıkla kullanılabiliyor. Bu şekilde arama yapan bir “search” servisini 1 kere yazıp tüm web uygulamalarında kullanabilmek mümkün.

3.Java SE 7 ve Universal VM

Java SE 6′dan Java SE 7′ye geçişin etkisinin, J2SE 1.4 ‘ten J2SE 5 ‘e geçişin etkisine oranla çok daha büyük olacağını düşünüyorum. Java SE 7 ile gelmesi beklenen yeni özelliklerin (daha kesinleşmiş bir özellik seti yok) dışında en büyük yeniliğin platform bazında olacağını bekliyorum.

JVM doesn’t know anything about Java

JVM Specification,1997

Aslında şu anki durumda da Java ile birlite scripting dillerini kullanmak mümkün. Ama ilk defa Sun bu dinamik diller için hafıza yönetimi, güvenlik gibi özellikleri JVM’e ekleyecek. Bunun için “invokedynamic” adlı yeni bir bytecode’un JVM’e eklenmesi bekleniyor. JSR-292 ile Java platformunda Java dışında dillerin çalıştırılması kolaylaşacak, bu da Java geliştiricelerinin işine yarayacak. JVM artık sadece Java  diline hizmet etmekten çıkacak.

4.Java FX

Asıl mesele RIA(Rich Internet Applications)…Flash,Flex, Silverlight kullanmamış biri olarak Java FX’i beğendiğimi söyleyebilirim:) Devoxx 08′de izlediğim Java FX keynote ‘u nu oldukça beğendim.  Joshua Marinacci demo sırasında firefox içinde çalışan MoviePuzzle uygulamasını firefoxtan çıkarıp masaüstüne çektiğinde salondan alkışlar yükseldi:)  Üstelik firefox’u kapatmasına rağmen uygulamanın masaüstünde çalışmaya devam etmesi ayrı güzeldi. Javaya benzer syntax i, grafikçilerin beğenerek kullandığı toollardan ( şu an sadece Adobe Photoshop,Adobe Illustrator için) import pluginleri sunması başarılı olacağına inanmamı sağlayan sebeplerden ikisi. Bir diğeri, belki de en önemlisi, Sun ‘ın artık Swing’i desteklemeyeceğini JVM Language Summit 2008′de açıklamış olması. Bu da Sun’ın istemci teknolojisi kısmında Java FX’e verdiği önemi gösteriyor. İlgilenenlere NetBeans 6.5 la gelen örneklerle göz atabilirler.

Kaynaklar

yazan sezer

Nov 28

duke-danceBu yazımızda JSF Richfaces Hibernate Spring teknolojilerini kullanarak bir ToDo uygulaması yapacağız. Bu uygulamada yapılacaklar listesi tutulacak ve bu liste arasında arama yapabileceğiz. Bu yapacağımız uygulamanın en güzel özelliği ise herşeyi AJAX ile yapıyor olmamız.

Projeye başlamadan önce kullanılan teknolojiler üzerinden geçmemiz iyi olacak.

JSF : Java’nın component tabanlı web geliştirme kütüphanesi. MyFaces 1.2 versiyonu kullanılıyor.
Richfaces : Gene JSF implementasyonu olan bu kütüphane bize zengin AJAX desteği sunuyor. 3.2.2.SR1 versiyonu kullanılıyor.
Hibernate : Hibernate ile birlikte Database işlemleri Obje tabanlı yapılmakta. 3.2.1.ga versiyonu kullanılıyor
Spring : Spring benim olmaz ise olmaz kütüphanelerimden. Spring ile birlikte J2EE’nin tüm nimetlerinden bir Application Server’a(JBoss, Glassfish gibi) ihtiyacınız olmadan yararlanabilirsiniz. 2.5.1 versiyonu kullanılıyor.

Veritabanı olarak HsqlDB kullanmaktayım. Veritabanı “on the fly” yaratıldığı için her uygulamayı başlattığınızda eski datalar yok olacaktır. İsterseniz siz bunun yerine MySql kullanabilirsiniz.

Projeyi çalıştırmak için bilgisayarınızda Maven kurulu olması gerekiyor. Ama “Maven nedir?” diyorsanız buradan gerekli bilgiyi öğrenebilirsiniz.

Aşağıdan Todo Ekleme, Listeleme ve Arama sayfalarını görebilirsiniz

TODO Listeleme

TODO Arama

Projeyi çalıştırmak için önce proje kodunu indirin.

Download: Javacı Todo Uygulaması  Javacı Todo Uygulaması (21.4 KiB, 420 hits)

İndirme işlemini tamamladıktan sonra proje dosyalarını sıkıştırılmış dosyadan çıkartıp, o klasöre konsoldan giriş yapınız.
Projeyi çalıştırmak için konsolda mvn jetty:run demeniz yeterli olacaktır. Gerisini Maven sizin için halledecektir.

Şimdi biraz da kodu inceleyelim.

1 tane model sınıfımız var. Veritabanı işlemlerimizi bu model sınıfı ile yapıyoruz.

package net.javaci.todo.domain;
 
import java.io.Serializable;
import java.util.Date;
import java.util.Calendar;
 
import javax.persistence.*;
 
@Entity
public class Todo implements Serializable{
 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
 
    @Basic
    private String title;
 
    @Basic
    @Lob
    private String description;
 
    @Basic
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date publishedDate;
 
    public Todo() {
        this.publishedDate = Calendar.getInstance().getTime();
    }
 
     public Todo(String title, String description) {
	this.title = title;
	this.description = description;
        this.publishedDate = Calendar.getInstance().getTime();
     }
 
    public long getId() {
        return id;
    }
 
    public void setId(long id) {
        this.id = id;
    }
 
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String title) {
        this.title = title;
    }
 
    public String getDescription() {
        return description;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
    public Date getPublishedDate() {
        return publishedDate;
    }
 
    public void setPublishedDate(Date publishedDate) {
        this.publishedDate = publishedDate;
    }
}

DAO(Data Access Object) sınıfımız sayesinde veritabanı üzerinde yapacağımız işlemleri belirliyoruz. Ayrıca DAO sayesinde ileride teknoloji değişikliği yapacaksak kolay entegre etmemizi sağlıyor. Mesela bir bu projede JPA(Java Persistence API) kullandık.

package net.javaci.todo.dao.jpa;
 
import org.springframework.stereotype.Repository;
import javax.persistence.Query;
 
import net.javaci.todo.domain.Todo;
import net.javaci.todo.dao.jpa.GenericDaoWithJpa;
import net.javaci.todo.dao.TodoDao;
 
import java.util.List;
 
@Repository
public class TodoDaoJpa extends GenericDaoWithJpa<Todo,Long> implements TodoDao {
 
    public List<Todo> getAllTodo() {
        return this.loadAll();
    }
 
    public List<Todo> findByTitle(String title) {
        Query query = entityManager.createQuery("Select t from Todo t where t.title like ?1");
	query.setParameter(1, title + "%");
 
	return query.getResultList();
    }
 
    public List<Todo> findByDescription(String description) {
        Query query = entityManager.createQuery("Select t from Todo t where t.description like ?1");
	query.setParameter(1, description + "%");
 
	return query.getResultList();
    }
}

JSF ve Spring ikilisinin diğer bir özellikleri ise bizi MVC(Model-View-Controller) pattern’ına zorlamasıdır. Yukarıda Model ve Controller’dan bahsettik. Şimdi ise View’den bahsedelim.

Her bir işlem için ayrı Backing Bean ekledim. Backing Bean’lerin özellikleri JSF web arayüzündeki işlemleri karşılamalarıdır. Bunu eğer .NET kullandıysanız web sayfası üzerindeki buttona işlem atamak için çift tıkladığınızda gelen sayfaya eştir.

Arama için gerekli olan Backing Bean’i aşağıda görebilirsiniz.

package net.javaci.todo.view;
 
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.ArrayList;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import net.javaci.todo.domain.Todo;
import net.javaci.todo.service.TodoService;
 
@Component("searchTodo")
@Scope("request")
public class SearchTodo implements Serializable{
 
    private Todo todo = new Todo();
    private List<Todo> result;
 
    @Autowired
    private TodoService todoService;
 
    public Todo getTodo() {
        return todo;
    }
 
    public void setTodo(Todo todo) {
        this.todo = todo;
    }
 
    public List<Todo> getResult() {
        return result;
    }
 
    public void setResult(List<Todo> result) {
        this.result = result;
    }
 
    public String search() {
        Set<Todo> s = new HashSet<Todo>();
        if(todo != null) {
            if(!todo.getTitle().equals("")) {
                s.addAll(todoService.findByTitle(todo.getTitle()));
            }
            if(!todo.getDescription().equals("")) {
                s.addAll(todoService.findByDescription(todo.getDescription()));
            }
        }
 
        result = new ArrayList<Todo>(s);
        return null;
    }
}

Bu Backing Bean’e karşılık gelen JSF Web Arayüzünü de aşağıda görebilirsiniz.

 <h:panelGrid id="todosearchgrid" columns="2">
     <h:outputLabel for="titlesearch" value="Başlık" />
     <h:inputText id="titlesearch" value="#{searchTodo.todo.title}" />
 
     <h:outputLabel for="descsearch" value="Açıklama" />
     <h:inputText id="descsearch" value="#{searchTodo.todo.description}" />
 
     <h:outputLabel/>
     <a4j:commandButton value="Arama Yap" action="#{searchTodo.search}" reRender="todosearchresult" />
 </h:panelGrid>

Yukarıda görüldüğü gibi searchTodo.search çağırımı ile searchTodo Backing Bean’i içerisindeki search methodu çağırılıyor. Çağırım işlemi tamamlandıktan sonra da todosearchresult datayı göstermek için yenileniyor.

Sonuç olarak Java ile kolay ve hızlı web siteleri geliştirelebilir. Eğer rol tabanlı kullanıcı kontrolü de eklemek istiyorsanız Spring Security kullanabilirsiniz. Bunu ileriki yazılarımda göreceksiniz.

yazan Erol KOCAMAN \\ tags: , , , , ,

Nov 24

Aşağıda basit bir hafıza oyunu bulacaksınız. Oyunun amacı gizlenmiş birbirinin aynı olan ikili simgeleri bulmak.

Oyunu çalıştırabilmek için Java 6 kullanmanız gerekecek.

SwingWorker sınıfını kullandım ve bu sınıf Java 6 ile gelen bir özellik. Eğer Java 6 sürümü kurulu değil yine de kodu çalıştırmak istiyorsanız, resetButton methodunu aşağıdaki gibi değiştirin.

    private void resetButton(final JButton fButton, final JButton sButton) {
        fButton.setForeground(FAILURE);
        sButton.setForeground(FAILURE);
 
        try {
            // 2 sn bekle
            Thread.sleep(2000);
        } catch(Exception exc) {}
 
        fButton.setText(DEFAULT_STR);
        fButton.setForeground(DEFAULT);
        sButton.setText(DEFAULT_STR);
        sButton.setForeground(DEFAULT);
    }

Aşağıdaki kodu indirin.

Download: Game  Game (4.3 KiB, 261 hits)

javac Game.java

komutu ile derleyin

java Game

komutu ile konsoldan çalıştırın.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
 
 
public class GUI extends JFrame implements ActionListener {
    private int n = 0;
    private JButton buttons[][];
    private String[][] hiddens;
    private JButton firstButton, secondButton;
    private String SPLITTER = ":";
    private String DEFAULT_STR = "X";
    private Color DEFAULT = Color.BLACK;
    private Color SUCCESS = Color.BLUE;
    private Color FAILURE = Color.ORANGE;
 
    public GUI() {
        try {
            do {
                String nStr = JOptionPane.showInputDialog("Çift sayı giriniz:");
                n = Integer.parseInt(nStr);
            } while(n%2!=0);
        } catch(NumberFormatException exc) {
            JOptionPane.showMessageDialog(null, "Lütfen geçerli sayı giriniz!");
            System.exit(1);
        }
 
        fillHiddens(n);
        init();
 
        setSize(600, 600);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
 
    private void init() {
        Container c = this.getContentPane();
        c.setLayout(new GridLayout(n, n));
 
        buttons = new JButton[n][n];
        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                buttons[i][j] = new JButton(DEFAULT_STR);
                buttons[i][j].setForeground(DEFAULT);
                buttons[i][j].setFont(new Font("", Font.BOLD, 18));
                buttons[i][j].addActionListener(this);
                buttons[i][j].setActionCommand(i + SPLITTER + j);
                c.add(buttons[i][j]);
            }
        }
    }
 
    private void fillHiddens(int h) {
        java.util.List<String> list = new ArrayList<String>();
 
        for(int i=0; i<h; i++) {
            for(int j=0; j<h/2; j++) {
                String randomStr = generateRandomString();
                while(list.contains(randomStr) || randomStr.equals(DEFAULT_STR)) {
                    randomStr = generateRandomString();
                }
                list.add(randomStr);                
            }
        }
 
        hiddens = new String[h][h];
        for(String str : list) {
            int i, j;
            do {
                i = (int)(Math.random()*h);
                j = (int)(Math.random()*h);
            } while(hiddens[i][j] != null);
            hiddens[i][j] = str;
 
            do {
                i = (int)(Math.random()*h);
                j = (int)(Math.random()*h);
            } while(hiddens[i][j] != null);
            hiddens[i][j] = str;
        }
    }
 
    private String generateRandomString() {
        return ((char)(30 + (int)(Math.random()*60))) + "";
    }
 
    public void actionPerformed(ActionEvent e) {
        if(!((JButton)e.getSource()).getText().equals(DEFAULT_STR)) {
            return;
        }
        String command = e.getActionCommand();
        String[] indexes = command.split(SPLITTER);
 
        int i = Integer.parseInt(indexes[0]);
        int j = Integer.parseInt(indexes[1]);
 
        if(firstButton==null) {
            firstButton = buttons[i][j];
            firstButton.setText(hiddens[i][j]);
            firstButton.setForeground(SUCCESS);
        }
        else {
            secondButton = buttons[i][j];
            secondButton.setText(hiddens[i][j]);
            secondButton.setForeground(SUCCESS);
 
            if(secondButton.getText().equals(firstButton.getText())) {
                // Puan hesaplaması burada yapılacak    
            }
            else {
                resetButton(firstButton, secondButton);
            }
 
            firstButton = null;
            secondButton = null;
        }
    }
 
    private void resetButton(final JButton fButton, final JButton sButton) {
        SwingWorker worker = new SwingWorker() {
            protected Object doInBackground() throws Exception {
                fButton.setForeground(FAILURE);
                sButton.setForeground(FAILURE);
 
                // 2 sn bekle
                Thread.sleep(2000);
 
                fButton.setText(DEFAULT_STR);
                fButton.setForeground(DEFAULT);
                sButton.setText(DEFAULT_STR);
                sButton.setForeground(DEFAULT);
                return null;
            }
        };
        worker.execute();
    }
 
    public static void main(String[] args) {
        new GUI();
    }
}

yazan Erol KOCAMAN \\ tags: