Question

Sorry if this question has been asked many times already, but i have a custom JDialog. It is made so that it has a custom background, and appears over the frame that called it, takes in a message and then should return a YES or NO (0 or 1) upon selecting an option to the frame that called it.

public class JYOptionPane {

@SuppressWarnings("deprecation")
public static void showJY_YES_NO_Dialog(final JFrame frame, String Question) {
    darken(frame);
    frame.disable();
    final JDialog OptionPane = new JDialog();
    OptionPane.setAlwaysOnTop(true);
    OptionPane.setBounds(
            (int) (frame.getX() + (frame.getSize().getWidth() / 2))
                    - (350 / 2), (int) (frame.getY() + (frame.getSize()
                    .getHeight() / 2)) - (200 / 2), 350, 200);
    OptionPane.setResizable(false);
    OptionPane.setUndecorated(true);
    ImageIcon icon = new ImageIcon(
            LoginFrame.class.getResource("/Images/bgprompt.png"));
    Image backImage = icon.getImage();
    ImagePanel contentPane = new ImagePanel();
    contentPane.setBackgroundImage(backImage);
    OptionPane.setContentPane(contentPane);
    OptionPane.setBackground(new Color(0, 0, 0, 0));
    JLabel lblQuestion = new JLabel(Question);
    lblQuestion.setBounds(0, 40, 350, 30);
    lblQuestion.setFont(new Font("Calibria", Font.PLAIN, 20));
    lblQuestion.setForeground(Color.white);
    lblQuestion.setHorizontalAlignment(SwingConstants.CENTER);
    lblQuestion.setVerticalAlignment(SwingConstants.CENTER);
    lblQuestion.setAlignmentY(JComponent.CENTER_ALIGNMENT);
    OptionPane.add(lblQuestion);

    JYButton btnYes = new JYButton(
        new ImageIcon(LoginFrame.class.getResource("/buttons/default.png")),
        new ImageIcon(LoginFrame.class.getResource("/buttons/defaultprs.png")),
        new ImageIcon(LoginFrame.class.getResource("/buttons/defaulthv.png")));
    btnYes.setText("Yes");
    btnYes.setFont(new Font("Arial", Font.BOLD, 17));
    btnYes.setForeground(Color.white);
    btnYes.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            LoginFrame.setOPintNo(0);
            Class<? extends JFrame> f = frame.getClass();
            try {
                f.newInstance().setVisible(true);
                frame.dispose();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            OptionPane.dispose();
        }
    });
    btnYes.setBounds(40, 200 / 2 - 31 / 2 + 50, 121, 31);
    OptionPane.add(btnYes);

    OptionPane.getRootPane().setDefaultButton(btnYes);

    JYButton btnNo = new JYButton(new ImageIcon(
        LoginFrame.class.getResource("/buttons/default.png")),
        new ImageIcon(LoginFrame.class.getResource("/buttons/defaultprs.png")),
        new ImageIcon(LoginFrame.class.getResource("/buttons/defaulthv.png")));
    btnNo.setText("No");
    btnNo.setFont(new Font("Arial", Font.BOLD, 17));
    btnNo.setForeground(Color.white);
    btnNo.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            LoginFrame.setOPintNo(1);
            Class<? extends JFrame> f = frame.getClass();
            try {
                f.newInstance().setVisible(true);
                frame.dispose();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            OptionPane.dispose();
        }
    });
    btnNo.setBounds(189, 200 / 2 - 31 / 2 + 50, 121, 31);
    OptionPane.add(btnNo);

    OptionPane.setVisible(true);
}
}

I tried to let it return an int, but it doesn't seem to be able to assign the int to a variable. Therefore i created an int variable in my LoginFrame (that is never disposed, just invisible) and set it there and created a Get() function for it. However, how do i get the frame to call the Get() function after a selection has been made in the JDialog? It has to be called from the frame that i have passed in as final JFrame frame. Thanks!

Was it helpful?

Solution

You may want to take a look to How to Use Modality in Dialogs document. First off you don't need to pass-in a JFrame to your class, you can simply get rid of it. Take a look to this example:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Demo {

    private void createAndShowGUI() {

        JButton button = new JButton("Show dialog");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                MyOptionPane optionPane = new MyOptionPane();
                int option = optionPane.showYesNoMessage("Close frame", "Do you really want to close the frame?");
                if(option == MyOptionPane.YES) {
                    JButton button = (JButton)e.getSource();
                    SwingUtilities.getWindowAncestor(button).dispose();
                }
            }
        });

        JPanel content = new JPanel();
        content.add(new JLabel("Test:"));
        content.add(button);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public class MyOptionPane {

        public static final int YES = 0;
        public static final int NO = -1;

        private int choice = NO;

        public int showYesNoMessage(String title, String message) {

            JLabel label = new JLabel(message);

            JButton yesButton = new JButton("Yes");
            yesButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    choice = YES;
                    JButton button = (JButton)e.getSource();
                    SwingUtilities.getWindowAncestor(button).dispose();
                }
            });

            JButton noButton = new JButton("No");
            noButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    choice = NO;
                    JButton button = (JButton)e.getSource();
                    SwingUtilities.getWindowAncestor(button).dispose();
                }
            });

            JPanel buttons = new JPanel();
            buttons.add(yesButton);
            buttons.add(noButton);

            JPanel content = new JPanel(new BorderLayout(8, 8));
            content.add(label, BorderLayout.CENTER);
            content.add(buttons, BorderLayout.SOUTH);

            JDialog dialog = new JDialog();
            dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            dialog.setModal(true);
            dialog.setTitle(title);
            dialog.getContentPane().add(content);
            dialog.pack();
            dialog.setLocationRelativeTo(null);
            dialog.setVisible(true);

            return choice;
        }
    }

    public static void main(String[] args) {   
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {                
                new Demo().createAndShowGUI();
            }
        });
    }

}

Off-topic

About the use of setBounds() and as @AndrewThompson always says:

Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or combinations of them, along with layout padding & borders for white space.

So you should totally avoid the use of setBounds() and set(Preferred | Minimum | Maximum)Size() when you're working with Swing components.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top