javaformsswinguser-interfacedesigner

How to open a new form from JOptionPane


I have an issue using Java Swing. I have an easy assignment but I don't know how to create a new form using JOptionPane.

The assignment must start with JOptionPane and it must start with a dialog with two options: Settings and Close. Clicking Settings opens a new form, which has a label and a button.

The label contains the current time, which is displayed in the format HH:mm:ss and changes every second, the Timer activates immediately. The button is used to choose the color for the given label. There is a Stop button, which can stop the Timer and an additional button that can restart the watch.

Also, the label must change color between the chosen red and the default color.

When I run the app, the dialog box pops up, however I couldn't figure it out how to open another form after clicking the Settings button.

`

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class Timer extends JFrame {
    private JPanel MainPanel;

    public Timer() {
        this.setContentPane(MainPanel);
        this.setTitle("Timer App");
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public static void main(String[] args) {
        Timer frame = new Timer();
        JButton settings = new JButton("Settings");
        JButton close = new JButton("Close");

        int option = JOptionPane.showOptionDialog(null, "Choose option", "Option dialog", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new String[] {"Settings", "Close"}, null);
    }
}

`


Solution

  • JOptionPane can safely be invoked from a thread which is not the event dispatch thread (EDT). Hence, in the below code, it is called from method main.

    Note that JOptionPane can be closed either by clicking on one of the option buttons, or pressing Esc key on computer keyboard or by pressing close button in window decorations. For Windows operating system, this is the X in the top, right corner of the window. Regardless of how you close the JOptionPane, method showOptionDialog will return YES_OPTION only if that button is clicked. In your program, that button displays the text Settings. Hence you only need to check whether the value returned by method showOptionDialog is YES_OPTION.

    Here is the code. Explanations appear after it.

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    import java.time.LocalTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.SwingConstants;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class StopWhat {
        private static final String  CLOSE = "Close";
        private static final String  SETTINGS = "Settings";
    
        private JButton  startButton;
        private JButton  stopButton;
        private JFrame  frame;
        private JLabel  theWatch;
        private Timer  timer;
    
        public StopWhat() {
            timer = new Timer(1000, this::updateTimer);
            timer.setDelay(0);
        }
    
        private void buildAndDisplayGui() {
            frame = new JFrame("Timer App");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            theWatch = new JLabel(getCurrentTime(), SwingConstants.CENTER);
            theWatch.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
            theWatch.setForeground(Color.red);
            theWatch.setToolTipText("Timer is currently stopped.");
            frame.add(theWatch, BorderLayout.CENTER);
            frame.add(createButtons(), BorderLayout.PAGE_END);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        private JPanel createButtons() {
            JPanel panel = new JPanel();
            startButton = new JButton("Start");
            startButton.setMnemonic(KeyEvent.VK_A);
            startButton.setToolTipText("Starts the timer.");
            startButton.addActionListener(this::startTimer);
            panel.add(startButton);
            stopButton = new JButton("Stop");
            stopButton.setMnemonic(KeyEvent.VK_O);
            stopButton.setToolTipText("Stops the timer.");
            stopButton.addActionListener(this::stopTimer);
            stopButton.setEnabled(false);
            panel.add(stopButton);
            return panel;
        }
    
        private String getCurrentTime() {
            return LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss", Locale.ENGLISH));
        }
    
        private void startTimer(ActionEvent event) {
            theWatch.setToolTipText(null);
            theWatch.setForeground(Color.black);
            startButton.setEnabled(false);
            timer.start();
            stopButton.setEnabled(true);
        }
    
        private void stopTimer(ActionEvent event) {
            timer.stop();
            theWatch.setForeground(Color.red);
            theWatch.setToolTipText("Timer is currently stopped.");
            startButton.setEnabled(true);
            stopButton.setEnabled(false);
        }
    
        private void updateTimer(ActionEvent event) {
            theWatch.setText(getCurrentTime());
        }
    
        public static void main(String[] args) {
            int choice = JOptionPane.showOptionDialog(null,
                                                      "Choose option",
                                                      "Option dialog",
                                                      JOptionPane.YES_NO_OPTION,
                                                      JOptionPane.QUESTION_MESSAGE,
                                                      null,
                                                      new String[]{SETTINGS, CLOSE},
                                                      SETTINGS);
            if (choice == JOptionPane.YES_OPTION) {
                String slaf = UIManager.getSystemLookAndFeelClassName();
                try {
                    UIManager.setLookAndFeel(slaf);
                }
                catch (ClassNotFoundException |
                       IllegalAccessException |
                       InstantiationException |
                       UnsupportedLookAndFeelException x) {
                    System.out.println("WARNING (ignored): Failed to set [System] look-and-feel.");
                }
                EventQueue.invokeLater(() -> new StopWhat().buildAndDisplayGui());
            }
            else {
                System.exit(0);
            }
        }
    }