JOptionPane สามารถสร้าง dialog box ทั่วไปให้เราใช้งานได้ เช่น message box, confirm box หรือ input box
แต่บางครั้งเราต้องการ dialog ที่พิเศษขึ้นมาอีกหน่อย เช่น มี 4 ปุ่ม มี 3 text field
ซึ่งโดย default มันเหมือนไม่มี ทุกครั้งเลยไปสร้าง custom dialog ขึ้นมาใช้งาน
จนวันนึงพบว่า ถ้าไม่ต้องการอะไรพิเศษมากๆ JOptionPane ก็สามารถ custom ได้ในระดับนึงเลย โดยไม่จำเป็นต้องสร้าง custom dialog เลยก็ได้

โดยหลักการคือเราส่ง array ของ component ที่ต้องการแสดงเข้าไปใน Object[] options array ตัวนี้
ส่วน Object message ก็ไม่จำเป็นต้องเป็น text string, เพราะเราสามารถส่ง component อะไรเข้าไปก็ได้เหมือนกัน
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Window;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
/**
*
* @author Thada
*/
public class PlatedCutoutsQueryDialog {
/**
* Enum สำหรับเก็บผลลัพธ์ที่ได้จากการเลือกปุ่มใน dialog
*/
public enum PlatedCutoutsDialogResult {
OUTLINE,
SKELETON,
CANCEL
}
public static void main(String[] args) {
// การสร้างและแสดง GUI ควรทำบน Event Dispatch Thread (EDT)
SwingUtilities.invokeLater(() -> {
// สร้าง Frame หลัก (เพื่อให้ dialog อยู่ตรงกลางของ frame นี้)
JFrame frame = new JFrame("Custom JOptionPane Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
// เรียกแสดง custom dialog และรับผลลัพธ์
JDialog jd = new JDialog();
jd.setAlwaysOnTop(true);
jd.setLocationRelativeTo(null);
PlatedCutoutsDialogResult result = showCustomDialog(jd);
jd.dispose();
// แสดงผลลัพธ์ที่ได้ใน console
//System.out.println("ผู้ใช้เลือก: " + result);
System.out.println("Select -:> " + result);
// ปิดโปรแกรมหลังจาก dialog ถูกปิด
System.exit(0);
});
}
/**
* เมธอดสำหรับสร้างและแสดง JOptionPane ที่กำหนดเอง
* @param parentComponent Frame หรือ Component ที่เป็นเจ้าของ dialog นี้
* @return ค่า enum DialogResult ตามปุ่มที่ผู้ใช้เลือก
*/
public static PlatedCutoutsDialogResult showCustomDialog(JDialog parentComponent) {
// 1. สร้างข้อความด้วย HTML เพื่อปรับขนาดและสี
String htmlMessage = "<html><body style='width: 450px;'>"
+ "<h1 style='font-size: 16px;'>Script found line/arc in selected feature</h1>"
+ "<p style='font-size: 12px;color: red'>Script is going to move selected feature for creating plated cutouts</p>"
+ "<p style='font-size: 12px;'>How do you want to create?</p>"
//+ "<font color='red'>'Skeleton'</font> "
//+ "อาจใช้เวลาในการประมวลผลนานกว่าปกติ</p>"
+ "</body></html>";
JLabel messageLabel = new JLabel(htmlMessage);
// 2. สร้างและปรับแต่งปุ่ม JButton
JButton ignoreButton = new JButton("Ignore");
ignoreButton.setBackground(new Color(100, 200, 225));
ignoreButton.setFont(new Font("Arial", Font.BOLD, 16));
ignoreButton.setPreferredSize(new Dimension(110, 40));
JButton outlineButton = new JButton("Outline");
outlineButton.setBackground(new Color(153, 255, 102)); // สีฟ้าอ่อน
outlineButton.setFont(new Font("Arial", Font.BOLD, 16));
outlineButton.setPreferredSize(new Dimension(110, 40));
JButton skeletonButton = new JButton("Skeleton");
skeletonButton.setBackground(new Color(255, 204, 102)); // สีชมพูอ่อน
skeletonButton.setFont(new Font("Arial", Font.BOLD, 16));
skeletonButton.setPreferredSize(new Dimension(110, 40));
JButton cancelButton = new JButton("Cancel");
cancelButton.setBackground(new Color(255, 153, 153)); // สีเทาอ่อน
cancelButton.setFont(new Font("Arial", Font.BOLD, 16));
cancelButton.setPreferredSize(new Dimension(110, 40));
// สร้าง Array ของ Object ที่เป็นปุ่มที่เราสร้างขึ้น
Object[] buttonOptions = {outlineButton, skeletonButton, ignoreButton, cancelButton};
// **ส่วนที่แก้ไข:** สร้าง JOptionPane ก่อนเพื่อจะเพิ่ม Listener ให้กับปุ่ม
final JOptionPane optionPane = new JOptionPane(
messageLabel,
JOptionPane.QUESTION_MESSAGE,
JOptionPane.DEFAULT_OPTION,
null,
buttonOptions, // ส่ง Array ปุ่มเข้าไป
buttonOptions[0]);
// เพิ่ม ActionListener ให้กับปุ่ม Outline
outlineButton.addActionListener(e -> {
optionPane.setValue(0); // กำหนดค่าที่จะ return เป็น 0
Window window = SwingUtilities.getWindowAncestor(outlineButton);
window.dispose(); // สั่งปิดหน้าต่าง dialog
});
// เพิ่ม ActionListener ให้กับปุ่ม Skeleton
skeletonButton.addActionListener(e -> {
optionPane.setValue(1); // กำหนดค่าที่จะ return เป็น 1
Window window = SwingUtilities.getWindowAncestor(skeletonButton);
window.dispose(); // สั่งปิดหน้าต่าง dialog
});
// เพิ่ม ActionListener ให้กับปุ่ม Cancel
cancelButton.addActionListener(e -> {
optionPane.setValue(2); // กำหนดค่าที่จะ return เป็น 2
Window window = SwingUtilities.getWindowAncestor(cancelButton);
window.dispose(); // สั่งปิดหน้าต่าง dialog
});
// สร้าง JDialog จาก JOptionPane และแสดงผล
//optionPane.createDialog(parentComponent, "เลือกรูปแบบการแสดงผล").setVisible(true);
optionPane.createDialog(parentComponent, "Query").setVisible(true);
// 3. รับค่าที่ได้จากการกดปุ่ม (ที่เรา setValue ไว้)
Object selectedValue = optionPane.getValue();
int choice = -1; // ค่าเริ่มต้นในกรณีที่ปิด dialog โดยไม่กดปุ่ม
if (selectedValue instanceof Integer) {
choice = (Integer) selectedValue;
}
// 4. แปลงค่า index ที่ได้ (0, 1, 2) ให้เป็นค่า enum ที่ต้องการ
switch (choice) {
case 0: // ปุ่มแรก "Outline"
return PlatedCutoutsDialogResult.OUTLINE;
case 1: // ปุ่มที่สอง "Skeleton"
return PlatedCutoutsDialogResult.SKELETON;
case 2: // ปุ่มที่สาม "Cancel"
return PlatedCutoutsDialogResult.CANCEL;
default: // กรณีที่ผู้ใช้กดปิดหน้าต่าง (X) หรือค่าไม่ถูกต้อง
return PlatedCutoutsDialogResult.CANCEL;
}
}
}

อืม แต่ทำขนาดนี้ก็ใกล้เคียงกับสร้าง custom dialog แล้วล่ะนะ
แต่ถ้าไม่ตกแต่งมาก จะสามารถเขียนจบในไม่กี่บรรทัดได้เลย
อยากใส่ text field ก็ทำได้เลย


