Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm creating a "Snake" game as homework and I've passed hours searching around all the possible methods to close a JFrame, without conclusion. I started the program creating a JFrame with a background image and a menu, nothing more. When I click on the "Start game" button (JMenuItem) it opens a new JFrame with a thread to play the game. My problem is that the first JFrame doesn't close anyway I try to. I tried using these solutions and these and these but that JFrame's still there. It looks like the only command he listens to is the "EXIT_ON_CLOSE" as DefaultCloseOperation, not even the "DISPOSE_ON_CLOSE" is working. This is my SnakeFrame class:
package snake;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
/**
*
* #author Giacomo
*/
public class SnakeFrame extends Snake{
protected JMenuItem start = new JMenuItem("Start game");
public void pullThePlug(final SnakeFrame frame) {
/*// this will make sure WindowListener.windowClosing() et al. will be called.
WindowEvent wev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
// this will hide and dispose the frame, so that the application quits by
// itself if there is nothing else around.
frame.setVisible(false);
frame.dispose();*/
frame.addComponentListener(new ComponentAdapter() {
#Override
public void componentHidden(ComponentEvent e) {
((JFrame)(e.getComponent())).dispose();
}
});
}
public int game(final SnakeFrame frame,final JFrame gameFrame){
short game_ok=0;
try{
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
GameThread gamethread = new GameThread(frame,gameFrame);
gamethread.start();
pullThePlug(frame);
}
});
}
catch(Exception e){
game_ok=1;
}
return game_ok;
}
//-----------Frame initialization with relative Listeners and Events.---------\\
public SnakeFrame(){
JFrame frame= new JFrame("Le Snake");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
frame.setBounds(((int)larghezza/4),((int)altezza/4),800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
ImageIcon icon = new ImageIcon("C:\\Users\\Giacomo\\Documents"
+ "\\NetBeansProjects\\Snake\\src\\res\\Snake-icon.png");
frame.setIconImage(icon.getImage());
frame.setResizable(false);
frame.setLayout(new GridLayout());
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
menuBar.setBounds(1, 1, frame.getWidth(),frame.getHeight()/25);
JMenuItem close = new JMenuItem("Exit");
close.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
menu.add(start);
menu.add(close);
frame.setJMenuBar(menuBar);
try {
frame.setContentPane(new JLabel(new ImageIcon(ImageIO.read
(new File("C:\\Users\\Giacomo\\Documents\\NetBeansProjects\\"
+ "Snake\\src\\res\\default.png")))));
} catch (IOException e) {
System.out.println("Exception with the background image.");
}
frame.pack();
}
//-------------------------Frame initialization ended.-----------------------\\
}
Here's the game thread's code instead (for now):
package snake;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
/**
*
* #author Giacomo
*/
public class GameThread extends Thread implements Runnable{
private final SnakeFrame frame;
private final JFrame gameFrame;
public GameThread(final SnakeFrame f,final JFrame gF){
this.frame = f;
this.gameFrame = gF;
}
#Override
public void run(){
System.out.println("Game Thread started.");
final Label[][] griglia = new Label[50][50];
final Container container = new Container();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
gameFrame.setVisible(true);
gameFrame.setBounds(((int)larghezza/4),((int)altezza/4),
800, 600);
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon icon = new ImageIcon("C:\\Users\\Giacomo\\Documents"
+ "\\NetBeansProjects\\Snake\\src\\res\\Snake-icon.png");
gameFrame.setIconImage(icon.getImage());
gameFrame.setResizable(false);
gameFrame.addWindowListener(new WindowAdapter(){
#Override
public void windowClosing(WindowEvent e){
//Just to be sure he dies.
gameFrame.dispose();
frame.dispose();
System.exit(0);
}
});
gameFrame.setLayout(new GridLayout(50,50));
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
griglia[i][j] = new Label();
griglia[i][j].setBackground(Color.BLACK);
container.add(griglia[i][j]);
}
}
gameFrame.add(container);
}
}
Did I forget something? Does anyone have an idea? Sorry if my code's bad but I'm at school to learn :P I'm using NetBeans 8.0.2. Thanks everyone.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EDIT:
I have now solved most of the problems I had, and here is the main:
public static void main(String[] args) {
final SnakeFrame frame = new SnakeFrame();
short isGameOk;
isGameOk =(short)frame.game(frame);
if(isGameOk==1)
System.err.println("Game Error!");
}
while here's the SnakeFrame class ("fixed"):
public class SnakeFrame extends Snake{
private final JMenuItem start = new JMenuItem("Start game");
private final BackgroundPanel defaultpanel;
public int game(final SnakeFrame frame){
short game_ok=0;
try{
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
defaultpanel.setVisible(false);
JPanel panel = new JPanel();
JLabel[][] griglia = new JLabel[50][50];
panel.setLayout(new GridLayout(50,50));
for(int i=0;i<50;i++){
for(int j=0;j<50;j++){
griglia[i][j] = new JLabel();
griglia[i][j].setBackground(Color.BLACK);
panel.add(griglia[i][j]);
}
}
frame.add(panel);
griglia[45][30].setIcon(new ImageIcon
("src\\res\\sneikhead.png"));
panel.setVisible(true);
}
});
}
catch(Exception e){
game_ok=1;
}
return game_ok;
}
//-----------Frame initialization with relative Listeners and Events.---------\\
public SnakeFrame(){
JFrame frame= new JFrame("Le Snake");
ImageIcon imm = new ImageIcon(getClass().getResource
("/res/default.png"));
Image background = imm.getImage();
defaultpanel = new BackgroundPanel(background, BackgroundPanel.ACTUAL,
1.0f, 0.5f);
frame.add(defaultpanel);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double larghezza = screenSize.getWidth();
double altezza = screenSize.getHeight();
frame.setBounds(((int)larghezza/4),((int)altezza/4),800, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon imageIcon = new ImageIcon(getClass().getResource("/res/Snake-icon.png"));
Image icon = imageIcon.getImage();
frame.setIconImage(icon);
frame.setResizable(false);
frame.setLayout(new GridLayout());
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
menuBar.add(menu);
menuBar.setBounds(1, 1, frame.getWidth(),frame.getHeight()/25);
JMenuItem close = new JMenuItem("Exit");
close.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
menu.add(start);
menu.add(close);
frame.setJMenuBar(menuBar);
frame.pack();
}
//-------------------------Frame initialization ended.-----------------------\\
}
I am now able to change the SnakeFrame's background with a defaultpanel.setVisible(false); but the panel full of black colored labels that should show isn't visible even if I set it true. How can I get it visible? Thank you.
Some general comments:
Why are you creating a second frame? Usually a game is played in its own frame? You have a menu that allows you to change options of the game and this is done by display a modal JDialog. Then you have a "Start" button that starts the game by adding a panel to the existing frame.
Don't use a ComponentListener on the frame. There is no need to handle componentHidden.
Why do you have the game() method? I don't even see in your code where you invoke the method. Just add the actionListener to the Start menu item in the constructor of your class. Keep the creation of the menu item and the assignment of the actionListener in the same block of code so we don't need to look all over the class to find all the related properties for the component.
When I click on the "Start game" button (JMenuItem) it opens a new JFrame with a thread to play the game.
This is wrong. You should NOT be starting a separate Thread. All Swing components should be created on the Event Dispatch Thread (EDT). So basically the code should just be invoked from within your ActionListener since all event code does execute on the EDT.
It looks like the only command he listens to is the "EXIT_ON_CLOSE" as DefaultCloseOperation, not even the "DISPOSE_ON_CLOSE" is working.
Those are properties that you set for the frame. Then when the user clicks on the "X" button at the top/right of the frame the frame will close depending on the property. These properties have no effect when you invoke frame.dispose() or System.exit() directly.
GameThread gamethread = new GameThread(frame,gameFrame);
Why are you passing the frame to your other class? If you goal is to close the original frame. Then close the frame here after creating the other frame. In fact why do you even have a reference to the "gameFrame" here. If you have another class that creates the components of the frame, it should create the frame as well.
pullThePlug(frame);
This code does nothing. You are invoking this method AFTER you attempt to close the frame.
In general, I can't follow your logic since the code is not complete. However as a general rule an application should only contain a single JFrame. Hiding/showing multiple frames is not an experience uses want to see. When a new game starts you should just refresh the content pane of the existing frame.
Related
I'm trying to use a few JDialogs inside my form JPanel to notify the user of incorrect data and form submission.
I'm just a bit confused with the JDialog constructor. I'd want to link the dialog to the panel (only because that's where it's created), but obviously the only owner parameters that are allowed are top level Frames (which I don't think I can access from the JPanel), or a Dialog (which I can't see helping me).
I could pass a reference for the Frame down to the JPanel, but isn't that a bit strange design wise? Or am I misunderstanding the class, or just more generally where the JDialog should be instantiated?
Hope I've made myself clear, I can make a sscce if it helps. Thanks.
the only owner parameters that are allowed are top level Frames (which I don't think I can access from the JPanel
You can access the parent frame of the panel by using:
Window window = SwingUtilities.windowForComponent( yourPanelHere );
Then just use the window as the owner of the dialog.
JComponent.getTopLevelAncestor gives you the owner of the JPanel:
Returns the top-level ancestor of this component (either the
containing Window or Applet), or null if this component has not been
added to any container.
You can try it:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class DialogTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
EventQueue.invokeLater(new Runnable() {
public void run() {
DialogFrame frame = new DialogFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
/**
* Frame contains menu. When we choose menu "File-> About" JDialog will be shown
*/
class DialogFrame extends JFrame {
public DialogFrame() {
setTitle("DialogTest");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// Menu
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
// Add About & Exit.
// Choose About - > About
JMenuItem aboutItem = new JMenuItem("About");
aboutItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (dialog == null) //if not
{
dialog = new AboutDialog(DialogFrame.this);
}
dialog.setVisible(true); // to show dialog
}
});
fileMenu.add(aboutItem);
// When Exit
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
fileMenu.add(exitItem);
}
public static final int DEFAULT_WIDTH = 300;
public static final int DEFAULT_HEIGHT = 200;
private AboutDialog dialog;
}
/*
* Modal dialog waits on click
*/
class AboutDialog extends JDialog {
public AboutDialog(JFrame owner) {
super(owner, "About DialogTest", true);
// Mark with HTML centration
add(new JLabel(
"<html><h1><i>Все о Java</i></h1><hr>"
+ "Something about java and JDialog</html>"),
BorderLayout.CENTER);
// When push "ok" dialog window will be closed
JButton ok = new JButton("ok");
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
setVisible(false);
}
});
// Button ОК down of panel
JPanel panel = new JPanel();
panel.add(ok);
add(panel, BorderLayout.SOUTH);
setSize(260, 160);
}
}
I have created one GUI in which I have used a JFrame. How should I make it Modal?
Your best bet is to use a JDialog instead of a JFrame if you want to make the window modal. Check out details on the introduction of the Modality API in Java 6 for info. There is also a tutorial.
Here is some sample code which will display a JPanel panel in a JDialog which is modal to Frame parentFrame. Except for the constructor, this follows the same pattern as opening a JFrame.
final JDialog frame = new JDialog(parentFrame, frameTitle, true);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
Edit: updated Modality API link & added tutorial link (nod to #spork for the bump).
You can create a class that is passed a reference to the parent JFrame and holds it in a JFrame variable. Then you can lock the frame that created your new frame.
parentFrame.disable();
//Some actions
parentFrame.enable();
just replace JFrame to JDialog in class
public class MyDialog extends JFrame // delete JFrame and write JDialog
and then write setModal(true); in constructor
After that you will be able to construct your Form in netbeans
and the form becomes modal
Create a new JPanel form
Add your desired components and code to it
YourJPanelForm stuff = new YourJPanelForm();
JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);
Your modal dialog awaits...
As far as I know, JFrame cannot do Modal mode. Use JDialog instead and call setModalityType(Dialog.ModalityType type) to set it to be modal (or not modal).
If you're prepared to use a JDialog instead of a JFrame, you can set the ModalityType to APPLICATION_MODAL.
This provides identical behaviour to your typical JOptionPane:
import java.awt.event.ActionEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class MyDialog extends JFrame {
public MyDialog() {
setBounds(300, 300, 300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(new FlowLayout());
JButton btn = new JButton("TEST");
add(btn);
btn.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e) {
showDialog();
}
});
}
private void showDialog()
{
JDialog dialog = new JDialog(this, Dialog.ModalityType.APPLICATION_MODAL);
//OR, you can do the following...
//JDialog dialog = new JDialog();
//dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
dialog.setBounds(350, 350, 200, 200);
dialog.setVisible(true);
}
public static void main(String[] args)
{
new MyDialog();
}
}
This static utility method shows a modal JFrame by secretly opening a modal JDialog, too. I used this successfully and with proper behavior on Windows 7, 8, and 10-with-multiple-desktops.
It's a nice example for the very rarely used feature of local classes.
import javax.swing.*;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
// ... (class declaration)
/**
* Shows an already existing JFrame as if it were a modal JDialog. JFrames have the upside that they can be
* maximized.
* <p>
* A hidden modal JDialog is "shown" to effect the modality.
* <p>
* When the JFrame is closed, this method's listener will pick up on that, close the modal JDialog, and remove the
* listener.
*
* made by dreamspace-president.com
*
* #param window the JFrame to be shown
* #param owner the owner window (can be null)
* #throws IllegalArgumentException if argument "window" is null
*/
public static void showModalJFrame(final JFrame window, final Frame owner) {
if (window == null) {
throw new IllegalArgumentException();
}
window.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
window.setVisible(true);
window.setAlwaysOnTop(true);
final JDialog hiddenDialogForModality = new JDialog(owner, true);
final class MyWindowCloseListener extends WindowAdapter {
#Override
public void windowClosed(final WindowEvent e) {
window.dispose();
hiddenDialogForModality.dispose();
}
}
final MyWindowCloseListener myWindowCloseListener = new MyWindowCloseListener();
window.addWindowListener(myWindowCloseListener);
final Dimension smallSize = new Dimension(80, 80);
hiddenDialogForModality.setMinimumSize(smallSize);
hiddenDialogForModality.setSize(smallSize);
hiddenDialogForModality.setMaximumSize(smallSize);
hiddenDialogForModality.setLocation(-smallSize.width * 2, -smallSize.height * 2);
hiddenDialogForModality.setVisible(true);
window.removeWindowListener(myWindowCloseListener);
}
The only code that have worked for me:
childFrame.setAlwaysOnTop(true);
This code should be called on the main/parent frame before making the child/modal frame visible. Your child/modal frame should also have this code:
parentFrame.setFocusableWindowState(false);
this.mainFrame.setEnabled(false);
What I've done in this case is, in the primary jframe that I want to keep visible (for example, a menu frame), I deselect the option focusableWindowState in the property window so It will be FALSE. Once that is done, the jframes I call don´t lose focus until I close them.
As others mentioned, you could use JDialog. If you don't have access to the parent frame or you want to freeze the hole application just pass null as a parent:
final JDialog frame = new JDialog((JFrame)null, frameTitle, true);
frame.setModal(true);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
There's a bit of code that might help:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class ModalJFrame extends JFrame {
Object currentWindow = this;
public ModalJFrame()
{
super();
super.setTitle("Main JFrame");
super.setSize(500, 500);
super.setResizable(true);
super.setLocationRelativeTo(null);
JMenuBar menuBar = new JMenuBar();
super.setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
JMenu editMenu = new JMenu("Edit");
menuBar.add(fileMenu);
menuBar.add(editMenu);
JMenuItem newAction = new JMenuItem("New");
JMenuItem openAction = new JMenuItem("Open");
JMenuItem exitAction = new JMenuItem("Exit");
JMenuItem cutAction = new JMenuItem("Cut");
JMenuItem copyAction = new JMenuItem("Copy");
JMenuItem pasteAction= new JMenuItem("Paste");
fileMenu.add(newAction);
fileMenu.add(openAction);
fileMenu.addSeparator();
fileMenu.add(exitAction);
editMenu.add(cutAction);
editMenu.add(copyAction);
editMenu.addSeparator();
editMenu.add(pasteAction);
newAction.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
JFrame popupJFrame = new JFrame();
popupJFrame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
((Component) currentWindow).setEnabled(true); }
});
((Component) currentWindow).setEnabled(false);
popupJFrame.setTitle("Pop up JFrame");
popupJFrame.setSize(400, 500);
popupJFrame.setAlwaysOnTop(true);
popupJFrame.setResizable(false);
popupJFrame.setLocationRelativeTo(getRootPane());
popupJFrame.setVisible(true);
popupJFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
});
exitAction.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
System.exit(0);
}
});
}
public static void main(String[] args) {
ModalJFrame myWindow = new ModalJFrame();
myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myWindow.setVisible(true);
}
}
not sure the contetns of your JFrame, if you ask some input from users, you can use JOptionPane, this also can set JFrame as modal
JFrame frame = new JFrame();
String bigList[] = new String[30];
for (int i = 0; i < bigList.length; i++) {
bigList[i] = Integer.toString(i);
}
JOptionPane.showInputDialog(
frame,
"Select a item",
"The List",
JOptionPane.PLAIN_MESSAGE,
null,
bigList,
"none");
}
The most simple way is to use pack() method before visualizing the JFrame object. here is an example:
myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);
I have created one GUI in which I have used a JFrame. How should I make it Modal?
Your best bet is to use a JDialog instead of a JFrame if you want to make the window modal. Check out details on the introduction of the Modality API in Java 6 for info. There is also a tutorial.
Here is some sample code which will display a JPanel panel in a JDialog which is modal to Frame parentFrame. Except for the constructor, this follows the same pattern as opening a JFrame.
final JDialog frame = new JDialog(parentFrame, frameTitle, true);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
Edit: updated Modality API link & added tutorial link (nod to #spork for the bump).
You can create a class that is passed a reference to the parent JFrame and holds it in a JFrame variable. Then you can lock the frame that created your new frame.
parentFrame.disable();
//Some actions
parentFrame.enable();
just replace JFrame to JDialog in class
public class MyDialog extends JFrame // delete JFrame and write JDialog
and then write setModal(true); in constructor
After that you will be able to construct your Form in netbeans
and the form becomes modal
Create a new JPanel form
Add your desired components and code to it
YourJPanelForm stuff = new YourJPanelForm();
JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);
Your modal dialog awaits...
As far as I know, JFrame cannot do Modal mode. Use JDialog instead and call setModalityType(Dialog.ModalityType type) to set it to be modal (or not modal).
If you're prepared to use a JDialog instead of a JFrame, you can set the ModalityType to APPLICATION_MODAL.
This provides identical behaviour to your typical JOptionPane:
import java.awt.event.ActionEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class MyDialog extends JFrame {
public MyDialog() {
setBounds(300, 300, 300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(new FlowLayout());
JButton btn = new JButton("TEST");
add(btn);
btn.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e) {
showDialog();
}
});
}
private void showDialog()
{
JDialog dialog = new JDialog(this, Dialog.ModalityType.APPLICATION_MODAL);
//OR, you can do the following...
//JDialog dialog = new JDialog();
//dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
dialog.setBounds(350, 350, 200, 200);
dialog.setVisible(true);
}
public static void main(String[] args)
{
new MyDialog();
}
}
This static utility method shows a modal JFrame by secretly opening a modal JDialog, too. I used this successfully and with proper behavior on Windows 7, 8, and 10-with-multiple-desktops.
It's a nice example for the very rarely used feature of local classes.
import javax.swing.*;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
// ... (class declaration)
/**
* Shows an already existing JFrame as if it were a modal JDialog. JFrames have the upside that they can be
* maximized.
* <p>
* A hidden modal JDialog is "shown" to effect the modality.
* <p>
* When the JFrame is closed, this method's listener will pick up on that, close the modal JDialog, and remove the
* listener.
*
* made by dreamspace-president.com
*
* #param window the JFrame to be shown
* #param owner the owner window (can be null)
* #throws IllegalArgumentException if argument "window" is null
*/
public static void showModalJFrame(final JFrame window, final Frame owner) {
if (window == null) {
throw new IllegalArgumentException();
}
window.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
window.setVisible(true);
window.setAlwaysOnTop(true);
final JDialog hiddenDialogForModality = new JDialog(owner, true);
final class MyWindowCloseListener extends WindowAdapter {
#Override
public void windowClosed(final WindowEvent e) {
window.dispose();
hiddenDialogForModality.dispose();
}
}
final MyWindowCloseListener myWindowCloseListener = new MyWindowCloseListener();
window.addWindowListener(myWindowCloseListener);
final Dimension smallSize = new Dimension(80, 80);
hiddenDialogForModality.setMinimumSize(smallSize);
hiddenDialogForModality.setSize(smallSize);
hiddenDialogForModality.setMaximumSize(smallSize);
hiddenDialogForModality.setLocation(-smallSize.width * 2, -smallSize.height * 2);
hiddenDialogForModality.setVisible(true);
window.removeWindowListener(myWindowCloseListener);
}
The only code that have worked for me:
childFrame.setAlwaysOnTop(true);
This code should be called on the main/parent frame before making the child/modal frame visible. Your child/modal frame should also have this code:
parentFrame.setFocusableWindowState(false);
this.mainFrame.setEnabled(false);
What I've done in this case is, in the primary jframe that I want to keep visible (for example, a menu frame), I deselect the option focusableWindowState in the property window so It will be FALSE. Once that is done, the jframes I call don´t lose focus until I close them.
As others mentioned, you could use JDialog. If you don't have access to the parent frame or you want to freeze the hole application just pass null as a parent:
final JDialog frame = new JDialog((JFrame)null, frameTitle, true);
frame.setModal(true);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
There's a bit of code that might help:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class ModalJFrame extends JFrame {
Object currentWindow = this;
public ModalJFrame()
{
super();
super.setTitle("Main JFrame");
super.setSize(500, 500);
super.setResizable(true);
super.setLocationRelativeTo(null);
JMenuBar menuBar = new JMenuBar();
super.setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
JMenu editMenu = new JMenu("Edit");
menuBar.add(fileMenu);
menuBar.add(editMenu);
JMenuItem newAction = new JMenuItem("New");
JMenuItem openAction = new JMenuItem("Open");
JMenuItem exitAction = new JMenuItem("Exit");
JMenuItem cutAction = new JMenuItem("Cut");
JMenuItem copyAction = new JMenuItem("Copy");
JMenuItem pasteAction= new JMenuItem("Paste");
fileMenu.add(newAction);
fileMenu.add(openAction);
fileMenu.addSeparator();
fileMenu.add(exitAction);
editMenu.add(cutAction);
editMenu.add(copyAction);
editMenu.addSeparator();
editMenu.add(pasteAction);
newAction.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
JFrame popupJFrame = new JFrame();
popupJFrame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
((Component) currentWindow).setEnabled(true); }
});
((Component) currentWindow).setEnabled(false);
popupJFrame.setTitle("Pop up JFrame");
popupJFrame.setSize(400, 500);
popupJFrame.setAlwaysOnTop(true);
popupJFrame.setResizable(false);
popupJFrame.setLocationRelativeTo(getRootPane());
popupJFrame.setVisible(true);
popupJFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
});
exitAction.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
System.exit(0);
}
});
}
public static void main(String[] args) {
ModalJFrame myWindow = new ModalJFrame();
myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myWindow.setVisible(true);
}
}
not sure the contetns of your JFrame, if you ask some input from users, you can use JOptionPane, this also can set JFrame as modal
JFrame frame = new JFrame();
String bigList[] = new String[30];
for (int i = 0; i < bigList.length; i++) {
bigList[i] = Integer.toString(i);
}
JOptionPane.showInputDialog(
frame,
"Select a item",
"The List",
JOptionPane.PLAIN_MESSAGE,
null,
bigList,
"none");
}
The most simple way is to use pack() method before visualizing the JFrame object. here is an example:
myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Does anyone have any example code to make a draggable menu?
I am new to Java and I am trying to find a way to make a menu that is draggable with the mouse. Like a lot of programs have. You can drag the top menu bar around the screen so that you can drop it in other locations. I think that Java can do this as well because I have seen some applications that I think were written in Java do this very same thing.
Question: How do I create a draggable menu in a JFrame in Java?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
public class MyExample extends JFrame {
public MyExample() {
initUI();
}
public final void initUI() {
JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);
JMenuItem eMenuItem = new JMenuItem("Exit");
eMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0); //exit the system
}
});
file.add(eMenuItem);
menubar.add(file);
setJMenuBar(menubar);
setTitle("My Menu");
setSize(300, 100);
setLocationRelativeTo(); //I tried draggable
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
MyExample e = new MyExample();
e.setVisible(true);
}
}
I want to be able to drag the menu from the top of the JFrame to another location out of the window and leave it there. I have used Toolbar and that worked good but I was trying to see if this can be done with a menu. If you look at any software application the usually is a grabable area right next tot he File location. This you can click and drag around the area.
ImageIcon icon = new ImageIcon(getClass().getResource("10cd.jpg"));
JMenu file1 = new JMenu("File");
file1.setMnemonic(KeyEvent.VK_F);
JMenu file2 = new JMenu("Open");
file2.setMnemonic(KeyEvent.VK_F);
JMenu file3 = new JMenu("A");
file3.setMnemonic(KeyEvent.VK_F);
JMenu file4 = new JMenu("B");
file4.setMnemonic(KeyEvent.VK_F);
JMenu file5 = new JMenu("C");
file5.setMnemonic(KeyEvent.VK_F);
JMenu file6 = new JMenu("D");
file6.setMnemonic(KeyEvent.VK_F);
JMenuItem eMenuItem1a = new JMenuItem("File 1"/*, icon*///);
/*eMenuItem1a.setMnemonic(KeyEvent.VK_E);
eMenuItem1a.setToolTipText("Exit application");
JMenuItem eMenuItem1b = new JMenuItem("File 2"/*, icon*///);
/* eMenuItem1b.setMnemonic(KeyEvent.VK_E);
eMenuItem1b.setToolTipText("Exit application");
JMenuItem eMenuItem1c = new JMenuItem("File 3"/*, icon*///);
/* eMenuItem1c.setMnemonic(KeyEvent.VK_E);
eMenuItem1c.setToolTipText("Exit application");
JMenuItem eMenuItem2 = new JMenuItem("Exit"/*, icon*///);
/* eMenuItem2.setMnemonic(KeyEvent.VK_E);
eMenuItem2.setToolTipText("Exit application");
JMenuItem eMenuItem3 = new JMenuItem("Exit"/*, icon*///);
/*eMenuItem3.setMnemonic(KeyEvent.VK_E);
eMenuItem3.setToolTipText("Exit application");
JMenuItem eMenuItem4 = new JMenuItem("Exit"/*, icon*///);
/*eMenuItem4.setMnemonic(KeyEvent.VK_E);
eMenuItem4.setToolTipText("Exit application");
eMenuItem1a.addActionListener(new myListenerOne());
eMenuItem1b.addActionListener(new myListenerTwo());
eMenuItem1c.addActionListener(new myListenerThree());
eMenuItem2.addActionListener(new myListenerOne());
eMenuItem3.addActionListener(new myListenerTwo());
eMenuItem4.addActionListener(new myListenerThree());
file1.add(eMenuItem1a);
file1.add(eMenuItem1b);
file1.add(eMenuItem1c);
file2.add(eMenuItem2);
file3.add(eMenuItem3);
file4.add(eMenuItem4);
menubar.add(file1);
menubar.add(file2);
menubar.add(file3);
menubar.add(file4);
menubar.add(file5);
menubar.add(file6);
setJMenuBar(menubar);
//Actionlisteners below
class myListenerOne implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action Class Listener 1");
System.exit(0);
}
}
class myListenerTwo implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action Class Listener 2");
System.exit(0);
}
}
class myListenerThree implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action Class Listener 3");
System.exit(0);
}
}
Here is another menu example that I forgot to include this morning. Was sick and just didn't think about it actually. Anyway, what I was wondering was if the menu could be set to a movable menu, so that when you click on it and drag it that it can be moved to any where in the frame. I have seen this done on some java applications I have used but just haven't seen it in a while.
import javax.swing.JToolBar;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.net.URL;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ToolBarDemo extends JPanel
implements ActionListener {
protected JTextArea textArea;
protected String newline = "\n";
static final private String PREVIOUS = "previous";
static final private String UP = "up";
static final private String NEXT = "next";
public ToolBarDemo() {
super(new BorderLayout());
//Create the toolbar.
JToolBar toolBar = new JToolBar("Still draggable");
addButtons(toolBar);
//Create the text area used for output. Request
//enough space for 5 rows and 30 columns.
textArea = new JTextArea(5, 30);
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(textArea);
//Lay out the main panel.
setPreferredSize(new Dimension(450, 130));
add(toolBar, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
}
protected void addButtons(JToolBar toolBar) {
JButton button = null;
//first button
button = makeNavigationButton("Back24", PREVIOUS,
"Back to previous something-or-other",
"Previous");
toolBar.add(button);
//second button
button = makeNavigationButton("Up24", UP,
"Up to something-or-other",
"Up");
toolBar.add(button);
//third button
button = makeNavigationButton("Forward24", NEXT,
"Forward to something-or-other",
"Next");
toolBar.add(button);
}
protected JButton makeNavigationButton(String imageName,
String actionCommand,
String toolTipText,
String altText) {
//Look for the image.
String imgLocation = imageName + ".gif";
URL imageURL = ToolBarDemo.class.getResource(imgLocation);
//Create and initialize the button.
JButton button = new JButton();
button.setActionCommand(actionCommand);
button.setToolTipText(toolTipText);
button.addActionListener(this);
if (imageURL != null) { //image found
button.setIcon(new ImageIcon(imageURL, altText));
} else { //no image found
button.setText(altText);
System.err.println("Resource not found: "
+ imgLocation);
}
return button;
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String description = null;
// Handle each button.
if (PREVIOUS.equals(cmd)) { //first button clicked
description = "taken you to the previous <something>.";
} else if (UP.equals(cmd)) { // second button clicked
description = "taken you up one level to <something>.";
} else if (NEXT.equals(cmd)) { // third button clicked
description = "taken you to the next <something>.";
}
displayResult("If this were a real app, it would have "
+ description);
}
protected void displayResult(String actionDescription) {
textArea.append(actionDescription + newline);
textArea.setCaretPosition(textArea.getDocument().getLength());
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Doug's Test ToolBarDemo!!!!");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add content to the window.
frame.add(new ToolBarDemo());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
}
The following code adds a JToolBar to the frame. I like this because it is draggable but it looks different than a regular menu. I was more interested in if you could set a menu to draggable.
Try using a JToolBar if you don't want to create your own floating window.
http://docs.oracle.com/javase/tutorial/uiswing/components/toolbar.html
I have created one GUI in which I have used a JFrame. How should I make it Modal?
Your best bet is to use a JDialog instead of a JFrame if you want to make the window modal. Check out details on the introduction of the Modality API in Java 6 for info. There is also a tutorial.
Here is some sample code which will display a JPanel panel in a JDialog which is modal to Frame parentFrame. Except for the constructor, this follows the same pattern as opening a JFrame.
final JDialog frame = new JDialog(parentFrame, frameTitle, true);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
Edit: updated Modality API link & added tutorial link (nod to #spork for the bump).
You can create a class that is passed a reference to the parent JFrame and holds it in a JFrame variable. Then you can lock the frame that created your new frame.
parentFrame.disable();
//Some actions
parentFrame.enable();
just replace JFrame to JDialog in class
public class MyDialog extends JFrame // delete JFrame and write JDialog
and then write setModal(true); in constructor
After that you will be able to construct your Form in netbeans
and the form becomes modal
Create a new JPanel form
Add your desired components and code to it
YourJPanelForm stuff = new YourJPanelForm();
JOptionPane.showMessageDialog(null,stuff,"Your title here bro",JOptionPane.PLAIN_MESSAGE);
Your modal dialog awaits...
As far as I know, JFrame cannot do Modal mode. Use JDialog instead and call setModalityType(Dialog.ModalityType type) to set it to be modal (or not modal).
If you're prepared to use a JDialog instead of a JFrame, you can set the ModalityType to APPLICATION_MODAL.
This provides identical behaviour to your typical JOptionPane:
import java.awt.event.ActionEvent;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class MyDialog extends JFrame {
public MyDialog() {
setBounds(300, 300, 300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(new FlowLayout());
JButton btn = new JButton("TEST");
add(btn);
btn.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e) {
showDialog();
}
});
}
private void showDialog()
{
JDialog dialog = new JDialog(this, Dialog.ModalityType.APPLICATION_MODAL);
//OR, you can do the following...
//JDialog dialog = new JDialog();
//dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
dialog.setBounds(350, 350, 200, 200);
dialog.setVisible(true);
}
public static void main(String[] args)
{
new MyDialog();
}
}
This static utility method shows a modal JFrame by secretly opening a modal JDialog, too. I used this successfully and with proper behavior on Windows 7, 8, and 10-with-multiple-desktops.
It's a nice example for the very rarely used feature of local classes.
import javax.swing.*;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
// ... (class declaration)
/**
* Shows an already existing JFrame as if it were a modal JDialog. JFrames have the upside that they can be
* maximized.
* <p>
* A hidden modal JDialog is "shown" to effect the modality.
* <p>
* When the JFrame is closed, this method's listener will pick up on that, close the modal JDialog, and remove the
* listener.
*
* made by dreamspace-president.com
*
* #param window the JFrame to be shown
* #param owner the owner window (can be null)
* #throws IllegalArgumentException if argument "window" is null
*/
public static void showModalJFrame(final JFrame window, final Frame owner) {
if (window == null) {
throw new IllegalArgumentException();
}
window.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
window.setVisible(true);
window.setAlwaysOnTop(true);
final JDialog hiddenDialogForModality = new JDialog(owner, true);
final class MyWindowCloseListener extends WindowAdapter {
#Override
public void windowClosed(final WindowEvent e) {
window.dispose();
hiddenDialogForModality.dispose();
}
}
final MyWindowCloseListener myWindowCloseListener = new MyWindowCloseListener();
window.addWindowListener(myWindowCloseListener);
final Dimension smallSize = new Dimension(80, 80);
hiddenDialogForModality.setMinimumSize(smallSize);
hiddenDialogForModality.setSize(smallSize);
hiddenDialogForModality.setMaximumSize(smallSize);
hiddenDialogForModality.setLocation(-smallSize.width * 2, -smallSize.height * 2);
hiddenDialogForModality.setVisible(true);
window.removeWindowListener(myWindowCloseListener);
}
The only code that have worked for me:
childFrame.setAlwaysOnTop(true);
This code should be called on the main/parent frame before making the child/modal frame visible. Your child/modal frame should also have this code:
parentFrame.setFocusableWindowState(false);
this.mainFrame.setEnabled(false);
What I've done in this case is, in the primary jframe that I want to keep visible (for example, a menu frame), I deselect the option focusableWindowState in the property window so It will be FALSE. Once that is done, the jframes I call don´t lose focus until I close them.
As others mentioned, you could use JDialog. If you don't have access to the parent frame or you want to freeze the hole application just pass null as a parent:
final JDialog frame = new JDialog((JFrame)null, frameTitle, true);
frame.setModal(true);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
There's a bit of code that might help:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class ModalJFrame extends JFrame {
Object currentWindow = this;
public ModalJFrame()
{
super();
super.setTitle("Main JFrame");
super.setSize(500, 500);
super.setResizable(true);
super.setLocationRelativeTo(null);
JMenuBar menuBar = new JMenuBar();
super.setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
JMenu editMenu = new JMenu("Edit");
menuBar.add(fileMenu);
menuBar.add(editMenu);
JMenuItem newAction = new JMenuItem("New");
JMenuItem openAction = new JMenuItem("Open");
JMenuItem exitAction = new JMenuItem("Exit");
JMenuItem cutAction = new JMenuItem("Cut");
JMenuItem copyAction = new JMenuItem("Copy");
JMenuItem pasteAction= new JMenuItem("Paste");
fileMenu.add(newAction);
fileMenu.add(openAction);
fileMenu.addSeparator();
fileMenu.add(exitAction);
editMenu.add(cutAction);
editMenu.add(copyAction);
editMenu.addSeparator();
editMenu.add(pasteAction);
newAction.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
JFrame popupJFrame = new JFrame();
popupJFrame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
((Component) currentWindow).setEnabled(true); }
});
((Component) currentWindow).setEnabled(false);
popupJFrame.setTitle("Pop up JFrame");
popupJFrame.setSize(400, 500);
popupJFrame.setAlwaysOnTop(true);
popupJFrame.setResizable(false);
popupJFrame.setLocationRelativeTo(getRootPane());
popupJFrame.setVisible(true);
popupJFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
});
exitAction.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
System.exit(0);
}
});
}
public static void main(String[] args) {
ModalJFrame myWindow = new ModalJFrame();
myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myWindow.setVisible(true);
}
}
not sure the contetns of your JFrame, if you ask some input from users, you can use JOptionPane, this also can set JFrame as modal
JFrame frame = new JFrame();
String bigList[] = new String[30];
for (int i = 0; i < bigList.length; i++) {
bigList[i] = Integer.toString(i);
}
JOptionPane.showInputDialog(
frame,
"Select a item",
"The List",
JOptionPane.PLAIN_MESSAGE,
null,
bigList,
"none");
}
The most simple way is to use pack() method before visualizing the JFrame object. here is an example:
myFrame frm = new myFrame();
frm.pack();
frm.setVisible(true);