Jaysmito Mukherjee
Jaysmito Mukherjee

Reputation: 1526

Prevent JPopupMenu from Closing on click

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!

Upvotes: 0

Views: 671

Answers (3)

Jaysmito Mukherjee
Jaysmito Mukherjee

Reputation: 1526

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

Upvotes: 3

Abra
Abra

Reputation: 20914

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.

Upvotes: 2

Siavash Renani
Siavash Renani

Reputation: 11

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

Upvotes: -1

Related Questions