วันพุธที่ 18 มกราคม พ.ศ. 2555

How to Solve java.io.FileNotFoundException: (Access is denied)

        หลาย ๆ คนคงเคยเขียน java เกี่ยวกับการ Execute, Read, Write ไฟล์กันมาบ้างแล้ว สำหรับคนที่ Run บน Linux หรือ Window XP ก็คงจะไม่เคยเจอปัญหานี้ แต่ถ้าได้ลองนำ Source Code ไป Run บน Windows 7 ดูสิครับ เกิดเรื่องเลยครับทีนี้ เนื่องจากติดปัญหาเรื่อง Permission ใน Windows7 วิธีแก้ก็คือไปคลิกขวาที่ C:/ หรือที่ Folder แล้วก็เข้าไปกำหนดสิทธิ์ให้กับ user นั้น ๆ กรณีที่รันเป็น Administrator ก็จะไม่พบเจอปัญหานี้เช่นกัน
        แต่อย่างไรก็ตาม ในคลาสของ  java.io.File มี Method setExecutable, setReadable, setWritable เดี๋ยวจะลองเขียน Code ตัวอย่างดูนะครับ

ลอง check สิทธิ์ด้วยคลาส CheckPermission
 import java.io.FilePermission;  
 import java.security.AccessController;  
 /**  
  *  
  * @author Kotcharit  
  */  
 public class CheckPermission {  
   public static void main(String[] args) {  
     try {  
       AccessController.checkPermission(new FilePermission("C:\\", "read,write"));  
       System.out.println("You have permission : ^-^");  
     } catch (SecurityException e) {  
       System.out.println("You don't have permission : T_T");  
     }  
   }  
 }  

ลองทำตาม Code นี้
 import java.io.BufferedWriter;  
 import java.io.File;  
 import java.io.FileOutputStream;  
 import java.io.OutputStreamWriter;  
 /**  
  *  
  * @author Kotcharit  
  */  
 public class WritePermissionFile {  
   public static void main(String[] args) {  
     FileOutputStream outputFileStream = null;  
     OutputStreamWriter streamWriter = null;  
     BufferedWriter bufferedWriter = null;  
     try {  
       /*สร้างไฟล์ Test Permission.txt เปล่า ๆ ไว้ที่ C:/ ไดเร็กทอรี่*/  
       File config = new File("C:/Test Permission.txt");  
       /*----Set ค่าให้เป็น true ---*/  
       config.setExecutable(true);  
       config.setReadable(true);  
       config.setWritable(true);  
       /*-------------------------*/  
       outputFileStream = new FileOutputStream(config);  
       streamWriter = new OutputStreamWriter(outputFileStream);  
       bufferedWriter = new BufferedWriter(streamWriter);  
       bufferedWriter.write("Test write permission file");  
       System.out.println("Success");  
     } catch (Exception e) {  
       System.out.println("Error : " + e.getMessage());  
     } finally {  
       try {  
         bufferedWriter.flush();  
       } catch (Exception e) {  
       }  
       try {  
         bufferedWriter.close();  
       } catch (Exception e) {  
       }  
       bufferedWriter = null;  
       streamWriter = null;  
       outputFileStream = null;  
     }  
   }  
 }  

        เพียงแค่นี้เราก็แก้ปัญหาเรื่อง Access is denied ได้แล้ว ลองนำไปประยุกต์กันดูนะครับ
Read more!

วันอังคารที่ 10 มกราคม พ.ศ. 2555

Java : Designing a Swing GUI in Eclipse IDE

        บทความนี้สำหรับผู้ที่อยากจะลองเขียน Java Swing Application ด้วยการใช้ Tool ลากวาง เราจะใช้ Visual Swing for Eclipse ซึ่งเป็น plugin ของ Eclipse IDE (จริง ๆ แล้วมีหลายตัวมาก ๆ ครับ) งานนี้สาวก Eclipse มีเฮครับ เพราะก่อนหน้านี้ผมได้เขียนบทความที่ใช้ Tool ลากวางที่มีมาให้ใน Netbeans กันแล้ว คราวนี้ก็ถึงตาของ Eclipse แสดงความสามารถกันบ้าง แต่อย่างว่าแหละครับ ถ้าเป็นสาวก java ตัวจริง ก็อย่าไปยึดติดกับ Tool หรือว่า IDE ตัวไหนเลย(เมื่อก่อนผมสาวก Netbeans ครับ 555+)
        เอาหล่ะครับก่อนเริ่มผมก็คงต้องขอกล่าวเหมือนกับบทความก่อนหน้านี้ก็คือ การทำความเข้าใจใน Code ที่ตัว Tool ได้ Generate มาให้นั้น ก็ถือว่าเป็นสิ่งที่ดีครับ เพราะมันก็เหมือนเป็น Framework ตัวหนึ่ง ซึ่งวางโครงสร้างของการเขียน Code มาให้อยู่ในกรอบอย่างมีรูปแบบ ทำให้เราเข้าใจแนวคิดในการที่จะ Design โปรแกรมด้วย

        1. หากใครยังไม่ได้ติดตั้ง Eclipse ให้ติดตั้งเสียก่อน โดยดาวน์โหลดได้จาก  http://www.eclipse.org/downloads/ เลือก Eclipse IDE for Java Developers หลังจากดาวน์โหลดเสร็จให้ทำการแตกไฟล์ออกมา จากนั้นก็สามารถ ดับเบิ้ลคลิกไฟล์ eclipse.exe เพื่อใช้งานได้เลย ไม่ต้องทำการติดตั้ง


        

        2. ดาวน์โหลด Visual Swing for Eclipse จะได้ไฟล์ .zip มา ก็แตกไฟล์ไปไว้ที่ eclipse\plugins

        3. ทำการ Restart Eclipse ใหม่ ถึงตอนนี้เราก็จะสามารถใช้ plugin ตัวนี้กันได้แล้ว

        4. New Project...
                4.1 ไปที่ File-->New-->Java Project

                4.2 ใส่ Project Name: GPADemo เลือก JRE จากนั้นกดปุ่ม Finish

        5. New Package
                5.1 คลิกขวาที่ src เลือก New-->Package

                5.2 ใส่ Name: view จากนั้นคลิก Finish (เนื่องจากเราต้องการแยกแพกเกจออกเป็นส่วน ๆ ซึ่งส่วนนี้จะมีไว้เก็บคลาสที่เป็นหน้า UI เท่านั้น ไม่มีการทำงานใด ๆ)

                5.3 คลิกขวาที่ Packave view เลือก New-->Other... หรือ Ctrl+N

                5.4 ที่หน้า Select a wizard เลือก Visual Swing Class-->Frame จากนั้นกดปุ่ม Next >

                5.5 ที่หน้า Java Class ใส่ Name: UI จากนั้นกดปุ่ม Finish


                5.6 จะได้ดังรูปด้านล่าง จากนั้นให้คลิกที่ลูกศร  เนื่องจากเราจะทำการ Design หน้าจอกันก่อน โดยที่ยังไม่ต้องไปสนใจ Code Generate
ลูกศร


        6. Design GUI
                 ที่หน้าต่าง Palatte ก็จะมี Component มาให้สำหรับลากวางได้เลย โดยแยกเป็นหมวดหมู่

                เรามาเริ่ม Design หน้า UI กันดีกว่า โดยบทความนี้จะสร้างเป็นโปรแกรมคิดคำนวณเกรดเฉลี่ยแบบง่าย ๆ ที่หลาย ๆ คนคงคุ้นกันเป็นอย่างดี แต่อยู่ในรูปแบบ GUI ให้ลากวางตามรูปได้เลย จากนั้นให้กำหนด Property ให้แต่ละ Component ที่ tap Properties (ต้องคอยกด Save แล้ว F5 อยู่เรื่อย ๆ นะครับ แล้วจึงจะขึ้นให้)

                6.1  uI (JFrame) : ให้คลิกในส่วน Container ด้านในจึงจะประกฎ Property
                         title : GPA-Demo
                         bounds : (0,0,287,384)
                6.2 jLabel : 3 ตัว
                          text : จำนวน, วิชา, เกรดเฉลี่ย ตามลำดับ
                6.3 jTextField : 2 ตัว
                          jTextField0
                                  Bean Field Name : tfSubject
                                  foreground : (153,153,153)
                                  text : ใส่ตัวเลขแล้วกด Enter
                                  focusable : false (เอาเครื่องหมายถูกออก)
                          jTextField1
                                  Bean Field Name : tfResult
                                  enabled : false (เอาเครื่องหมายถูกออก)
                6.4 jButton0
                          Bean Field Name : btCal
                          text : คำนวณ
                6.5 jTable0 : ที่ method getJTable0() ให้แก้ไข code ดังนี้เพื่อกำหนดคุณสมบัติเพิ่มเติม (เนื่องจากผมเองไม่สามารถหาหรือกำหนด model ได้)
      private JTable getJTable0() {  
           if (jTable0 == null) {  
                jTable0 = new JTable();  
                jTable0.setModel(new DefaultTableModel(new Object[][] {}, new String[] { "ลำดับวิชา", "หน่วยกิจ","เกรดที่ได้" }) {  
                     private static final long serialVersionUID = 1L;  
                     Class<?>[] types = new Class<?>[] { Object.class, Integer.class,Double.class };  
                     boolean[] canEdit = new boolean []{  
                               false, true, true  
                     };  
                     public Class<?> getColumnClass(int columnIndex) {  
                          return types[columnIndex];  
                     }  
                     public boolean isCellEditable(int rowIndex, int columnIndex){  
                          return canEdit [columnIndex];  
                     }  
                });  
           }  
           return jTable0;  
      }  

                6.6 ทดสอบ run โปรแกรมด้วยการคลิกขวาที่ Project เลือก Run As-->2 Java Application หรือ คลิกขวาที่ jFrame แล้วเลือก Preview Design

        7. เขียน Code เพื่อให้โปรแกรมทำงาน
                7.1 เริ่มจากเขียนในส่วนของการควบคุม Component ต่าง ๆ ที่นอกเหนือจากการกำหนดใน Properties และการสร้างคลาสคำนวณเกรดเฉลี่ย โดยเริ่มจากสร้าง Package ชื่อ controller จากนั้นสร้าง จาวาคลาส 2 คลาส ชื่อว่า ControlUI.java และ Calculate.java จากนั้นเขียน Code ดังนี้

ControlUI.java        
 /*  
  * To change this template, choose Tools | Templates  
  * and open the template in the editor.  
  */  
 package controller;  
 import java.awt.Dimension;  
 import java.awt.Toolkit;  
 import javax.swing.table.DefaultTableModel;  
 /**  
  *  
  * @author T000Rxx  
  */  
 public class ControlUI {  
   int subject = 0;  
   DefaultTableModel model;  
   public ControlUI() {  
   }  
   public void setSubject(String n) {  
     subject = Integer.parseInt(n);  
   }  
   public int getSubject() {  
     return subject;  
   }  
   public void setModel(javax.swing.JTable tb) {  
     removeOldModel(tb.getRowCount());  
     model = (DefaultTableModel) tb.getModel();  
     for (int j = 0; j < getSubject(); j++) {  
       model.addRow(new Object[]{j + 1});  
     }  
   }  
   public void removeOldModel(int row) {  
     for (int i = 0; i < row; i++) {  
       model.removeRow(0);  
     }  
   }  
   public void innitComponentByDevelop(javax.swing.JFrame fm) {  
     Dimension fd = fm.getSize();  
     int w = fd.width;  
     int h = fd.height;  
     Dimension d = Toolkit.getDefaultToolkit().getScreenSize();  
     int x = (d.width - w) / 2;  
     int y = (d.height - h) / 2;  
     fm.setBounds(x, y, w, h);  
   }  
 }  

Calculate.java
 /*  
  * To change this template, choose Tools | Templates  
  * and open the template in the editor.  
  */  
 package controller;  
 import java.text.DecimalFormat;  
 import javax.swing.JTable;  
 /**  
  *  
  * @author T000Rxx  
  */  
 public class Calculate {  
   int subjectAmount = 0;  
   int listSubject[];  
   int listUnit[];  
   JTable tb;  
   double totalGrade;  
   int cumulativeCredit = 0;  
   public Calculate(javax.swing.JTable tb) {  
     this.tb = tb;  
     subjectAmount = tb.getRowCount();  
     listSubject = new int[subjectAmount];  
     listUnit = new int[subjectAmount];  
   }  
   public String calGrade() {  
     for (int i = 0; i < tb.getRowCount(); i++) {  
       cumulativeCredit+= Integer.parseInt(tb.getValueAt(i, 1).toString());  
       totalGrade+= Double.parseDouble(tb.getValueAt(i, 1).toString()) * Double.parseDouble(tb.getValueAt(i, 2).toString());  
     }  
     DecimalFormat dfm = new java.text.DecimalFormat("0.00");  
     return dfm.format(totalGrade/cumulativeCredit);  
   }  
 }  

        8. เขียน Code เพื่อกำหนด Action ของ component ต่าง ๆ ของคลาส UI
                8.1 เพิ่ม Code import ประกาศตัวแปรคลาส Control, Calculate และเพิ่ม Code ที่ Constructor ดังนี้ UI.java (ดูบรรทัดที่มี //<--Add)
import controller.ControlUI; //<--Add
import controller.Calculate; //<--Add 
public class UI extends JFrame {  
      private static final long serialVersionUID = 1L;  
      private JLabel jLabel0;  
      private JTextField tfSubject;  
      private JLabel jLabel1;  
      private JTable jTable0;  
      private JScrollPane jScrollPane0;  
      private JButton btCal;  
      private JTextField tfResult;  
      private JLabel jLabel2;  
      private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";  
      ControlUI ct = new ControlUI(); //<--Add  
      public UI() {  
           initComponents();  
           ct.innitComponentByDevelop(this); //<--Add  
      }  

                8.2 คลิกขวาที่ Component tfSubject[JTextField] เลือก Add Edit Events-->action-->actionPerformed

                8.3 เพิ่ม Code ดังนี้
      private void tfSubjectActionActionPerformed(ActionEvent event) {  
           ct.setSubject(tfSubject.getText()); //<--Add   
           ct.setModel(jTable0); //<--Add   
      }  

                8.4 คลิกขวาที่ Component tfSubject[JTextField] เลือก Add Edit Events-->mouse-->mousePressed และเพิ่ม code ดังนี้
      private void tfSubjectMouseMousePressed(MouseEvent event) {  
           tfSubject.setText(""); /* <--Add */  
           tfSubject.setFocusable(true); /* <--Add */  
           btCal.transferFocus(); /* <--Add */  
      }  

                8.5 คลิกขวาที่ Component btCal[JButton] เลือก Add Edit Events-->action-->actionPerformed และเพิ่ม code ดังนี้
      private void btCalActionActionPerformed(ActionEvent event) {  
           Calculate c = new Calculate(jTable0); // <--Add  
           tfResult.setText(c.calGrade()); // <--Add  
      }  

                เป็นอันว่าเสร็จสิ้น สามารถตรวจสอบ Code UI.java ทั้งหมดได้จากข้างล่างนี้
 package view;  
 import java.awt.Color;  
 import java.awt.event.ActionEvent;  
 import java.awt.event.ActionListener;  
 import java.awt.event.MouseAdapter;  
 import java.awt.event.MouseEvent;  
 import javax.swing.JButton;  
 import javax.swing.JFrame;  
 import javax.swing.JLabel;  
 import javax.swing.JScrollPane;  
 import javax.swing.JTable;  
 import javax.swing.JTextField;  
 import javax.swing.SwingUtilities;  
 import javax.swing.UIManager;  
 import javax.swing.table.DefaultTableModel;  
 import org.dyno.visual.swing.layouts.Constraints;  
 import org.dyno.visual.swing.layouts.GroupLayout;  
 import org.dyno.visual.swing.layouts.Leading;  
 import controller.ControlUI; //<--Add  
 import controller.Calculate; //<--Add  
 //VS4E -- DO NOT REMOVE THIS LINE!  
 public class UI extends JFrame {  
      private static final long serialVersionUID = 1L;  
      private JLabel jLabel0;  
      private JTextField tfSubject;  
      private JLabel jLabel1;  
      private JTable jTable0;  
      private JScrollPane jScrollPane0;  
      private JButton btCal;  
      private JTextField tfResult;  
      private JLabel jLabel2;  
      ControlUI ct = new ControlUI(); // <--Add  
      private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";  
      public UI() {  
           initComponents();  
           ct.innitComponentByDevelop(this); // <--Add  
      }  
      private void initComponents() {  
           setTitle("GPA-Demo");  
           setLayout(new GroupLayout());  
           add(getJTextField0(), new Constraints(new Leading(57, 186, 10, 10),  
                     new Leading(21, 12, 12)));  
           add(getJLabel1(), new Constraints(new Leading(246, 10, 10),  
                     new Leading(22, 12, 12)));  
           add(getJLabel0(), new Constraints(new Leading(14, 10, 10), new Leading(  
                     24, 12, 12)));  
           add(getJButton0(), new Constraints(new Leading(204, 10, 10),  
                     new Leading(343, 10, 10)));  
           add(getJLabel2(), new Constraints(new Leading(16, 10, 10), new Leading(  
                     348, 12, 12)));  
           add(getJScrollPane0(), new Constraints(new Leading(12, 262, 12, 12),  
                     new Leading(48, 286, 12, 12)));  
           add(getJTextField1(), new Constraints(new Leading(85, 116, 12, 12),  
                     new Leading(346, 12, 12)));  
           setSize(287, 384);  
      }  
      private JLabel getJLabel2() {  
           if (jLabel2 == null) {  
                jLabel2 = new JLabel();  
                jLabel2.setText("เกรดเฉลี่ย :");  
           }  
           return jLabel2;  
      }  
      private JTextField getJTextField1() {  
           if (tfResult == null) {  
                tfResult = new JTextField();  
                tfResult.setEnabled(false);  
           }  
           return tfResult;  
      }  
      private JButton getJButton0() {  
           if (btCal == null) {  
                btCal = new JButton();  
                btCal.setText("คำนวณ");  
                btCal.addActionListener(new ActionListener() {  
                     public void actionPerformed(ActionEvent event) {  
                          btCalActionActionPerformed(event);  
                     }  
                });  
           }  
           return btCal;  
      }  
      private JScrollPane getJScrollPane0() {  
           if (jScrollPane0 == null) {  
                jScrollPane0 = new JScrollPane();  
                jScrollPane0.setViewportView(getJTable0());  
           }  
           return jScrollPane0;  
      }  
      private JTable getJTable0() {  
           if (jTable0 == null) {  
                jTable0 = new JTable();  
                jTable0.setModel(new DefaultTableModel(new Object[][] {},  
                          new String[] { "ลำดับวิชา", "หน่วยกิจ", "เกรดที่ได้" }) {  
                     private static final long serialVersionUID = 1L;  
                     Class<?>[] types = new Class<?>[] { Object.class,  
                               Integer.class, Double.class };  
                     boolean[] canEdit = new boolean[] { false, true, true };  
                     public Class<?> getColumnClass(int columnIndex) {  
                          return types[columnIndex];  
                     }  
                     public boolean isCellEditable(int rowIndex, int columnIndex) {  
                          return canEdit[columnIndex];  
                     }  
                });  
           }  
           return jTable0;  
      }  
      private JLabel getJLabel1() {  
           if (jLabel1 == null) {  
                jLabel1 = new JLabel();  
                jLabel1.setText("วิชา");  
           }  
           return jLabel1;  
      }  
      private JTextField getJTextField0() {  
           if (tfSubject == null) {  
                tfSubject = new JTextField();  
                tfSubject.setForeground(new Color(153, 153, 153));  
                tfSubject.setText("ใส่ตัวเลขแล้วกด Enter");  
                tfSubject.addActionListener(new ActionListener() {  
                     public void actionPerformed(ActionEvent event) {  
                          tfSubjectActionActionPerformed(event);  
                     }  
                });  
                tfSubject.addMouseListener(new MouseAdapter() {  
                     public void mousePressed(MouseEvent event) {  
                          tfSubjectMouseMousePressed(event);  
                     }  
                });  
           }  
           return tfSubject;  
      }  
      private JLabel getJLabel0() {  
           if (jLabel0 == null) {  
                jLabel0 = new JLabel();  
                jLabel0.setText("จำนวน");  
           }  
           return jLabel0;  
      }  
      private static void installLnF() {  
           try {  
                String lnfClassname = PREFERRED_LOOK_AND_FEEL;  
                if (lnfClassname == null)  
                     lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();  
                UIManager.setLookAndFeel(lnfClassname);  
           } catch (Exception e) {  
                System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL  
                          + " on this platform:" + e.getMessage());  
           }  
      }  
      /**  
       * Main entry of the class. Note: This class is only created so that you can  
       * easily preview the result at runtime. It is not expected to be managed by  
       * the designer. You can modify it as you like.  
       */  
      public static void main(String[] args) {  
           installLnF();  
           SwingUtilities.invokeLater(new Runnable() {  
                public void run() {  
                     UI frame = new UI();  
                     frame.setDefaultCloseOperation(UI.EXIT_ON_CLOSE);  
                     frame.setTitle("UI");  
                     frame.getContentPane().setPreferredSize(frame.getSize());  
                     frame.pack();  
                     frame.setLocationRelativeTo(null);  
                     frame.setVisible(true);  
                }  
           });  
      }  
      private void tfSubjectActionActionPerformed(ActionEvent event) {  
           ct.setSubject(tfSubject.getText()); // <--Add  
           ct.setModel(jTable0); // <--Add  
      }  
      private void tfSubjectMouseMousePressed(MouseEvent event) {  
           tfSubject.setText(""); /* <--Add */  
           tfSubject.setFocusable(true); /* <--Add */  
           btCal.transferFocus(); /* <--Add */  
      }  
      private void btCalActionActionPerformed(ActionEvent event) {  
           Calculate c = new Calculate(jTable0); // <--Add  
           tfResult.setText(c.calGrade()); // <--Add  
      }  
 }  

        ทดสอบรันโปรแกรม
1. ใส่จำนวนวิชา แล้วกด Enter จากนั้น โปรแกรมจะไปสร้าง Model ของ Table ให้ออกมาตามจำนวนวิชาที่กรอกเข้าไป
2. ใส่หน่วยกิตของแต่ละวิชา
3. ใส่เกรดของแต่ละวิชา
4. กดปุ่มคำนวณ

         เป็นอย่างไรกันบ้างครับ ค่อนข้างทุลักทุเลพอสมควร เนื่องจากส่วนตัวผมถนัด Tool ที่ Netbeans มีมาให้มากกว่า ค่อนข้างที่จะมีประสิทธิภาพกว่า อีกทั้งยังมี Interface ให้เราเยอะมากกว่าที่จะต้องเขียน code เอง(บางทีผมอาจจะหาไม่เจอเองก็ได้ 5555)
        สำหรับบทความนี้ ก็เป็นโปรแกรมง่าย ๆ ซึ่งผมไม่ขออธิบายในส่วนของ Code ผมใช้วิธีการเขียนแบบแยกกันเป็นส่วน ๆ คล้ายลักษณะ MVC ส่วนของ Control ก็จะทำหน้าที่ควบคุมการทำงานต่าง ๆ เช่น Method ต่าง ๆ ที่ใช้คำนวณ Method ที่ใช้ควบคุมการทำงานของ Component ในส่วนของ View ก็จะเป็นแค่หน้า UI และ Action ต่าง ๆ ของ Component เท่านั้น ซึ่งก็จะทำให้ง่ายต่อการ Develop ในกรณีที่เขียนเป็นโปรแกรมที่ใหญ่กว่านี้
Read more!

วันพุธที่ 21 ธันวาคม พ.ศ. 2554

Android : Designing GUI in Eclipse Android Graphical Layout Editor

        สำหรับการพัฒนาระบบปฏิบัติการ Android นั้น แน่นอนว่าผู้ที่เพิ่งจะเริ่มต้นกับการเขียนโปรแกรมแรก หรือใครที่เคยศึกษามาก่อนหน้านี้ ก็ต้องไปจบชีวิตการพัฒนา Android ด้วยภาษา XML ที่เกี่ยวข้องกับการวาง Layout แต่ไม่ต้องกลัวครับ วันนี้ผมจะช่วยให้คุณได้พัฒนาระบบปฏิบัติการ Android ได้ง่ายขึ้น ด้วย Graphical Layout Editor ที่มีมาใน Eclipse IDE ซึ่งมันก็คือ การดีไซน์ Android แบบลากวางนั่นเอง ซึ่ง Tool ตัวนี้ก็จะไปจัดการกับ XML บางส่วนให้เราโดยอัตโนมัติ แล้วบางทีก็อาจจะทำให้เราเข้าใจภาษา XML ได้ไปโดยปริยาย โดยไม่ต้องไปศึกษาให้ปวดหัว แต่อย่างไรก็ตาม สิ่งที่สำคัญที่สุดก็คือ การทำความเข้าใจใน Code ที่ Tool ได้ Generate มาให้ครับ เอาหล่ะ งั้นเราไปเริ่มกันเลยดีกว่ากับโปรแกรมทดลอง Celsius to Fahrenheit ที่คุ้นเคยกันดี Let's go....

        1. หากยังไม่เคยเขียน Android มาก่อน แนะนำให้ Set Environment และเริ่มโปรแกรมแรกกับ Android กันก่อน

        2. เปิด Eclipse แล้วไปที่ File->New->Other...


        3. Select a wizard เลือก Android Project จากนั้นกดปุ่ม Next

        4. Project Name: CelsiusToFahrenheit จากนั้นกดปุ่ม Next

        5. เลือก Android 4.0 หรือตัวไหนก็ได้ที่ติดตั้งเอาไว้แล้ว จากนั้นกดปุ่ม Next

        6. ใส่ Application Name: CelsiusToFahrenheit ใส่ Package Name: com.android.project จากนั้นกดปุ่ม Finish

       7. ที่ Package Explorer จะเห็นโปรเจกที่ Eclipse IDE สร้างมาให้ ให้ไปที่โฟลเดอร์ "res" จากนั้นจะเห็นโฟลเดอร์ "layout" ข้างในจะมีไฟล์ที่ชื่อว่า main.xml ให้ดับเบิ้ลคลิ๊ก จากนั้นก็จะเห็นหน้าดีไซน์สำหรับการลากวาง Component ต่าง ๆ ของ Android ซึ่งจะเห็นว่ามี TextView มาให้ 1 อัน ("Hello World, Cels...") ให้ลบทิ้งไปก่อนด้วยการกดปุ่ม Delete 

        8. Design หน้าจอกันด้วยการลาก Component ต่าง ๆ มาวางให้ได้ดังรูป 
                8.1 Layouts -> LinearLayout(Horizontal)
                        8.1.1 วาง Text Fields-> Number (42) ใน LinearLayout
                        8.1.2 วาง Form Widgets-> Large Text ต่อจาก Number (42)
                8.2 Layouts -> LinearLayout(Horizontal)

                        8.1.1 วาง Form Widgets-> Button ใน LinearLayout
                        8.1.2 วาง Form Widgets-> Medium Text ต่อจาก Button


                 8.3 คลิกที่ component แต่ละตัว แล้วไปที่ Properties หา Property ที่ชื่อว่า Text จากนั้นให้เปลี่ยน Value ดั้งนี้
                        8.3.1 editText1 = "0"
                        8.3.2 textView1 = "Celsius"
                        8.3.3 textView2 = "32 Fahrenheit"
                        8.8.4 button1 = "Calculate"

                 8.4 คลิกที่ component แต่ละตัว แล้วไปที่ Properties หา Property ที่ชื่อว่า Id จากนั้นให้เปลี่ยนValue ดั้งนี้
                        8.4.1 editText1 -> "@+id/etInput"

                        8.4.2 textView1 -> "@+id/tvCel"
                        8.4.3 textView2 -> "@+id/tvFah"
                        8.4.4 button1 -> "@+id/btCal"

   
        9. ที่ Package Explorer ไปที่ src->com.android.project ดับเบิ้ลคลิก CelsiusToFahrenheitActivity.java จากนั้นเขียน Code ดังนี้ 
 package com.android.project;  
 import android.app.Activity;  
 import android.os.Bundle;  
 import android.view.View;  
 import android.view.View.OnClickListener;  
 import android.widget.Button;  
 import android.widget.EditText;  
 import android.widget.TextView;  
 public class CelsiusToFahrenheitActivity extends Activity {  
   /** Called when the activity is first created. */  
   @Override  
   public void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.main);  
     Button btCal = (Button) findViewById(R.id.btCal);  
     final EditText etInput = (EditText) findViewById(R.id.etInput);  
     final TextView tvFah = (TextView) findViewById(R.id.tvFah);  
     btCal.setOnClickListener(new OnClickListener() {  
                public void onClick(View v) {  
                            int tempFahr = (int)(Double.parseDouble(etInput.getText().toString())  
                                * 1.8 + 32);  
                            tvFah.setText(Integer.toString(tempFahr)+" Fahrenheit");  
                }  
           });  
   }  
 }  

        10. รันโปรแกรม หากยังไม่ได้ Start Virtual Device ให้ทำการ start เสียก่อน คลิกที่สัญลักษณ์
จากนั้นกดปุ่ม Start แล้วกดปุ่ม Launch รอสักครู่ ...

                10.1 หลังจาก Start เสร็จเรียบร้อยแล้วจะขึ้นดังรูปข้างล่าง จากนั้นให้ไปคลิกขวาที่โปรเจก จากนั้นเลือก Run As-> 1.Android Application


                10.2 จะปรากฏ icon Program ดังภาพ จากนั้นให้คลิกเข้าไปที่โปรแกรม


                10.3 ให้ทดลองใส่ค่าตัวเลขไป เช่น 45 แล้วกดปุ่ม Calculate


        ก็เป็นอันว่าเสร็จสิ้นขั้นตอน ในการเขียนโปรแกรม Celsius to Fahrenheit ซึ่งก็อาจจะยังไม่สมบูรณ์ดีนัก เพราะว่าค่าเริ่มต้นของ EditText นั้นเป็น 0 จึงต้องลบก่อน แล้วค่อยใส่ค่า ทางที่ดีเมื่อทำตามบทความนี้สำเร็จแล้ว ให้ลองศึกษาเพิ่มเติมเกี่ยวกับ Activity ของ Android ด้วย ซึ่งศึกษาได้จาก Link ด้านล่างนี้ หวังว่าคงจะช่วยให้ใครหลาย ๆ คน ที่ถอดใจจาก Android ไปแล้ว กลับมาลองศึกษามันใหม่และสนุกกับมัน โปรดช่วยเผยแพร่บทความนี้และช่วย Comment ด้วยนะครับ หากมีข้อสงสัย หรือว่าอธิบายผิดตรงส่วนไหน ......

Read more!

วันจันทร์ที่ 19 ธันวาคม พ.ศ. 2554

Java : Designing a Swing GUI in NetBeans IDE

        บทความนี้เหมาะสำหรับผู้ที่อยากจะลองเขียน Java Swing Application ด้วยการใช้ Tool ลากวาง ที่ Netbeans มีมาให้ หรือใครก็ตามที่ยังเขียนแบบ Code อย่างเดียวอยู่ อาจจะทำให้มีความรู้สึกว่า Java ทำไมยากจัง ไม่มี Tool ลากวางเหมือน .Net บ้างเหรอ ซึ่งจริง ๆ ใน Netbeans มีมานานมากแล้วครับซึ่งก็คงไม่ใช่เรื่องใหม่แน่นอน แต่ผมเห็นว่ามันคงจะเป็นการเริ่มต้นที่ดี สำหรับผู้ที่ยังไม่เคยลองใช้ Tool นี้มาก่อน(แล้วจะติดใจครับ) แต่อย่างไรก็ตาม การทำความเข้าใจใน Code ที่ตัว Tool ได้ Generate มาให้นั้น ก็ถือว่าเป็นสิ่งที่ดีครับ เพราะมันก็เหมือนเป็น Framework ตัวหนึ่ง ซึ่งวางโครงสร้างของการเขียน Code มาให้อยู่ในกรอบอย่างมีรูปแบบ ทำให้เราเข้าใจแนวคิดในการที่จะ Design โปรแกรมด้วย
     
        1. หากใครยังไม่ได้ติดตั้ง Netbeans ให้ติดตั้งเสียก่อน โดยดาวน์โหลดได้จาก http://netbeans.org/downloads/ ซึ่งทาง Netbeans บอกว่าต้องใช้ Version 6.9/7.0 และ JDK Version 6 ขึ้นไป ซึ่งในบทความนี้ใช้ Netbeans 7.0.1 และ JDK Version 7

        2.  New Project...
                2.1 เมื่อติดตั้งแล้วให้เปิด Netbeans ขึ้นมา ไปที่ File-->New Project...




                2.2 เลือก Categaories: Java , Projects: Java Application จากนั้นกด Next >


                2.3 ใส่ Project Name: GPADemo แล้วติ๊กเครื่องหมายถูกออก ตรง Create Main Class จากนั้นกดปุ่ม Finish

        3. New Java Package... และ New JFrame Form...
                3.1 คลิกขวาที่ Source Packages เลือก New--> Java Package...

                3.2  ใส่ Package Name: view จากนั้นคลิก Finish (เนื่องจากเราต้องการแยกแพกเกจออกเป็นส่วน ๆ ซึ่งส่วนนี้จะมีไว้เก็บคลาสที่เป็นหน้า UI เท่านั้น ไม่มีการทำงานใด ๆ)

                3.3 คลิกขวาที่ Package view เลือก New--> JFrame Form..

                3.4 ใส่ Class Name: UI จากนั้นกดปุ่ม Finish

        4. Design GUI  
                หลังจากเสร็จสิ้นจากขั้นตอนการ New JFrame Form แล้ว Netbeans จะสร้าง JFram มาให้ดังรูป สามาถเลือกมุมมองได้ทั้ง Source และ Design 

                 ส่วนที่หน้าต่าง Palette ก็จะมี Component มาให้สำหรับลากวางได้เลย โดยแยกเป็นหมวดหมู่ (ไม่ต้องกำหนด x, y เหมือนแต่ก่อนแล้ว ^^) แต่อย่างไรก็ตาม Component เหล่านี้ก็ยังสามารถ Customize ได้

        เรามาเริ่ม Design หน้า UI กันดีกว่า โดยบทความนี้จะสร้างเป็นโปรแกรมคิดคำนวณเกรดเฉลี่ยแบบง่าย ๆ ที่หลาย ๆ คนคงคุ้นกันเป็นอย่างดี แต่อยู่ในรูปแบบ GUI ให้ลากวางตามรูปได้เลย จากนั้นคลิกขวาเลือก Properties เพื่อกำหนดคุณสมบัติให้แต่ละ Component


                4.1 JFrame :
                        title : GPA-Demo
                        preferredSize : [287,384] (ลากให้ได้ขนาดที่ใกล้เคียง หรือตามใจชอบ)
                4.2 JLabel : 3 ตัว
                        text : จำนวน, วิชา, เกรดเฉลี่ย ตามลำดับ
                4.3 JTextField : 2 ตัว
                        jTextField1 คลิกขวาเลือก Change Variable Name ... New Name: tfSubject
                                text : ใส่ตัวเลขแล้วกด Enter
                                foreground : [153,153,153]
                                nextFocusableComponent : tfResult (กำหนดหลังจากที่ changed variable)
                        jTextField2 คลิกขวาเลือก Change Variable Name ... New Name: tfResult
                                text : 
                                enabled : false (เอาเครื่องหมายถูกออก)
                                nextFocusableComponent : btCal (กำหนดหลังจากที่ changed variable)
                4.4 JButton : คลิกขวาเลือก Change Variable Name ... New Name:btCal
                                text : คำนวณ

                4.5 JTable : 
                                ที่ Properties >> model คลิกที่ปุ่ม ... จะปรากฎไดอะล็อก model ให้กำหนดค่าต่าง ๆ ดังรูป

                *Trick เวลาที่เราลากวางนั้นจะเห็นว่าแต่ละ component จะขึ้นต่อกัน จึงทำให้บางทีจัดวางยาก แนะนำให้คลิกขวาที่ JFrame แล้วเลือก Set Layout >> Absolute Layout ทีนี้แต่ละ Component ก็จะเป็นอิสระต่อกัน เราก็สามารถไปกำหนดค่า x,y ที่ Properties ได้เช่นกัน ^^

                4.6 ทดสอบ run โปรแกรมด้วยการคลิกขวาที่ไฟล์แล้วเลือก Run File หรือกด Shift+F6 ก็จะปรากฏหน้าโปรแกรมดังรูป

        5. เขียน Code เพื่อให้โปรแกรมทำงาน 
                 5.1 เริ่มจากเขียนในส่วนของการควบคุม Component ต่าง ๆ ที่นอกเหนือจากการกำหนดใน Properties และการสร้างคลาสคำนวณเกรดเฉลี่ย โดยเริ่มจากสร้าง Package ชื่อ controller จากนั้นสร้าง จาวาคลาส 2 คลาส ชื่อว่า ControlUI.java และ Calculate.java จากนั้นเขียน Code ดังนี้

ControlUI.java        
 /*  
  * To change this template, choose Tools | Templates  
  * and open the template in the editor.  
  */  
 package controller;  
 import java.awt.Dimension;  
 import java.awt.Toolkit;  
 import javax.swing.table.DefaultTableModel;  
 /**  
  *  
  * @author T000Rxx  
  */  
 public class ControlUI {  
   int subject = 0;  
   DefaultTableModel model;  
   public ControlUI() {  
   }  
   public void setSubject(String n) {  
     subject = Integer.parseInt(n);  
   }  
   public int getSubject() {  
     return subject;  
   }  
   public void setModel(javax.swing.JTable tb) {  
     removeOldModel(tb.getRowCount());  
     model = (DefaultTableModel) tb.getModel();  
     for (int j = 0; j < getSubject(); j++) {  
       model.addRow(new Object[]{j + 1});  
     }  
   }  
   public void removeOldModel(int row) {  
     for (int i = 0; i < row; i++) {  
       model.removeRow(0);  
     }  
   }  
   public void innitComponentByDevelop(javax.swing.JFrame fm) {  
     Dimension fd = fm.getSize();  
     int w = fd.width;  
     int h = fd.height;  
     Dimension d = Toolkit.getDefaultToolkit().getScreenSize();  
     int x = (d.width - w) / 2;  
     int y = (d.height - h) / 2;  
     fm.setBounds(x, y, w, h);  
   }  
 }  

Calculate.java
 /*  
  * To change this template, choose Tools | Templates  
  * and open the template in the editor.  
  */  
 package controller;  
 import java.text.DecimalFormat;  
 import javax.swing.JTable;  
 /**  
  *  
  * @author T000Rxx  
  */  
 public class Calculate {  
   int subjectAmount = 0;  
   int listSubject[];  
   int listUnit[];  
   JTable tb;  
   double totalGrade;  
   int cumulativeCredit = 0;  
   public Calculate(javax.swing.JTable tb) {  
     this.tb = tb;  
     subjectAmount = tb.getRowCount();  
     listSubject = new int[subjectAmount];  
     listUnit = new int[subjectAmount];  
   }  
   public String calGrade() {  
     for (int i = 0; i < tb.getRowCount(); i++) {  
       cumulativeCredit+= Integer.parseInt(tb.getValueAt(i, 1).toString());  
       totalGrade+= Double.parseDouble(tb.getValueAt(i, 1).toString()) * Double.parseDouble(tb.getValueAt(i, 2).toString());  
     }  
     DecimalFormat dfm = new java.text.DecimalFormat("0.00");  
     return dfm.format(totalGrade/cumulativeCredit);  
   }  
 }  

        6. เขียน Code เพื่อกำหนด Action ของ component ต่าง ๆ ของคลาส UI
                6.1 เพิ่ม Code import ประกาศตัวแปรคลาส Control, Calculate และเพิ่ม Code ที่ Constructor ดังนี้
UI.java
package view;
import controller.Calculate; //<--Add
import controller.ControlUI; //<--Add
public class UI extends javax.swing.JFrame {
    ControlUI ct = new ControlUI(); //<--Add
    public UI() {
        initComponents();
        ct.innitComponentByDevelop(this); //<--Add
    }  
                6.2 คลิกขวาที่ Component  tfSubject[JTectField] เลือก Events->Action->actionPerformed
                6.3 เพิ่ม Code ดังนี้
 private void tfSubjectActionPerformed(java.awt.event.ActionEvent evt) {                       
   ct.setSubject(tfSubject.getText()); //<--Add  
   ct.setModel(jTable1); //<--Add  
 }  

                6.4 คลิกขวาที่ Component tfSubject[JTectField] เลือก Events->Mouse->MousePressed และเพิ่ม Code ดังนี้
 private void tfSubjectMousePressed(java.awt.event.MouseEvent evt) {  
   tfSubject.setText(""); /*<--Add*/  
   tfSubject.setFocusable(true); /*<--Add*/  
   btCal.transferFocus(); /*<--Add*/  
 }  

                6.5 คลิกขวาที่ Component btCal[JButton] เลือก Events->Action->actionPerformed และเพิ่ม Code ดังนี้ (ต้อง import controller.Calculate; ด้วย)
 private void btCalActionPerformed(java.awt.event.ActionEvent evt) {                     
   Calculate c = new Calculate(jTable1); //<--Add  
   tfResult.setText(c.calGrade()); //<--Add  
 }   

                เป็นอันว่าเสร็จสิ้น สามารถตรวจสอบ Code UI.java ทั้งหมดได้จากข้างล่างนี้
 /*  
  * UI.java  
  *  
  * Created on Dec 16, 2011, 1:45:42 PM  
  */  
 package view;  
 import controller.Calculate;  
 import controller.ControlUI;  
 /**  
  *  
  * @author T000Rxx  
  */  
 public class UI extends javax.swing.JFrame {  
   ControlUI ct = new ControlUI();  
   /** Creates new form UI */  
   public UI() {  
     initComponents();  
     ct.innitComponentByDevelop(this);  
   }  
   /** This method is called from within the constructor to  
    * initialize the form.  
    * WARNING: Do NOT modify this code. The content of this method is  
    * always regenerated by the Form Editor.  
    */  
 @SuppressWarnings("unchecked")  
 Generated Code  
 private void tfSubjectActionPerformed(java.awt.event.ActionEvent evt) {                       
   ct.setSubject(tfSubject.getText());  
   ct.setModel(jTable1);  
 }                       
 private void tfSubjectMousePressed(java.awt.event.MouseEvent evt) {                      
   tfSubject.setText("");  
   tfSubject.setFocusable(true);  
   btCal.transferFocus();  
 }                     
 private void btCalActionPerformed(java.awt.event.ActionEvent evt) {                     
   Calculate c = new Calculate(jTable1);  
   tfResult.setText(c.calGrade());  
 }  
 /**  
    * @param args the command line arguments  
    */  
   public static void main(String args[]) {  
     /* Set the Nimbus look and feel */  
      Look and feel setting code (optional)  
 /* Create and display the form */  
     java.awt.EventQueue.invokeLater(new Runnable() {  
       public void run() {  
         new UI().setVisible(true);  
       }  
     });  
   }  
   // Variables declaration - do not modify  
   private javax.swing.JButton btCal;  
   private javax.swing.JLabel jLabel1;  
   private javax.swing.JLabel jLabel2;  
   private javax.swing.JLabel jLabel3;  
   private javax.swing.JScrollPane jScrollPane1;  
   private javax.swing.JTable jTable1;  
   private javax.swing.JTextField tfResult;  
   private javax.swing.JTextField tfSubject;  
   private org.jdesktop.beansbinding.BindingGroup bindingGroup;  
   // End of variables declaration  
 }  

        ทดสอบรันโปรแกรม 
1. ใส่จำนวนวิชา แล้วกด Enter จากนั้น โปรแกรมจะไปสร้าง Model ของ Table ให้ออกมาตามจำนวนวิชาที่กรอกเข้าไป
2. ใส่หน่วยกิตของแต่ละวิชา
3. ใส่เกรดของแต่ละวิชา
4. กดปุ่มคำนวณ

         เป็นอย่างไรกันบ้างครับสำหรับบทความนี้ ก็เป็นโปรแกรมง่าย  ๆ ซึ่งผมไม่ขออธิบายในส่วนของ Code ซึ่งผมใช้วิธีการเขียนแบบแยกกันเป็นส่วน ๆ คล้ายลักษณะ MVC ซึ่งส่วนของ Control ก็จะทำหน้าที่ควบคุมการทำงานต่าง ๆ เช่น Method ต่าง ๆ ที่ใช้คำนวณ Method ที่ใช้ควบคุมการทำงานของ Component ในส่วนของ View ก็จะเป็นแค่หน้า UI และ Action ต่าง ๆ ของ Component เท่านั้น ซึ่งก็จะทำให้ง่ายต่อการ Develop ในกรณีที่เขียนเป็นโปรแกรมที่ใหญ่กว่านี้

Read more!

วันพุธที่ 14 ธันวาคม พ.ศ. 2554

Java : Installing Apache Ant On Linux

        Apache Ant คือ java library และ command-line ตัวหนึ่งซึ่งเป็น tool สำหรับช่วยในการ building โปรแกรมที่เราเขียนขึ้น เพียงแค่เราเขียน Script สำหรับสั่งให้ Ant ทำหน้าที่ compile ไฟล์ .java ไปเป็น .class ไปจนถึงการ coppy ไฟล์ไปยังไดเร็กทอรี่ต่าง ๆ ที่เราต้องการ ซึ่งเราจะคุ้นกันในชื่อ build.xml หากใครเคยลองสร้างโปรเจก java จาก Netbeans หรือ Eclipse มาแล้วก็จะเห็นว่าแต่ละ IDE นั้น generate โครงสร้างตัวโปรเจกมาให้ ซึ่งต่างก็ไม่เหมือนกัน แต่ก็จะมีไฟล์ build.xml ซึ่งภายในนั้นเป็น script ที่อยู่ในรูปแบบคำสั่ง xml สั่งให้ทำการคอมไพล์ หรือการสร้างไฟล์ .jar , .war จาก .class ฯลฯ(ยังทำอะไรได้อีกเยอะมาก) กล่าวได้ว่า Ant นั้นเป็น shell script หรือ batch files ที่ไม่ขึ้นต่อ OS ใด ๆ ก็ได้เนื่องจาก Ant ใช้ xml และ java
        ในบทความนี้ก็จะเป็นการติดตั้ง apahce ant บนระบบปฏิบัติการ Linux ซึ่งจำเป็นต้องทำก่อนที่จะเริ่มต้นเขียน Script Ant ซึ่งสามารถศึกษาได้จาก http://ant.apache.org/index.html มาเริ่มกันเลยดีกว่า แต่ก่อนที่จะติดตั้ง Ant ได้นั้น ต้องทำการติดตั้ง java ก่อนเพราะว่า Ant นั้นทำงานผ่านคำสั่งภาษาจาวา

        1. Set Environment สำหรับ จาวา บน Linux      

        2. ไปที่ URL: http://ant.apache.org/bindownload.cgi จากนั้นให้ดู Release ล่าสุดของ Ant

        3. เลือกดาวน์โหลด apache-ant-x.x.x-bin.tar.gz [PGP] [SHA1] [SHA512] [MD5] ในบทความนี้จะใช้เวอร์ชั่น 1.8.2
  
        4. จากนั้นย้ายหรือ coppy ไฟล์ .tar.gz ที่ได้ดาวน์โหลดมา ไปไว้ยังไดเร็กทอรี่ usr ที่ root
                EX. ตัวอย่างการใช้คำสั่ง ย้าย หรือ coppy พิมพ์  mv หรือ cp  วรรค ต้นทาง วรรค  ปลายทาง

                เมื่อทำการก็อปปี้เสร็จแล้ว ลองเข้าไปดูที่ไดเร็กทอรี่ปลายทาง จะมีไฟล์ apache-ant-1.8.2-bin.tar.gz ที่ได้ทำการย้ายหรือ coppy ไปแล้ว

        5. ทำการแตกไฟล์โดยใช้คำสั่ง tar zxvf ตามด้วยชื่อไฟล์

                จะได้ไดเร็กทอรี่ apache-ant-1.8.2 ดังรูป

                จากนั้นให้ลบไฟล์ .tar.gz ทิ้งไปถ้าไม่ต้องการ ด้วยคำสั่ง rm  apache-ant-1.8.2.tar.gz

        6. เซ็ต ANT_OPTS โดยใช้คำสั่ง export ANT_OPTS="-Xmx256M"

        7. เซ็ต ANT_HOME โดยใช้คำสั่ง export ANT_HOME=/usr/apache-ant-1.8.2

        8. เซ็ต PATH โดยใช้คำสั่ง export PATH=$PATH:/usr/apache-ant-1.8.2/bin

        9. เมื่อเสร็จทุกขั้นตอนแล้ว ลองใช้คำสั่งต่อไปนี้เพื่อเช็คความถูกต้อง 
                echo $ANT_OPTS
                echo $ANT_HOME
                echo $PATH
                ant -version

                เป็นอันว่าเสร็จสิ้นขั้นตอนการติดตั้ง ในบทความหน้าเรามาลอง complie java ด้วย ant บนระบบปฎิบัติการ Linux กัน 
Read more!