Exporting and sharing (ဒေတာ ထုတ်ပေးခြင်းနဲ့ မျှဝေခြင်း)
IA အတွက် tool တွေပါ၊ စာမေးပွဲ ခေါင်းစဉ် မဟုတ်ပါဘူး။ ဒါတွေက ကိုယ့် IA (Internal Assessment: IB သင်တန်းမှာ ကျောင်းသားတစ်ယောက်ချင်း ကိုယ်တိုင် တည်ဆောက်ရပြီး ကျောင်းက ဆရာက အမှတ်ပေးတဲ့ အပိုင်း) နဲ့ ကိုက်အောင် ပြင်သုံးရမယ့် JavaFX (Java နဲ့ desktop app တည်ဆောက်တဲ့ library) နဲ့ standard library (Java မှာ အသင့်ပါတဲ့ library) code ပုံစံတွေပါ။ ဒီစာမျက်နှာက ဘယ်အရာကိုမှ စာမေးပွဲမှာ မမေးပါဘူး၊ ပြီးတော့ ကိုယ့် IA က ကိုယ်တိုင် လုပ်ထားတဲ့ အလုပ် ဖြစ်ရပါမယ်။
ဒီစာမျက်နှာက ကိုယ့် app ထဲက ဒေတာကို အပြင် ထုတ်ပေးတဲ့ အကြောင်းပါ: spreadsheet (Excel လို ဇယားကွက် program) က ဖွင့်လို့ရတဲ့ CSV (comma နဲ့ ခြားထားတဲ့ စာသား file) file တစ်ခု ရေးတာ၊ user ရဲ့ mail client (email ပို့၊ ဖတ်တဲ့ program) ကို အကြောင်းအရာ ကြိုဖြည့်ပြီး ဖွင့်ပေးတာနဲ့ ဝဘ်စာမျက်နှာ တစ်ခုကို ဖွင့်ပေးတာတွေပါ။
ဒီ cookbook (recipe တွေကို စုထားတဲ့ လမ်းညွှန်) ကို ပထမဆုံး ဖတ်တာလား။ Start here: how every recipe fits together (ဒီမှာ စပါ: recipe တိုင်း ဘယ်လို ချိတ်ဆက်ထားလဲ) ကို အရင် ဖတ်ပါ။ အဲဒီ စာမျက်နှာက ကိုယ် ပြင်ရမယ့် နေရာ နှစ်ခုကို ရှင်းပြထားပြီး recipe (ချက်ချင်း ယူသုံးလို့ရတဲ့ code နမူနာ) တိုင်း အားကိုးရတဲ့ onAction (button နှိပ်ရင် run မယ့် method ကို သတ်မှတ်တဲ့ setting) ချိတ်ဆက်မှုကိုလည်း ရှင်းပြထားပါတယ်။
ကိုယ့် ဒေတာကို CSV file အဖြစ် ထုတ်ပေးခြင်း
ဒါက ဘာလုပ်ပေးလဲ: ကိုယ့် record (အချက်အလက် အများကြီး စုထားတဲ့ ဒေတာ တစ်ခု) တွေကို comma နဲ့ ခြားထားတဲ့ row (အလျားလိုက် အတန်း) တွေအဖြစ် spreadsheet တွေက တိုက်ရိုက် ဖွင့်လို့ရတဲ့ file တစ်ခုထဲ ရေးပေးပါတယ်။
IA မှာ ဘယ်အချိန် သုံးမလဲ: client (product ကို သုံးမယ့်သူ) ကို spreadsheet မှာ ဖွင့်ကြည့်လို့ရတဲ့ report တစ်ခု ပေးတာ ဒါမှမဟုတ် ဒေတာကို တခြားနေရာမှာ သုံးလို့ရအောင် table တစ်ခုကို export (app ထဲက ဒေတာကို တခြား program တွေ သုံးလို့ရတဲ့ file အဖြစ် ထုတ်ပေးခြင်း) လုပ်တာတွေမှာ သုံးပါတယ်။ CSV မှာ library (အသင့်ရေးထားတဲ့ code အစု) အပို မလိုလို့ တကယ့် spreadsheet file တွေထက် ပိုသုံးကြတာပါ။
SceneBuilder မှာ (layout): SceneBuilder (FXML layout ကို ပုံနဲ့ မြင်ရင်း ပြင်တဲ့ editor) ထဲက layout (control တွေကို screen ပေါ်မှာ စီစဉ်ထားပုံ) မှာ export လုပ်ပေးမယ့် button တစ်ခုကလွဲပြီး ဘာမှ ထည့်စရာ မလိုပါဘူး။ Button တစ်ခု ထည့်ပြီး သူ့ onAction ကို handleExport လို့ သတ်မှတ်ပါ။
<Button text="Export CSV" onAction="#handleExport" />
Controller (user လုပ်တာတွေကို ကိုင်တွယ်ပြီး Model နဲ့ screen တွေကို ချိတ်ပေးတဲ့ class) မှာ (.java file):
Import (တခြားနေရာက code ကို ယူသုံးမယ်လို့ ကြေညာခြင်း) line များ:
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.List;
Method (သီးခြား အလုပ်တစ်ခု လုပ်ပေးတဲ့ code အပိုင်း) များ: button က handleExport ကို run ပါတယ်၊ အဲဒီ method က file ကို ဘယ်မှာ သိမ်းမလဲ user ကို မေးပြီးမှ exportCsv ကို ခေါ်ပါတယ်။
@FXML
private void handleExport(ActionEvent event) {
FileChooser chooser = new FileChooser();
chooser.setTitle("Export to CSV");
chooser.setInitialFileName("export.csv");
chooser.getExtensionFilters().add(
new FileChooser.ExtensionFilter("CSV files", "*.csv"));
Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
File file = chooser.showSaveDialog(stage);
if (file == null) {
return; // the user pressed Cancel
}
// your IA logic here: pass your app's own list of records
exportCsv(file, items);
}
private void exportCsv(File file, List<Item> items) {
try (PrintWriter out = new PrintWriter(file)) {
// your IA logic here: the header and one line per record, from your own fields
out.println("Name,Quantity"); // header row
for (int i = 0; i < items.size(); i++) {
Item item = items.get(i);
out.println(item.getName() + "," + item.getQuantity());
}
// for-each version: for (Item item : items) { ... }
} catch (IOException e) {
// tell the user the export failed
}
}
ကိုယ်ပိုင် logic (ဘာလုပ်မလဲ ဆုံးဖြတ်တဲ့ code) ထည့်ရမယ့် နေရာ: // your IA logic here (ကိုယ့် IA ရဲ့ logic ကို ဒီမှာ ထည့်ပါ) လို့ မှတ်ထားတဲ့ နေရာ နှစ်ခုပါ။ handleExport ထဲမှာတော့ exportCsv ကို ပေးလိုက်တဲ့ record list ပါ၊ exportCsv ထဲမှာတော့ header line (column နာမည်တွေ ပါတဲ့ ပထမ line) နဲ့ row line ပါ။ အဲဒီ line တွေက ကိုယ်ပိုင် column (ဒေါင်လိုက် ကော်လံ) တွေကို နာမည်ပေးပြီး ကိုယ်ပိုင် getter (private attribute ရဲ့ တန်ဖိုးကို ပြန်ပေးတဲ့ method) တွေကို ခေါ်ဖတ်ပါတယ်။ Save dialog (file သိမ်းမယ့် နေရာကို user ကို ရွေးခိုင်းတဲ့ window အသေး)၊ file ရေးတာနဲ့ try/catch (error ဖြစ်ရင် ဖမ်းပြီး ကိုင်တွယ်ပေးတဲ့ ပုံစံ) ကတော့ ပြန်သုံးလို့ရတဲ့ wiring (screen နဲ့ code ကို ချိတ်ပေးတဲ့၊ ဘယ် project မှာမဆို တူတဲ့ code) ပါ။
ကိုယ့် project နဲ့ ကိုက်အောင် ပြင်ပါ:
- Header line နဲ့ row line ကို ကိုယ်ပိုင် column တွေ၊ getter တွေနဲ့ ကိုက်အောင် ပြောင်းပါ။
handleExportထဲကitemsကို ကိုယ့် app ရဲ့ ကိုယ်ပိုင် record list နဲ့ အစားထိုးပါ၊ ဥပမာ ကိုယ့်ဒေတာနဲ့ table ကို ဖြည့်ခြင်း ထဲကObservableList(TableViewက စောင့်ကြည့်နေတဲ့ အထူး list) ပါ။- Save dialog က User ကို file ရွေးခွင့်ပေးခြင်း ထဲက dialog ပါပဲ၊ ဒီမှာ
"*.csv"filter နဲ့ပါ။ သူ့ title နဲ့ ကြိုဖြည့်ပေးထားတဲ့ file နာမည်ကို ကိုယ့် app နဲ့ ကိုက်အောင် ပြောင်းပါ။
သတိထားရမယ့် အချက်များ:
onActionမှာ ပေးထားတဲ့ နာမည်နဲ့ method (handleExport) က controller ထဲမှာ ရှိရပါမယ်၊ မရှိရင် screen က load မဖြစ်ပါဘူး။- CSV မှာ တကယ် သတိထားရမယ့် တစ်ခုတည်းသော ပြဿနာက ကိုယ်တိုင် comma ပါနေတဲ့ တန်ဖိုးပါ၊ ဥပမာ
Smith, Johnလို နာမည် တစ်ခု။ အဲဒီ တန်ဖိုးက column နှစ်ခု ကွဲသွားပြီး row တစ်ခုလုံး နေရာ ရွေ့သွားပါလိမ့်မယ်။ အရိုးရှင်းဆုံး ပြင်နည်းတွေက အဲဒီလို တန်ဖိုးတွေကို double quote တွေနဲ့ ပိတ်ထားတာ ("Smith, John")၊ ဒါမှမဟုတ် ဒေတာထဲမှာ ဘယ်တော့မှ မပါနိုင်တဲ့ semicolon ဒါမှမဟုတ် tab လို delimiter (အပိုင်းတွေကို ခြားပေးတဲ့ character) တစ်ခုကို ရွေးတာပါ။ - တန်ဖိုး တစ်ခုထဲမှာ မတော်တဆ ပါလာတဲ့ line break (line အသစ်ကို ပြတဲ့ character) ကလည်း ဒီလို ပြဿနာမျိုး ဖြစ်စေပါတယ်။ Export လုပ်မယ့် တန်ဖိုးတွေကို line တစ်ကြောင်းတည်းမှာပဲ ထားပါ။
တွဲသုံးလို့ရတဲ့ recipe များ: User ကို file ရွေးခွင့်ပေးခြင်း၊ Scroll လုပ်လို့ရတဲ့ table ထဲမှာ row တွေကို ပြခြင်း။
Button တစ်ခုကနေ email ပို့ခြင်း
ဒါက ဘာလုပ်ပေးလဲ: user ရဲ့ ကိုယ်ပိုင် mail program ကို အကြောင်းအရာ ကြိုဖြည့်ထားတဲ့ message အသစ် တစ်စောင်နဲ့ ဖွင့်ပေးပါတယ်။ User က ပြန်စစ်ပြီး ပို့ရုံပါပဲ။
IA မှာ ဘယ်အချိန် သုံးမလဲ: “Contact support” (အကူအညီ တောင်းရန်) ဒါမှမဟုတ် “Email this booking” (ဒီ booking ကို email ပို့ရန်) လို button တစ်ခုမှာ သုံးပါတယ်။ အဲဒီမှာ ကိုယ့် app က user အစား message ကို ပို့ပေးတာ မဟုတ်ဘဲ user က သူ့ကိုယ်ပိုင် account ကနေ ပို့တာပါ။
SceneBuilder မှာ (layout): email ဖွင့်ပေးမယ့် button တစ်ခုကလွဲပြီး ဘာမှ ထည့်စရာ မလိုပါဘူး။ Button တစ်ခု ထည့်ပြီး သူ့ onAction ကို handleEmail လို့ သတ်မှတ်ပါ။
<Button text="Email support" onAction="#handleEmail" />
Controller မှာ (.java file):
Import line များ:
import javafx.fxml.FXML;
import java.awt.Desktop;
import java.net.URI;
Method များ: button က handleEmail ကို run ပါတယ်၊ အဲဒီ method က emailSupport ကို ခေါ်ပါတယ်။
@FXML
private void handleEmail() {
emailSupport();
}
private void emailSupport() {
if (!Desktop.isDesktopSupported()) {
return; // not available on this system
}
try {
// your IA logic here: the recipient, subject, and body for your app
String to = "support@example.com";
String subject = "Question about my booking";
String body = "Hello,";
URI mailto = new URI("mailto:" + to
+ "?subject=" + subject.replace(" ", "%20")
+ "&body=" + body.replace(" ", "%20"));
Desktop.getDesktop().mail(mailto);
} catch (Exception e) {
// handle the error
}
}
ကိုယ်ပိုင် logic ထည့်ရမယ့် နေရာ: // your IA logic here လို့ မှတ်ထားတဲ့ to၊ subject နဲ့ body string (စာသား) တွေပါ။ mailto URI (email လိပ်စာ၊ ဝဘ်လိပ်စာ စတဲ့ လိပ်စာတွေကို ရေးတဲ့ စံပုံစံ) ကို တည်ဆောက်တာနဲ့ Desktop guard (Desktop ကို သုံးလို့ရမရ ကြိုစစ်တဲ့ if) ကတော့ ပြန်သုံးလို့ရတဲ့ wiring ပါ။
ကိုယ့် project နဲ့ ကိုက်အောင် ပြင်ပါ:
to၊subjectနဲ့bodystring တွေကို ပြောင်းပါ။- URL (website လိပ်စာ) ထဲမှာ space တွေနဲ့ တခြား အထူး character တွေကို encode (သတ်မှတ်ထားတဲ့ code ပုံစံအဖြစ် ပြောင်း) လုပ်ရပါတယ်၊ ဒါကြောင့် ဥပမာမှာ space တွေကို
%20နဲ့ အစားထိုးထားတာပါ။ ပိုရှည်တဲ့ body တွေအတွက်java.net.URLEncoder.encode(text, "UTF-8")က ဒီအလုပ်ကို ပိုစေ့စေ့စပ်စပ် လုပ်ပေးပါတယ်။
သတိထားရမယ့် အချက်များ:
onActionမှာ ပေးထားတဲ့ နာမည်နဲ့ method (handleEmail) က controller ထဲမှာ ရှိရပါမယ်၊ မရှိရင် screen က load မဖြစ်ပါဘူး။- ဒါက field (ဖြည့်ရမယ့် အကွက်) တွေကို ဖြည့်ပြီးသား ဖြစ်အောင် user ရဲ့ mail client ကို ဖွင့်ပေးတာပါ။ ကိုယ့် application မှာ email password ဒါမှမဟုတ် mail server နဲ့ ချိတ်ဆက်မှု မလိုပါဘူး။
- Hardcoded (code ထဲမှာ ပုံသေ ရေးထည့်ထားတဲ့) login အချက်အလက်တွေနဲ့ ကိုယ့် app ကနေ mail ကို တိုက်ရိုက် ပို့ဖို့ မကြိုးစားပါနဲ့။ ဒါက JavaMail (Java ကနေ email ပို့တဲ့ library) ဒါမှမဟုတ် SMTP (email ပို့တဲ့ protocol) ကို သုံးတဲ့ နည်းပါ။ အဲဒီနည်းမှာ mail server တစ်ခုနဲ့ ကိုယ့် code ထဲမှာ သိမ်းထားတဲ့ credentials (sign in ဝင်ဖို့ အထောက်အထား၊ ဥပမာ username နဲ့ password) လိုပါတယ်၊ ဒါက ကောင်းတဲ့ အလေ့အထ မဟုတ်သလို လုံခြုံရေး အန္တရာယ်လည်း ဖြစ်ပါတယ်။ အပေါ်က mail client နည်းက နှစ်ခုလုံးကို ရှောင်ပေးပါတယ်။
Desktopကjava.awtထဲမှာ ရှိပေမယ့် ဒီမှာ တောင်းဆိုချက်ကို operating system (ကွန်ပျူတာကို စီမံတဲ့ အဓိက software) ဆီ လွှဲပေးဖို့ပဲ သုံးတာပါ၊ Swing (Java မှာ window တွေ တည်ဆောက်တဲ့ အဟောင်း library) window တစ်ခုခု တည်ဆောက်ဖို့ မဟုတ်ပါဘူး။ Interface (user မြင်ပြီး သုံးရတဲ့ မျက်နှာပြင်) က JavaFX သက်သက်ပဲ ဆက်ဖြစ်ပါတယ်။
တွဲသုံးလို့ရတဲ့ recipe များ: ကိုယ့် app ကနေ ဝဘ်စာမျက်နှာ တစ်ခု ဖွင့်ခြင်း၊ User ကို တစ်ခုခု အသိပေးခြင်း။
ကိုယ့် app ကနေ ဝဘ်စာမျက်နှာ တစ်ခု ဖွင့်ခြင်း
ဒါက ဘာလုပ်ပေးလဲ: ဝဘ်လိပ်စာ တစ်ခုကို user ရဲ့ default browser (ကွန်ပျူတာမှာ ပုံမှန် သုံးဖို့ သတ်မှတ်ထားတဲ့ ဝဘ်စာမျက်နှာ ဖွင့်တဲ့ software) မှာ ဖွင့်ပေးပါတယ်။
IA မှာ ဘယ်အချိန် သုံးမလဲ: online documentation (အသုံးပြုနည်း ရှင်းလင်းချက်) ဆီ သွားတဲ့ Help link၊ project စာမျက်နှာဆီ သွားတဲ့ About link ဒါမှမဟုတ် app က ရည်ညွှန်းတဲ့ resource (အရင်းအမြစ်) တစ်ခုဆီ သွားတဲ့ link တစ်ခုမှာ သုံးပါတယ်။
SceneBuilder မှာ (layout): ဝဘ်စာမျက်နှာ ဖွင့်ပေးမယ့် button တစ်ခုကလွဲပြီး ဘာမှ ထည့်စရာ မလိုပါဘူး။ Button တစ်ခု ထည့်ပြီး သူ့ onAction ကို handleHelp လို့ သတ်မှတ်ပါ။
<Button text="Help" onAction="#handleHelp" />
Controller မှာ (.java file):
Import line များ:
import javafx.fxml.FXML;
import java.awt.Desktop;
import java.net.URI;
Method များ: button က handleHelp ကို run ပါတယ်၊ အဲဒီ method က openHelpPage ကို ခေါ်ပါတယ်။
@FXML
private void handleHelp() {
openHelpPage();
}
private void openHelpPage() {
if (!Desktop.isDesktopSupported()) {
return;
}
try {
// your IA logic here: the address you want to open
Desktop.getDesktop().browse(new URI("https://example.com/help"));
} catch (Exception e) {
// handle the error
}
}
ကိုယ်ပိုင် logic ထည့်ရမယ့် နေရာ: // your IA logic here လို့ မှတ်ထားတဲ့ new URI(...) ထဲက လိပ်စာပါ။ Desktop guard နဲ့ try/catch ကတော့ ပြန်သုံးလို့ရတဲ့ wiring ပါ။
ကိုယ့် project နဲ့ ကိုက်အောင် ပြင်ပါ:
new URI(...)ထဲက လိပ်စာကို ကိုယ် ဖွင့်ချင်တဲ့ စာမျက်နှာနဲ့ ပြောင်းပါ။- Email မှာလိုပဲ
Desktop.isDesktopSupported()guard ကို သုံးပါ။
သတိထားရမယ့် အချက်များ:
onActionမှာ ပေးထားတဲ့ နာမည်နဲ့ method (handleHelp) က controller ထဲမှာ ရှိရပါမယ်၊ မရှိရင် screen က load မဖြစ်ပါဘူး။- လိပ်စာက
https://အပါအဝင် URL အပြည့်အစုံ ဖြစ်ရပါမယ်၊ မဟုတ်ရင်new URI(...)က အဲဒါကို ဝဘ်စာမျက်နှာ အဖြစ် မဖွင့်နိုင်တာ ဖြစ်နိုင်ပါတယ်။ - တချို့ system တွေမှာ
Desktopကို မထောက်ပံ့ပါဘူး၊ ဥပမာ headless server (screen နဲ့ keyboard မပါဘဲ run တဲ့ server) ဒါမှမဟုတ် setting တွေကို ပိတ်ထားတဲ့ lab ကွန်ပျူတာမှာပါ။ Guard စစ်ဆေးမှုက ကာကွယ်ပေးတာ အဲဒီ အခြေအနေကိုပါပဲ။
တွဲသုံးလို့ရတဲ့ recipe များ: Button တစ်ခုကနေ email ပို့ခြင်း၊ Menu bar မှာ လုပ်ဆောင်ချက်တွေ ထည့်ခြင်း။