0

I am a beginner in java swing an this is my first question. Before asking this I have searched long and not found any solution.

I have a main window with JmenuBar and MenuItems. My problem is that when I click on a menu item the already opened window is going beneath the main Window and new window popup on the top of the main widow.

My requirements

  1. When I click on a menu item the opened new window should be on the top of the previously opened window and and both windows should be over the main window.
  2. When I click again on menu at this position the drop down menu items should be over all the windows.

I have tried setAlwaysOnTop(true); to all the menu item windows. but it fails to meet my requirement (2.)

Please help me

Here is my code for main window

public class Main extends JFrame {
    private JPanel contentPane;
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Main frame = new Main();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public Main() {
        setTitle("Menu");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(500, 500, 400, 425);
        setLocationRelativeTo(null);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(null);
        
        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        
        JMenu mnPurchase = new JMenu("Purchase");
        menuBar.add(mnPurchase);
        
        JMenuItem mntmAddPurchaseInvoice = new JMenuItem("Purchase Invoice");
        mntmAddPurchaseInvoice.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Purchase frame = new Purchase();
                frame.setVisible(true);
                
                }
            });
        mnPurchase.add(mntmAddPurchaseInvoice);
        
        JMenu mnSales = new JMenu("Sales");
        menuBar.add(mnSales);
        
        JMenuItem mntmProcessSale = new JMenuItem("Generate Sales Invoice");
        mntmProcessSale.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Sale frame = new Sale();
                frame.setVisible(true);
            }
        });
        mnSales.add(mntmProcessSale);
    }
    
    public class Purchase extends JFrame {
    public void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Purchase frame = new Purchase();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public Purchase() {
        setTitle("Purchase");
        setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        setBounds(500, 500, 300, 300);
        setLocationRelativeTo(null);
        contentPane = new JPanel();
        setContentPane(contentPane);
        }
    }   
    
    public class Sale extends JFrame {
    public void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Sale frame = new Sale();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public Sale() {
        setTitle("Sale");
        setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        setBounds(500, 500, 300, 300);
        setLocationRelativeTo(null);
        contentPane = new JPanel();
        setContentPane(contentPane);
            }
        }
    }
Renoj Joseph
  • 93
  • 10
  • Can you reduce this down to a compilable exampe? It sounds like all you need is a JFrame, JMenu, and two windows that you open. As of now it is a bit overkill, with classes that we cannot use. – matt Jul 06 '20 at 11:49
  • https://stackoverflow.com/help/how-to-ask – matt Jul 06 '20 at 11:50
  • dear matt, I have edited the code as you said. Now there is a main window with menu bar and menu items. And two child windows viz purchase & sale open from the menu items. Now the first child window goes beneath the main window when clicked either on menu or content pane of main window. I want both the child windows over the main window, and at this stage when clicked on the menu, the drop menu should stay over the child windows. Please help me – Renoj Joseph Jul 06 '20 at 14:15
  • Have you considered a [JDesktopPane](https://docs.oracle.com/javase/7/docs/api/javax/swing/JDesktopPane.html) I suspected it would be possible to make the windows stay above the main jframe, but interleaving that with the menu sounds difficult. What was wrong with using always on top? – matt Jul 06 '20 at 16:36
  • Thanks a lot matt, it works!!! Excellent, meets all my requirements – Renoj Joseph Jul 07 '20 at 02:53

1 Answers1

0

This is a pretty trivial fix: Use a JDialog instead of a JFrame for your 'child' frames.

public class Sale extends JDialog {
    public Sale(JFrame owner) {
        super(owner);
        setTitle("Sale");
        setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        setBounds(500, 500, 300, 300);
        setLocationRelativeTo(null);
        contentPane = new JPanel();
        setContentPane(contentPane);
    }
}

I did that for both, Sale and Purchase and it seemed to work as described. I also had to change the action listener code.

mntmProcessSale.addActionListener( e -> {
            Sale frame = new Sale(this);
            frame.setVisible(true);
        });

I switched from an anonymous class to a lambda for the syntax of using this instead of the alternative Main.this notation.

matt
  • 10,892
  • 3
  • 22
  • 34
  • But matt, minimize and maximize buttons are not there in the child windows, Only Close button is present.Can we fix it too? at least for minimize button? – Renoj Joseph Jul 07 '20 at 05:22
  • Thats funny, you're the second person asking for that recently. Why not just use the close button? – matt Jul 07 '20 at 06:52
  • Ok it is not good to add other buttons to JDialog. Satisfied with Close Button. – Renoj Joseph Jul 07 '20 at 07:45
  • @RenojJoseph adding buttons is ok, but adding window decoration buttons is really tricky. They rely more heavily on native components, and I don't know of a solution that would be cross platform. You might be able to achieve what you want with JFrame and a a focus listeners, but I think you're getting to a point where the effort is going to exceed the reward. – matt Jul 07 '20 at 08:05
  • Yes you are right. Close button is enough at that position.Wasting time to add other window decoration button is worthless especially when it is heavy. I am very happy and fully satisfied with your help and thank you again. – Renoj Joseph Jul 07 '20 at 09:25