Search code examples
javaswingjpaneljoptionpane

How to make a JPanel that work like JOptionPane?


I'm making a simple POS system on NetBeans that would pop out a JPanel (quantity) asking for the quantity when the photo of the product is clicked. I am using a card layout and putting the panel inside the card layout doesn't seem to work as it is different in size. It's also very hard to position it since moving it makes a bigger panel (buy) absorb it and becomes a part of the panel, messing up the layout of that panel. I want to make the panel initially invisible and pop up only with this code:

public void mouseClicked(MouseEvent e) {
    if (e.getSource() == bpie )
    {
        String name = "Banoffee Pie";
        int price = 8;

        quantity.setVisible(true);
    }
}

I'm currently a beginner and have a hard time customizing JOptionPane dialogs and prefer the use of panels if possible. The problem could be solved with the use of another JFrame, however, the use of multiple frames according to experts, is bad practice.

Here is how I want the option pane to look:

pink JOptionPane


Solution

  • I'm currently a beginner and have a hard time customizing JOptionPanes

    The JOptionPane was made for utility rather than customizability. As soon as you start thinking 'How can I change a JOptionPane to..?' abandon the option pane and instead use a modal JDialog.

    Here is an example of using a dialog. I've tweaked the layout along these lines:

    • The food icons centered below the title bar.
    • Abandoned the simpler button names for more descriptive ones.
    • Adding the question and answer in the same line with a spinner to choose the number.

    Of course, colors need to be adjusted to suit the style seen above, which might (and might not - depending on further factors not immediately evident) best be approached by using a custom Pluggable Look and Feel.

    import java.awt.*;
    import java.awt.image.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.EmptyBorder;
    import java.util.Random;
    
    public class SweetShop {
    
        private JComponent ui = null;
        private static JFrame frame = new JFrame("Sweet Shop");
        private final JDialog dialog = new JDialog(frame, "Choose Sweets", true);
        Random random = new Random();
        SpinnerNumberModel quantityModel = new SpinnerNumberModel(1, 1, 144, 1);
    
        SweetShop() {
            initUI();
        }
    
        public final void initUI() {
            if (ui!=null) return;
    
            ui = new JPanel(new GridBagLayout());
            ui.setBorder(new EmptyBorder(40,100,40,100));
    
            JButton button = new JButton("Buy Sweets");
            ui.add(button);
            ActionListener openChooserListener = (ActionEvent e) -> {
                dialog.setLocationRelativeTo(button);
                dialog.setVisible(true);
            };
            button.addActionListener(openChooserListener);
    
            dialog.add(getSweetSelectionPanel());
            dialog.pack();
        }
    
        private JPanel getSweetSelectionPanel() {
            JPanel panel = new JPanel(new BorderLayout());
            int pad = 10;
            panel.setBorder(new EmptyBorder(pad, pad, pad, pad));
    
            JPanel iconPanel = new JPanel();
            for (int ii=0; ii<12; ii++) {
                iconPanel.add(new JLabel(new ImageIcon(getSize16Image())));
            }
            panel.add(iconPanel, BorderLayout.PAGE_START);
    
            JPanel buttonPanel = new JPanel();
            JButton okButton = new JButton("Buy Delicious");
            buttonPanel.add(okButton);
            ActionListener okListener = (ActionEvent e) -> {
                System.out.println("Yuuuummmmm.. x " + 
                    quantityModel.getNumber().intValue());
                dialog.setVisible(false);
            };
            okButton.addActionListener(okListener);
    
            JButton cancelButton = new JButton("No Thanks");
            buttonPanel.add(cancelButton);
            ActionListener cancelListener = (ActionEvent e) -> {
                System.out.println("I just like licking them.");
                dialog.setVisible(false);
            };
            cancelButton.addActionListener(cancelListener);
            panel.add(buttonPanel, BorderLayout.PAGE_END);
    
            JPanel questionPanel = new JPanel();
            questionPanel.setBorder(new EmptyBorder(20, 50, 20, 50));
            panel.add(questionPanel); // automatically uses CENTER constraint
            JLabel label = new JLabel("How many do you wish to buy?");
            Font font = label.getFont();
            label.setFont(font.deriveFont(Font.ITALIC));
            label.setText("How many do you wish to buy?");
            label.setBorder(new EmptyBorder(5, 5, 5, 5));
            questionPanel.add(label);
            JSpinner spinner = new JSpinner(quantityModel);
            questionPanel.add(spinner);
    
            return panel;
        }
    
        private Image getSize16Image() {
            int w = 16;
            int h = 16;
            if (random.nextBoolean()) {
                w = random.nextInt(12) + 4;
            } else {
                h = random.nextInt(12) + 4;
            }
            BufferedImage bi = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
            return bi;
        }
    
        public JComponent getUI() {
            return ui;
        }
    
        public static void main(String[] args) {
            Runnable r = () -> {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                SweetShop o = new SweetShop();
    
                frame = new JFrame(o.getClass().getSimpleName());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationByPlatform(true);
    
                frame.setContentPane(o.getUI());
                frame.pack();
                frame.setMinimumSize(frame.getSize());
    
                frame.setVisible(true);
            };
            SwingUtilities.invokeLater(r);
        }
    }