0

I have a popup menu but it closes when i click something.

This is ok most of the time but sometimes it is required that it does not close on click!

Here is a piece of code i am working on which would help you to reproduce what i have :

import javax.swing.*;
import javax.swing.event.*;

import java.awt.*;
import java.awt.event.*;

public class Try{
    public static void main(String[] args) {
        JFrame frame = new JFrame("Trial");
        JPopupMenu menu = new JPopupMenu();
        JLabel label = new JLabel("This is a popup menu!");
        menu.add(label);
        frame.setSize(900, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        menu.show(frame, 450, 250);
    }
}

What i want it the menu wont close if i click on the frame!

Jaysmito Mukherjee
  • 1,467
  • 2
  • 10
  • 29

3 Answers3

3

So this is possible with JPopupMenu itself and there is no need of JDialog.

I had to override the setVisible method and allow to close the popup only after the close method is called!

Here is the code the popupmenu will only close after 5000ms and not on a click!

import javax.swing.*;
import javax.swing.event.*;

import java.awt.*;
import java.awt.event.*;

public class Try{
    public static void main(String[] args) {
        JFrame frame = new JFrame("Trial");
        MyPopupMenu menu = new MyPopupMenu();
        JLabel label = new JLabel("This is a popup menu!");
        menu.add(label);
        frame.setSize(900, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        menu.show(frame, 450, 250);
        Timer timer = new Timer(5000, new ActionListener() {
             public void actionPerformed(ActionEvent evt) {
                 menu.closePopup();         
                 ((Timer)evt.getSource()).stop();
             }
         });
         timer.start();
    }
}

class MyPopupMenu extends JPopupMenu{
    private boolean isHideAllowed;

    public MyPopupMenu(){
        super();
        this.isHideAllowed = false;
    }

    @Override
    public void setVisible(boolean visibility){
        if(isHideAllowed && !visibility)
            super.setVisible(false);
        else if(!isHideAllowed && visibility)
            super.setVisible(true);
    }

    public void closePopup(){
        this.isHideAllowed = true;
        this.setVisible(false);
    }
}
Jaysmito Mukherjee
  • 1,467
  • 2
  • 10
  • 29
  • 1
    Been researching for hours to get an idea of how to implement this idea. I've added a panel to a JMenuItem and I wanted it to be visible even when the user clicks outside of the popup menu area. With a specific button being clicked, it will either show or hide the popup menu. Your solution worked like a charm. Thanks mate! ;-) – Damoiskii May 26 '23 at 21:18
  • @Damoiskii great! – Jaysmito Mukherjee May 27 '23 at 08:16
2

The right tool for the right job.
Consider a non-modal, undecorated dialog (rather than a JPopupMenu).

Is this the kind of thing you require?

import java.awt.Color;

import javax.swing.*;

public class Try{
    public static void main(String[] args) {
        JFrame frame = new JFrame("Trial");
        JLabel label = new JLabel("This is a popup menu!");
        label.setBorder(BorderFactory.createLineBorder(Color.red, 2));
        frame.setSize(900, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        JDialog dlg = new JDialog(frame);
        dlg.add(label);
        dlg.setUndecorated(true);
        dlg.pack();
        dlg.setLocationRelativeTo(frame);
        dlg.setVisible(true);
    }
}

This is how it looks on my computer.

gui

If you click on the JFrame, the dialog remains visible.

Abra
  • 19,142
  • 7
  • 29
  • 41
-1

You need to set correct defaultCloseOperation-

import javax.swing.*;
import javax.swing.event.*;

import java.awt.*;
import java.awt.event.*;

public class Try{
    public static void main(String[] args) {
        JFrame frame = new JFrame("Trial");
        JPopupMenu menu = new JPopupMenu();
        JLabel label = new JLabel("This is a popup menu!");
        menu.add(label);
        frame.setSize(900, 500);
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.addWindowsListener(new WindowAdapter(){
           //Determine whether you should call frame.dispose or hide.
         });
        menu.show(frame, 450, 250);
    }
}

See also How to programmatically close a JFrame

  • Allright I misunderstood your question regarding JPopupMenu and assumed it was regarding the Jframe. Fine. Now, please re-read my answer regarding the last part. – Siavash Renani Apr 11 '21 at 18:03
  • What of the last part – Jaysmito Mukherjee Apr 11 '21 at 18:11
  • That you should determine whether you need to dispose the frame or hide it. I had assumed you were using the frame as the popup. I have read through the source code of JPopup. The only way implementing this behavior that I could see is by overriding SetVisibile method, but I judge that as a bad solution as the original implementation refers to many private variables. You are better off doing what @Abra suggests. – Siavash Renani Apr 11 '21 at 18:37
  • Please checkout my answer once – Jaysmito Mukherjee Apr 12 '21 at 03:30