Problem with Closing Application

Super26
Super26 used Ask the Experts™
on
I am having a slight problem with my frame.  I have an Exit button in the frame and when the user clicks it, I ask them if they are sure they want to exit, if they click no nothing happens, else the program exits.  I tried the same thing when the user clicks the 'X' on the frame window.  However, regardless of what the user selects the program ends.  I have this in my Frame's constructor.  I was hoping someone could point out what I am doing wrong.  Thanks.

   // Close window event
   this.addWindowListener(new WindowAdapter()
   {
      public void windowClosing(WindowEvent we)
       {
           int result =
               JOptionPane.showConfirmDialog(
                   null,
                   "Are you sure you want to close the window?",
                   "Close",
                   JOptionPane.YES_NO_OPTION);
           if (result == JOptionPane.YES_OPTION)
               {
               System.exit(0);
           }
       }
   });
   this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Hello,

  I tested your code, it looks ok.... here is my test code

import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class WindowClose extends JFrame
{

public WindowClose()
{
 // Close window event
 this.addWindowListener(new WindowAdapter()
 {
   public void windowClosing(WindowEvent we)
   {
    int result =
      JOptionPane.showConfirmDialog(
      null,"Are you sure you want to close the window?",
      "Close", JOptionPane.YES_NO_OPTION);

   if (result == JOptionPane.YES_OPTION)
   {
      System.exit(0);
   }
 }
 });

this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

 setBounds( 10,10,100,100 );
 show();
  }

  public static void main ( String[] argvs )
  {
       WindowClose wc = new WindowClose();
  }

}

hth,
Kok Choon.
i tested your code .. it worked fine ...

:)
-=[sKySh@DoW]=-

Author

Commented:
Hmm, it's weired I tested it in another frame too and it seems to be working fine.  But in this particular frame it doesn't work.  I have a few panels in the frame but I don't think that seems to be the problem.  I have a few menu items too.  I just don't know what is wrong with it.
OWASP Proactive Controls

Learn the most important control and control categories that every architect and developer should include in their projects.

why don't you paste the whole code for us to see ? it would be easier for us to see where ur error is

:)
-=[sKySh@DoW]=-

Author

Commented:
Here's my Constructor:

public MainFrame()
{
    // Close window event
    this.addWindowListener(new WindowAdapter()
    {
        public void windowClosing(WindowEvent event)
        {
            int result =
                JOptionPane.showConfirmDialog(
                    null,
                    "Are you sure you want to close the window?",
                    "Close",
                    JOptionPane.YES_NO_OPTION);
            if (result == JOptionPane.YES_OPTION)
                {
                System.exit(0);
            }
        }
    });
    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

    //Initialize frame
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    int screenHeight = screenSize.height;
    int screenWidth = screenSize.width;
    //Center frame in user's screen
    setSize(440, 315);
    setLocation(screenWidth / 4, screenHeight / 4);
    //Set title
    setTitle("Test1");

    //Add mnemonics
    menuFile.setMnemonic('F');
    menuReport.setMnemonic('R');
    menuHelp.setMnemonic('H');
    itemMainPage.setMnemonic('M');
    itemVideoRental.setMnemonic('I');
    itemCustomer.setMnemonic('T');
    itemSupplier.setMnemonic('S');
    itemVideo.setMnemonic('V');
    itemExit.setMnemonic('X');
    itemRetrieveOverdueRentals.setMnemonic('N');
    itemRetrieveVideos.setMnemonic('E');
    itemSummaryReport.setMnemonic('Y');
    itemAbout.setMnemonic('B');
    itemWeb.setMnemonic('W');
    itemSubMenu.setMnemonic('U');
    itemRetrieveCustomers.setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
    itemRetrieveSuppliers.setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
    itemRetrieveVideos.setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_3, ActionEvent.ALT_MASK));
    itemRetrieveVideoRentals.setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_4, ActionEvent.ALT_MASK));

    //Add menu items to submenu
    itemSubMenu.add(itemRetrieveCustomers);
    itemSubMenu.add(itemRetrieveSuppliers);
    itemSubMenu.add(itemRetrieveVideos);
    itemSubMenu.add(itemRetrieveVideoRentals);

    //Add menu items to main menu
    menuFile.add(itemMainPage);
    menuFile.add(new JSeparator());
    menuFile.add(itemVideoRental);
    menuFile.add(itemCustomer);
    menuFile.add(itemSupplier);
    menuFile.add(itemVideo);
    menuFile.add(new JSeparator());
    menuFile.add(itemExit);
    menuReport.add(itemSubMenu);
    menuReport.add(itemRetrieveOverdueRentals);
    menuReport.add(itemSummaryReport);
    menuHelp.add(itemAbout);
    menuHelp.add(itemWeb);

    //Add menu to menu bar
    menuBar.add(menuFile);
    menuBar.add(menuReport);
    menuBar.add(menuHelp);

    //Add listeners
    this.itemMainPage.addActionListener(this);
    this.itemVideoRental.addActionListener(this);
    this.itemCustomer.addActionListener(this);
    this.itemSupplier.addActionListener(this);
    this.itemVideo.addActionListener(this);
    this.itemSubMenu.addActionListener(this);
    this.itemExit.addActionListener(this);
    this.itemRetrieveOverdueRentals.addActionListener(this);
    this.itemSummaryReport.addActionListener(this);
    this.itemRetrieveCustomers.addActionListener(this);
    this.itemRetrieveSuppliers.addActionListener(this);
    this.itemRetrieveVideos.addActionListener(this);
    this.itemRetrieveVideoRentals.addActionListener(this);
    this.itemAbout.addActionListener(this);
    this.itemWeb.addActionListener(this);

    //Add the menu bar to the top of the frame
    this.setJMenuBar(menuBar);

    //Add the main panel to the frame
    Container contentPane = getContentPane();
    contentPane.add(panel);
}

Commented:
i think you're currently implementing the ActionListener class.... but maybe instead of implementing the action listener, why not try this pattern:

//Add listeners
   this.itemMainPage.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        itemMainPage_actionPerformed(e);
      }
    });

// now, you must have a method:

  void itemMainPage_actionPerformed(ActionEvent e) {
    // your implementation here....

  }

Commented:
nothing looks wrong with this code either.. is this frame enclosed in something else??
try debugging your windowClosing method like for example who is the WindowEvent that invokes it (event.getSource() )
and what is the value of OptionPane before it exits..


vemul
there seems to be no error

:)
-=[sKySh@DoW]=-

Author

Commented:
Yes, I am implementing action listener, but as you suggested, I commented out the implements part and ran it.  It still did the same thing however.  I just have no idea what could be wrong.
paste the whole program's code
maybe it will help

-=[sKySh@DoW]=-

Author

Commented:
import java.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class MainFrame extends JFrame implements ActionListener
{
    //Main panel
    private MainPanel panel = new MainPanel();

    //Menu
    public static JMenuBar menuBar = new JMenuBar();
    public static JMenu menuFile = new JMenu("File");
    public static JMenuItem itemMainPage = new JMenuItem("Main");
    public static JMenuItem itemVideoRental = new JMenuItem("Video Rental");
    public static JMenuItem itemCustomer = new JMenuItem("Customer");
    public static JMenuItem itemSupplier = new JMenuItem("Supplier");
    public static JMenuItem itemVideo = new JMenuItem("Video");
    public static JMenuItem itemExit = new JMenuItem("Exit");
    public static JMenu menuReport = new JMenu("Report");
    public static JMenu itemSubMenu = new JMenu("Retrieve Lists");
    public static JMenuItem itemRetrieveOverdueRentals =
        new JMenuItem("Retrieve Overdue Rentals");
    public static JMenuItem itemRetrieveCustomers =
        new JMenuItem("Retrieve Customer List");
    public static JMenuItem itemRetrieveSuppliers =
        new JMenuItem("Retrieve Supplier List");
    public static JMenuItem itemRetrieveVideos =
        new JMenuItem("Retrieve Video List");
    public static JMenuItem itemRetrieveVideoRentals =
        new JMenuItem("Retrieve Video Rental List");
    public static JMenuItem itemSummaryReport = new JMenuItem("Summary Report");
    public static JMenu menuHelp = new JMenu("Help");
    public static JMenuItem itemAbout = new JMenuItem("About");
    public static JMenuItem itemWeb = new JMenuItem("On the Web");
/**
 * MyPanel constructor comment.
 */
public MainFrame()
{
    // Close window event
    this.addWindowListener(new WindowAdapter()
    {
        public void windowClosing(WindowEvent event)
        {
            Object source = event.getSource();
            int result =
                JOptionPane.showConfirmDialog(
                    null,
                    "Are you sure you want to close the window?",
                    "Close",
                    JOptionPane.YES_NO_OPTION);
            if (result == JOptionPane.YES_OPTION)
                {
                System.exit(0);
            }
        }
    });
    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

    //Initialize frame
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    int screenHeight = screenSize.height;
    int screenWidth = screenSize.width;
    //Center frame in user's screen
    setSize(440, 315);
    setLocation(screenWidth / 4, screenHeight / 4);
    //Set title
    setTitle("Super Inc. Video Rental");

    //Add mnemonics
    menuFile.setMnemonic('F');
    menuReport.setMnemonic('R');
    menuHelp.setMnemonic('H');
    itemMainPage.setMnemonic('M');
    itemVideoRental.setMnemonic('I');
    itemCustomer.setMnemonic('T');
    itemSupplier.setMnemonic('S');
    itemVideo.setMnemonic('V');
    itemExit.setMnemonic('X');
    itemRetrieveOverdueRentals.setMnemonic('N');
    itemRetrieveVideos.setMnemonic('E');
    itemSummaryReport.setMnemonic('Y');
    itemAbout.setMnemonic('B');
    itemWeb.setMnemonic('W');
    itemSubMenu.setMnemonic('U');
    itemRetrieveCustomers.setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
    itemRetrieveSuppliers.setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
    itemRetrieveVideos.setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_3, ActionEvent.ALT_MASK));
    itemRetrieveVideoRentals.setAccelerator(
        KeyStroke.getKeyStroke(KeyEvent.VK_4, ActionEvent.ALT_MASK));

    //Add menu items to submenu
    itemSubMenu.add(itemRetrieveCustomers);
    itemSubMenu.add(itemRetrieveSuppliers);
    itemSubMenu.add(itemRetrieveVideos);
    itemSubMenu.add(itemRetrieveVideoRentals);

    //Add menu items to main menu
    menuFile.add(itemMainPage);
    menuFile.add(new JSeparator());
    menuFile.add(itemVideoRental);
    menuFile.add(itemCustomer);
    menuFile.add(itemSupplier);
    menuFile.add(itemVideo);
    menuFile.add(new JSeparator());
    menuFile.add(itemExit);
    menuReport.add(itemSubMenu);
    menuReport.add(itemRetrieveOverdueRentals);
    menuReport.add(itemSummaryReport);
    menuHelp.add(itemAbout);
    menuHelp.add(itemWeb);

    //Add menu to menu bar
    menuBar.add(menuFile);
    menuBar.add(menuReport);
    menuBar.add(menuHelp);

    //Add listeners
    this.itemMainPage.addActionListener(this);
    this.itemVideoRental.addActionListener(this);
    this.itemCustomer.addActionListener(this);
    this.itemSupplier.addActionListener(this);
    this.itemVideo.addActionListener(this);
    this.itemSubMenu.addActionListener(this);
    this.itemExit.addActionListener(this);
    this.itemRetrieveOverdueRentals.addActionListener(this);
    this.itemSummaryReport.addActionListener(this);
    this.itemRetrieveCustomers.addActionListener(this);
    this.itemRetrieveSuppliers.addActionListener(this);
    this.itemRetrieveVideos.addActionListener(this);
    this.itemRetrieveVideoRentals.addActionListener(this);
    this.itemAbout.addActionListener(this);
    this.itemWeb.addActionListener(this);

    //Add the menu bar to the top of the frame
    this.setJMenuBar(menuBar);

    //Add the main panel to the frame
    Container contentPane = getContentPane();
    contentPane.add(panel);
}
/**
 * Insert the method's description here.
 * Creation date: (10/9/2002 12:46:52 PM)
 * @param event java.awt.event.ActionEvent
 */
public void actionPerformed(ActionEvent event)
{
    Object source = event.getSource();

    //Main page menu was pressed
    if (source == itemMainPage)
        {
        panel.displayMainPage();
    }
    //Video Rental menu was pressed
    else if (source == itemVideoRental)
        {
        panel.displayVideoRentalPage("New Video Rental");
    }
    //Customer menu was pressed
    else if (source == itemCustomer)
        {
        panel.displayCustomerPage("New Customer");
    }
    //Supplier menu was pressed
    else if (source == itemSupplier)
        {
        panel.displaySupplierPage("New Supplier");
    }
    //Video menu was pressed
    else if (source == itemVideo)
        {
        panel.displayVideoPage("New Video");
    }
    //List All Customers menu was pressed
    else if (source == itemRetrieveCustomers)
        {
        panel.getCustomerFileDirectory();
    }
    //List All Suppliers menu was pressed
    else if (source == itemRetrieveSuppliers)
        {
        panel.getSupplierFileDirectory();
    }
    //List All Videos menu was pressed
    else if (source == itemRetrieveVideos)
        {
        panel.getVideoFileDirectory();
    }
    //List All Video Rentals menu was pressed
    else if (source == itemRetrieveVideoRentals)
        {
        panel.getVideoRentalFileDirectory();
    }
    //OverDue Rentals menu was pressed
    else if (source == itemRetrieveOverdueRentals)
        {
        panel.getOverDueRentalFileDirectory();
    }
    //Summary Report menu was pressed
    else if (source == itemSummaryReport)
        {
        panel.getSummaryReportFileDirectory();
    }
    //Exit menu was pressed
    else if (source == itemExit)
        {
        panel.exitProgram();
    }
    //About menu was pressed
    else if (source == itemAbout)
        {
        panel.displayAboutPage();
    }
    //Web menu was pressed
    else if (source == itemWeb)
        {
        panel.displayWebsite();
    }
}
}
Commented:
Hi! I've tested your program and works fine with few adjustments. This adjustments should not be the problem, the cahnges was maded in order to be able to compile the app.
I've used instead of MainPanel a JPanel because the source was not posted, and commented all the calls to MainPanel methods.
Also for the JOptionPane, instead of null parameter for parent, I've passed MainFrame.this, in order to get a centered dialog relative to the frame. I suggest you modify again from JPanel to MainPanel compile and run. If it works, repeat the process and uncomment from the actionPerformed method every call to a MainPanel method and see at which one it hangs. Don't uncomment all calls at once, but one at the time, compile and run. Here is the modified source:

import java.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class MainFrame extends JFrame implements ActionListener
{
   //Main panel
   private JPanel panel = new JPanel();

   //Menu
   public static JMenuBar menuBar = new JMenuBar();
   public static JMenu menuFile = new JMenu("File");
   public static JMenuItem itemMainPage = new JMenuItem("Main");
   public static JMenuItem itemVideoRental = new JMenuItem("Video Rental");
   public static JMenuItem itemCustomer = new JMenuItem("Customer");
   public static JMenuItem itemSupplier = new JMenuItem("Supplier");
   public static JMenuItem itemVideo = new JMenuItem("Video");
   public static JMenuItem itemExit = new JMenuItem("Exit");
   public static JMenu menuReport = new JMenu("Report");
   public static JMenu itemSubMenu = new JMenu("Retrieve Lists");
   public static JMenuItem itemRetrieveOverdueRentals =
       new JMenuItem("Retrieve Overdue Rentals");
   public static JMenuItem itemRetrieveCustomers =
       new JMenuItem("Retrieve Customer List");
   public static JMenuItem itemRetrieveSuppliers =
       new JMenuItem("Retrieve Supplier List");
   public static JMenuItem itemRetrieveVideos =
       new JMenuItem("Retrieve Video List");
   public static JMenuItem itemRetrieveVideoRentals =
       new JMenuItem("Retrieve Video Rental List");
   public static JMenuItem itemSummaryReport = new JMenuItem("Summary Report");
   public static JMenu menuHelp = new JMenu("Help");
   public static JMenuItem itemAbout = new JMenuItem("About");
   public static JMenuItem itemWeb = new JMenuItem("On the Web");
/**
* MyPanel constructor comment.
*/
public MainFrame()
{
   // Close window event
   this.addWindowListener(new WindowAdapter()
   {
       public void windowClosing(WindowEvent event)
       {
           Object source = event.getSource();
           int result =
               JOptionPane.showConfirmDialog(
                   MainFrame.this,
                   "Are you sure you want to close the window?",
                   "Close",
                   JOptionPane.YES_NO_OPTION);
           if (result == JOptionPane.YES_OPTION)
               {
               System.exit(0);
           }
       }
   });
   setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

   //Initialize frame
   Toolkit kit = Toolkit.getDefaultToolkit();
   Dimension screenSize = kit.getScreenSize();
   int screenHeight = screenSize.height;
   int screenWidth = screenSize.width;
   //Center frame in user's screen
   setSize(440, 315);
   setLocation(screenWidth / 4, screenHeight / 4);
   //Set title
   setTitle("Super Inc. Video Rental");

   //Add mnemonics
   menuFile.setMnemonic('F');
   menuReport.setMnemonic('R');
   menuHelp.setMnemonic('H');
   itemMainPage.setMnemonic('M');
   itemVideoRental.setMnemonic('I');
   itemCustomer.setMnemonic('T');
   itemSupplier.setMnemonic('S');
   itemVideo.setMnemonic('V');
   itemExit.setMnemonic('X');
   itemRetrieveOverdueRentals.setMnemonic('N');
   itemRetrieveVideos.setMnemonic('E');
   itemSummaryReport.setMnemonic('Y');
   itemAbout.setMnemonic('B');
   itemWeb.setMnemonic('W');
   itemSubMenu.setMnemonic('U');
   itemRetrieveCustomers.setAccelerator(
       KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
   itemRetrieveSuppliers.setAccelerator(
       KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
   itemRetrieveVideos.setAccelerator(
       KeyStroke.getKeyStroke(KeyEvent.VK_3, ActionEvent.ALT_MASK));
   itemRetrieveVideoRentals.setAccelerator(
       KeyStroke.getKeyStroke(KeyEvent.VK_4, ActionEvent.ALT_MASK));

   //Add menu items to submenu
   itemSubMenu.add(itemRetrieveCustomers);
   itemSubMenu.add(itemRetrieveSuppliers);
   itemSubMenu.add(itemRetrieveVideos);
   itemSubMenu.add(itemRetrieveVideoRentals);

   //Add menu items to main menu
   menuFile.add(itemMainPage);
   menuFile.add(new JSeparator());
   menuFile.add(itemVideoRental);
   menuFile.add(itemCustomer);
   menuFile.add(itemSupplier);
   menuFile.add(itemVideo);
   menuFile.add(new JSeparator());
   menuFile.add(itemExit);
   menuReport.add(itemSubMenu);
   menuReport.add(itemRetrieveOverdueRentals);
   menuReport.add(itemSummaryReport);
   menuHelp.add(itemAbout);
   menuHelp.add(itemWeb);

   //Add menu to menu bar
   menuBar.add(menuFile);
   menuBar.add(menuReport);
   menuBar.add(menuHelp);

   //Add listeners
   this.itemMainPage.addActionListener(this);
   this.itemVideoRental.addActionListener(this);
   this.itemCustomer.addActionListener(this);
   this.itemSupplier.addActionListener(this);
   this.itemVideo.addActionListener(this);
   this.itemSubMenu.addActionListener(this);
   this.itemExit.addActionListener(this);
   this.itemRetrieveOverdueRentals.addActionListener(this);
   this.itemSummaryReport.addActionListener(this);
   this.itemRetrieveCustomers.addActionListener(this);
   this.itemRetrieveSuppliers.addActionListener(this);
   this.itemRetrieveVideos.addActionListener(this);
   this.itemRetrieveVideoRentals.addActionListener(this);
   this.itemAbout.addActionListener(this);
   this.itemWeb.addActionListener(this);

   //Add the menu bar to the top of the frame
   this.setJMenuBar(menuBar);

   //Add the main panel to the frame
   Container contentPane = getContentPane();
   contentPane.add(panel);
}
/**
* Insert the method's description here.
* Creation date: (10/9/2002 12:46:52 PM)
* @param event java.awt.event.ActionEvent
*/
public void actionPerformed(ActionEvent event)
{
   Object source = event.getSource();

   //Main page menu was pressed
   if (source == itemMainPage)
       {
//       panel.displayMainPage();
   }
   //Video Rental menu was pressed
   else if (source == itemVideoRental)
       {
//       panel.displayVideoRentalPage("New Video Rental");
   }
   //Customer menu was pressed
   else if (source == itemCustomer)
       {
//       panel.displayCustomerPage("New Customer");
   }
   //Supplier menu was pressed
   else if (source == itemSupplier)
       {
//       panel.displaySupplierPage("New Supplier");
   }
   //Video menu was pressed
   else if (source == itemVideo)
       {
//       panel.displayVideoPage("New Video");
   }
   //List All Customers menu was pressed
   else if (source == itemRetrieveCustomers)
       {
//       panel.getCustomerFileDirectory();
   }
   //List All Suppliers menu was pressed
   else if (source == itemRetrieveSuppliers)
       {
//       panel.getSupplierFileDirectory();
   }
   //List All Videos menu was pressed
   else if (source == itemRetrieveVideos)
       {
//       panel.getVideoFileDirectory();
   }
   //List All Video Rentals menu was pressed
   else if (source == itemRetrieveVideoRentals)
       {
//       panel.getVideoRentalFileDirectory();
   }
   //OverDue Rentals menu was pressed
   else if (source == itemRetrieveOverdueRentals)
       {
//       panel.getOverDueRentalFileDirectory();
   }
   //Summary Report menu was pressed
   else if (source == itemSummaryReport)
       {
//       panel.getSummaryReportFileDirectory();
   }
   //Exit menu was pressed
   else if (source == itemExit)
       {
//       panel.exitProgram();
   }
   //About menu was pressed
   else if (source == itemAbout)
       {
//       panel.displayAboutPage();
   }
   //Web menu was pressed
   else if (source == itemWeb)
       {
//       panel.displayWebsite();
   }
}

public static void main(String[] args) {
  MainFrame mf = new MainFrame();
  mf.setVisible(true);
}
}

Author

Commented:
Oh man, I am so sorry for making you guys go through all this trouble.  I just figured out what I have been doing wrong all this time.  Seeing Ovi's modified program reminded me that MainFrame was not my actual runner application.  My main string was sitting in another class "Program", that is where I was calling my MainFrame.  Instead of putting my windowClosing event there, stupid me put it in the MainFrame class.  My brain was totally missing yesterday, I apologise for putting you guys through all this trouble.  Thanks so much for all your help.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial