3. ทำการ Restart Eclipse ใหม่ ถึงตอนนี้เราก็จะสามารถใช้ plugin ตัวนี้กันได้แล้ว
4. New Project...
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 ในกรณีที่เขียนเป็นโปรแกรมที่ใหญ่กว่านี้