/*
 * MIT License
 *
 * Copyright (c) 2010 - 2021 The OSHI Project Contributors: https://github.com/oshi/oshi/graphs/contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package oshi.demo;

import java.awt.BorderLayout;
import java.awt.Container;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import oshi.SystemInfo;
import oshi.demo.gui.Config;
import oshi.demo.gui.FileStorePanel;
import oshi.demo.gui.InterfacePanel;
import oshi.demo.gui.MemoryPanel;
import oshi.demo.gui.OsHwTextPanel;
import oshi.demo.gui.OshiJPanel;
import oshi.demo.gui.ProcessPanel;
import oshi.demo.gui.ProcessorPanel;
import oshi.demo.gui.UsbPanel;

/**
 * Basic Swing class to demonstrate potential uses for OSHI in a monitoring GUI.
 * Not ready for production use and intended as inspiration/examples.
 */
public class OshiGui {

    private JFrame mainFrame;
    private JButton jMenu;
    private JMenuBar menuBar;

    private SystemInfo si = new SystemInfo();

    public static void main(String[] args) {
        OshiGui gui = new OshiGui();
        gui.init();
        SwingUtilities.invokeLater(gui::setVisible);
    }

    private void setVisible() {
        mainFrame.setVisible(true);
        jMenu.doClick();
    }

    private void init() {
        // Create the external frame
        mainFrame = new JFrame(Config.GUI_TITLE);
        mainFrame.setSize(Config.GUI_WIDTH, Config.GUI_HEIGHT);
        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        mainFrame.setResizable(true);
        mainFrame.setLocationByPlatform(true);
        mainFrame.setLayout(new BorderLayout());
        // Add a menu bar
        menuBar = new JMenuBar();
        mainFrame.setJMenuBar(menuBar);
        // Create the first menu option in this thread
        jMenu = getJMenu("OS & HW Info", 'O', "Hardware & OS Summary", new OsHwTextPanel(si));
        menuBar.add(jMenu);
        // Add later menu items in their own threads
        new Thread(new AddMenuBarTask("Memory", 'M', "Memory Summary", new MemoryPanel(si))).start();
        new Thread(new AddMenuBarTask("CPU", 'C', "CPU Usage", new ProcessorPanel(si))).start();
        new Thread(new AddMenuBarTask("FileStores", 'F', "FileStore Usage", new FileStorePanel(si))).start();
        new Thread(new AddMenuBarTask("Processes", 'P', "Processes", new ProcessPanel(si))).start();
        new Thread(new AddMenuBarTask("USB Devices", 'U', "USB Device list", new UsbPanel(si))).start();
        new Thread(new AddMenuBarTask("Network", 'N', "Network Params and Interfaces", new InterfacePanel(si))).start();
    }

    private JButton getJMenu(String title, char mnemonic, String toolTip, OshiJPanel panel) {
        JButton button = new JButton(title);
        button.setMnemonic(mnemonic);
        button.setToolTipText(toolTip);
        button.addActionListener(e -> {
            Container contentPane = this.mainFrame.getContentPane();
            if (contentPane.getComponents().length <= 0 || contentPane.getComponent(0) != panel) {
                resetMainGui();
                this.mainFrame.getContentPane().add(panel);
                refreshMainGui();
            }
        });

        return button;
    }

    private void resetMainGui() {
        this.mainFrame.getContentPane().removeAll();
    }

    private void refreshMainGui() {
        this.mainFrame.revalidate();
        this.mainFrame.repaint();
    }

    /**
     * Runnable class to add a JMenu to the menubar.
     */
    private final class AddMenuBarTask implements Runnable {
        private String title;
        private char mnemonic;
        private String toolTip;
        private OshiJPanel panel;

        private AddMenuBarTask(String title, char mnemonic, String toolTip, OshiJPanel panel) {
            this.title = title;
            this.mnemonic = mnemonic;
            this.toolTip = toolTip;
            this.panel = panel;
        }

        @Override
        public void run() {
            menuBar.add(getJMenu(title, mnemonic, toolTip, panel));
        }
    }
}

@@ -2310,32 +2310,98 @@
 tVisible(true);%0A
+        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);%0A
         jMenu.do
@@ -2405,24 +2405,24 @@
 .doClick();%0A
-
     %7D%0A%0A    p
@@ -2909,30 +2909,30 @@
 %0A        // 
-Create
+Assign
  the first m
@@ -2946,22 +2946,35 @@
 ion 
-in this thread
+to be clicked on visibility
 %0A   
@@ -3128,67 +3128,37 @@
 tems
- in their own threads%0A        new Thread(new AddMenuBarTask
+%0A        menuBar.add(getJMenu
 (%22Me
@@ -3204,32 +3204,24 @@
 yPanel(si)))
-.start()
 ;%0A        ne
@@ -3222,37 +3222,28 @@
     
-new Thread(new AddMenuBarTask
+menuBar.add(getJMenu
 (%22CP
@@ -3284,32 +3284,24 @@
 rPanel(si)))
-.start()
 ;%0A        ne
@@ -3302,37 +3302,28 @@
     
-new Thread(new AddMenuBarTask
+menuBar.add(getJMenu
 (%22Fi
@@ -3377,32 +3377,24 @@
 ePanel(si)))
-.start()
 ;%0A        ne
@@ -3395,37 +3395,28 @@
     
-new Thread(new AddMenuBarTask
+menuBar.add(getJMenu
 (%22Pr
@@ -3461,32 +3461,24 @@
 sPanel(si)))
-.start()
 ;%0A        ne
@@ -3479,37 +3479,28 @@
     
-new Thread(new AddMenuBarTask
+menuBar.add(getJMenu
 (%22US
@@ -3549,32 +3549,24 @@
 bPanel(si)))
-.start()
 ;%0A        ne
@@ -3567,37 +3567,28 @@
     
-new Thread(new AddMenuBarTask
+menuBar.add(getJMenu
 (%22Ne
@@ -3661,16 +3661,8 @@
 i)))
-.start()
 ;%0A  
@@ -4437,24 +4437,24 @@
 validate();%0A
+
         this
@@ -4484,641 +4484,7 @@
    %7D
-%0A%0A    /**%0A     * Runnable class to add a JMenu to the menubar.%0A     */%0A    private final class AddMenuBarTask implements Runnable %7B%0A        private String title;%0A        private char mnemonic;%0A        private String toolTip;%0A        private OshiJPanel panel;%0A%0A        private AddMenuBarTask(String title, char mnemonic, String toolTip, OshiJPanel panel) %7B%0A            this.title = title;%0A            this.mnemonic = mnemonic;%0A            this.toolTip = toolTip;%0A            this.panel = panel;%0A        %7D%0A%0A        @Override%0A        public void run() %7B%0A            menuBar.add(getJMenu(title, mnemonic, toolTip, panel));%0A        %7D%0A    %7D
 %0A%7D%0A

Remove non-Swing concurrency from demo GUI (#1637)