Special dialog ด้วย JOptionPane

Special dialog ด้วย JOptionPane

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 ก็ทำได้เลย

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *