The multiple JFrame approach in java has been something I’ve implemented since I began programming Swing apps. For the most part, I did it in the beginning because I didn’t know any better. However, as I matured in my experience and knowledge as a developer and as began to read and absorb the opinions of so many more experienced Java devs online, I made an attempt to shift away from the multiple JFrame approach. As I began implementing model dialogs to control “child” windows and JInternalFrames for separate components, I was quite surprised, as I was doing what I thought was best-practice! But, as they say, It is not a good practice.
So, I’m going to explain the benefits of the multiple JFrame
approach, as well as myth-bust some of the cons that others have presented.
- Ultimate flexibility in layout – By allowing separate
JFrame
s, you give your end-user the ability to spread out and control what’s on his/her screen. The concept feels “open” and non-constricting. You lose this when you go towards one bigJFrame
and a bunch ofJInternalFrame
s. - Works well for very modularized applications – In my case, most of my applications have 3 – 5 big “modules” that really have nothing to do with each other whatsoever. For instance, one module might be a sales dashboard and one might be an accounting dashboard. They don’t talk to each other or anything. However, the executive might want to open both and them being separate frames on the taskbar makes his life easier.
- Myth: Hard to code – This is not true in my experience. I don’t see why it would be any easier to create a
JInternalFrame
than aJFrame
. In fact, in my experience,JInternalFrames
offer much less flexibility. I have developed a systematic way of handling the opening & closing ofJFrame
s in my applets that really works well. I control the frame almost completely from within the frame’s code itself; the creation of the new frame,SwingWorker
s that control the retrieval of data on background threads and the GUI code on EDT, restoring/bringing to front the frame if the user tries to open it twice, etc. All you need to open myJFrame
s is call a public static methodopen()
and the open method, combined with awindowClosing()
event handles the rest (is the frame already open? is it not open, but loading? etc.) I made this approach a template so it’s not difficult to implement for each frame. - Myth/Unproven: Resource Heavy – I’d like to see some facts behind this speculative statement. Although, perhaps, you could say a
JFrame
needs more space than aJInternalFrame
, even if you open up 100JFrame
s, how many more resources would you really be consuming? If your concern is memory leaks because of resources: callingdispose()
frees all resources used by the frame for garbage collection (and, again I say, aJInternalFrame
should invoke exactly the same concern).
I feel like I could write more. Anyways,
A great example of multiple frames/single document per frame (SDI) vs single frame/multiple documents per frame (MDI) is Microsoft Excel. Some of MDI benefits:
- it is possible to have a few windows in non rectangular shape – so they don’t hide desktop or other window from another process (e.g. web browser)
- it is possible to open a window from another process over one Excel window while writing in second Excel window – with MDI, trying to write in one of internal windows will give focus to the entire Excel window, hence hiding window from another process
- it is possible to have different documents on different screens, which is especially useful when screens do not have the same resolution.
Here is the Code to implement the Multiple JFrames
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | //import statement import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; //create class and extend with JFrame public class OldWindow extends JFrame { //declare variable private JPanel contentPane; /** * Launch the application. */ //main method public static void main(String[] args) { /* It posts an event (Runnable)at the end of Swings event list and is processed after all other GUI events are processed.*/ EventQueue.invokeLater(new Runnable() { public void run() { //try - catch block try { //Create object of OldWindow OldWindow frame = new OldWindow(); //set frame visible true frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public OldWindow() //constructor { //set frame title setTitle("Old Frame"); //set default close operation setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //set bounds of the frame setBounds(100, 100, 450, 300); //create object of JPanel contentPane = new JPanel(); //set border contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); //set ContentPane setContentPane(contentPane); //set null contentPane.setLayout(null); //create object of JButton and set label on it JButton btnNewFrame = new JButton("New"); //add actionListener btnNewFrame.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { //call the object of NewWindow and set visible true NewWindow frame = new NewWindow(); frame.setVisible(true); //set default close operation setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); } }); //set font of the Button btnNewFrame.setFont(new Font("Microsoft YaHei UI", Font.BOLD, 12)); //set bounds of the Button btnNewFrame.setBounds(180, 195, 78, 25); //add Button into contentPane contentPane.add(btnNewFrame); //set Label in the frame JLabel lblThisIsOld = new JLabel("This is Old Frame"); //set foreground color to the label lblThisIsOld.setForeground(Color.BLUE); //set font of that label lblThisIsOld.setFont(new Font("Times New Roman", Font.BOLD | Font.ITALIC, 24)); //set bound of the label lblThisIsOld.setBounds(127, 82, 239, 39); //add label to the contentPane contentPane.add(lblThisIsOld); } } |
And the for the new Window
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | //import statement import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; //create class and extend with JFrame public class NewWindow extends JFrame { //declare variable private JPanel contentPane; /** * Launch the application. */ //main method public static void main(String[] args) { /* It posts an event (Runnable)at the end of Swings event list and is processed after all other GUI events are processed.*/ EventQueue.invokeLater(new Runnable() { public void run() { //try - catch block try { //Create object of NewWindow NewWindow frame = new NewWindow(); //set frame visible true frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public NewWindow() //constructor { //set frame title setTitle("New Frame"); //set default close operation setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //set bounds of the frame setBounds(100, 100, 450, 300); //create object of JPanel contentPane = new JPanel(); //set border contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); //set ContentPane setContentPane(contentPane); //set null contentPane.setLayout(null); //label in the frame JLabel lblWelcome = new JLabel("Welcome this is New Frame"); //set fore ground color to the label lblWelcome.setForeground(Color.RED); //set font to the label lblWelcome.setFont(new Font("Times New Roman", Font.BOLD | Font.ITALIC, 24)); //set bounds of the label lblWelcome.setBounds(75, 100, 294, 32); //add label to the contentPane contentPane.add(lblWelcome); } } |
Take your time and comment on our article.