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
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);
}
}
}
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.