public class Manubar extends JFrame {
JMenuBar jmb;
JMenu jm;
JMenu jm2;
JMenuItem jmt;
JMenuItem jmt2;
public Manubar() {
setSize(500, 500);
jmb = new JMenuBar();
jm = new JMenu("file");
jm2 = new JMenu("edit");
jmt = new JMenuItem("copy");
jmt2 = new JMenuItem("exit");
jmb.add(jm);
jmb.add(jm2);
jm.add(jmt);
jm.add(jmt2);
add(jmb, BorderLayout.NORTH);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Manubar();
}
}
Here I want to close the window when I click on exit menu item,
also before closing, it should display a popup to ask whether to close if user clicks OK then it should close.
Here I want to close the window when I click on exit menu item, also before closing, it should display a popup to ask whether to close if user clicks OK then it should close.
Check out Closing an Application. It shows you how to display a JOptionPane to confirm closing of the application first.
It shows:
the basic approach of using a WindowListener
a simplified approach by using the included custom classes
Here is your complete solution,
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Manubar extends JFrame implements ActionListener {
JMenuBar jmb;
JMenu jm;
JMenu jm2;
JMenuItem jmt;
JMenuItem jmt2;
public Manubar() {
setSize(500, 500);
jmb = new JMenuBar();
jm = new JMenu("file");
jm2 = new JMenu("edit");
jmt = new JMenuItem("copy");
jmt2 = new JMenuItem("exit");
jmb.add(jm);
jmb.add(jm2);
jm.add(jmt);
jm.add(jmt2);
add(jmb, BorderLayout.NORTH);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jmt2.addActionListener(this);
}
public static void main(String[] args) {
new Manubar();
}
#Override
public void actionPerformed(ActionEvent e) {
if("exit".equals(e.getActionCommand())){
int dialogButton = JOptionPane.YES_NO_OPTION;
JOptionPane.showConfirmDialog (null, "Would You Like to Save your Previous Note First?","Warning",dialogButton);
if(dialogButton == JOptionPane.YES_OPTION){
System.exit(NORMAL);
}
}
}
}
Related
I'm trying to exit menu using the ActionListener, however my code doesn't work properly and the "Quit the Program" button doesn't do anything. Below is the code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.ButtonGroup;
import javax.swing.JMenuBar;
import javax.swing.KeyStroke;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JFrame;
public class testCoinSorterGUI extends testCoinSorter{
JTextArea output;
JScrollPane scrollPane;
public JMenuBar createMenuBar() {
JMenuBar menuBar;
JMenu menu, submenu;
JMenuItem menuItem;
JRadioButtonMenuItem rbMenuItem;
JCheckBoxMenuItem cbMenuItem;
//Create the menu bar.
menuBar = new JMenuBar();
//Build the first menu.
menu = new JMenu("Calculator");
menu.setMnemonic(KeyEvent.VK_A);
menu.getAccessibleContext().setAccessibleDescription(
"The only menu in this program that has menu items");
menuBar.add(menu);
menuItem = new JMenuItem("Coin calculator");
menu.add(menuItem);
menuItem = new JMenuItem("Multi Coin calculator");
menu.add(menuItem);
//Build second menu in the menu bar.
menu = new JMenu("Print coin list");
menu.setMnemonic(KeyEvent.VK_N);
menu.getAccessibleContext().setAccessibleDescription("This menu does nothing");
menuBar.add(menu);
//Build third menu in the menu bar.
menu = new JMenu("Set details");
menuBar.add(menu);
menuItem = new JMenuItem("Set currency");
menu.add(menuItem);
menuItem = new JMenuItem("Set minimum coin input value");
menu.add(menuItem);
menuItem = new JMenuItem("Set maximum coin input value");
menu.add(menuItem);
menu.addSeparator();
menuItem = new JMenuItem("Display program configurations");
menu.add(menuItem);
//Build fifth menu in the menu bar.
menu = new JMenu("Quit the program");
menuBar.add(menu);
menu.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
);
return menuBar;
}
public Container createContentPane() {
//Create the content-pane-to-be.
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setOpaque(true);
//Create a scrolled text area.
output = new JTextArea(5, 30);
output.setEditable(false);
scrollPane = new JScrollPane(output);
//Add the text area to the content pane.
contentPane.add(scrollPane, BorderLayout.CENTER);
return contentPane;
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = testCoinSorterGUI.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("*** CoinSorterGUI ***");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
testCoinSorterGUI demo = new testCoinSorterGUI();
frame.setJMenuBar(demo.createMenuBar());
frame.setContentPane(demo.createContentPane());
//Display the window.
frame.setSize(680, 480);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Currently I only want to test the "quit the program" button, so please ignore all the other menu.
Any help would be appreciated, I am really stucked though I think I have put the code in the correct order.
First of all:
public class testCoinSorterGUI extends testCoinSorter{
Class names should start with an upper case character. Follow the conventions used by the JDK.
I'm trying to exit menu using the ActionListener
A JMenuBar is designed to display JMenu objects.
A JMenu is designed to be clicked and display a list of JMenuItems.
An ActionListener only works on a JMenuItem.
So the logical structure of your code should be:
JMenuBar
JMenu
JMenuItem
When you add the JMenuItem you can add an "accelerator" to the menu item so the application by be closed directly from the keyboard. This save the user from using the mouse all the time and having to click on the menu and menu item.
Use a menuitem, not a menu
menu = new JMenu("Quit the program");
menuBar.add(menu);
menu.addActionListener(
Should be
JMenuItem menuI = new JMenuItem("Quit the program");
menuBar.add(menuI);
menuI.addActionListener(
I'm trying to make a help button on a JMenuBar. Currently I can make it align to right using this
helpItem.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
The issue is that it takes up the entire space of the JMenuBar so you can basically press anywhere on the empty space of the JMenuBar and it will press that button. I fixed that by overriding the size of the JMenuItem using this
JMenuItem helpItem = new JMenuItem() {
#Override
public Dimension getMaximumSize() {
Dimension d1 = super.getPreferredSize();
Dimension d2 = super.getMaximumSize();
d2.width = d1.width;
return d2;
}
};
However, after I override getMaximumSize, setComponentOrientation doesn't align the JMenuItem to the right.
EDIT (Current code):
private void createMenuBar() {
JMenuBar newMenuBar = new JMenuBar();
newMenuBar.setName("");
JMenu newMenu = new JMenu("Menu");
JMenuItem updateItem = new JMenuItem("Update");
JMenuItem aboutMe = new JMenuItem("About");
JMenuItem exitItem = new JMenuItem("Exit");
JMenuItem helpItem = new JMenuItem();
URL iconPath = getClass().getResource("/help.png");
helpItem.setIcon(new ImageIcon(iconPath));
addMenuItemActionListeners(updateItem, aboutMe, exitItem, helpItem);
newMenu.add(updateItem);
newMenu.add(aboutMe);
newMenu.add(exitItem);
newMenuBar.add(newMenu);
newMenuBar.add(Box.createHorizontalGlue());
newMenuBar.add(helpItem);
this.setJMenuBar(newMenuBar);
}
There is no need to manually set the component size, avoid it because it's a bad practice and could break your layout.
If you just want to align the help menu on the right, you can make use of Box.createHorizontalGlue method.
Yuo can add all the other menus you're gonna use (of course, if you need), then add the glue, and then add all the other menus you want to have aligned to the right side.
This is an example:
And this is a MCVE to achieve the above result:
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.SwingUtilities;
public class GlueMenuBarTest
{
public static void main (String [] a) {
SwingUtilities.invokeLater (new Runnable () {
#Override public void run () {
createAndShowGUI ();
}
});
}
private static void createAndShowGUI () {
JFrame frame = new JFrame ("Test");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar (createGlueMenuBar ());
frame.setSize (500, 250); // just for convenience, use pack () in a real app.
frame.setLocationRelativeTo (null);
frame.setVisible (true);
}
private static JMenuBar createGlueMenuBar () {
JMenuBar menuBar = new JMenuBar ();
menuBar.add (new JMenu ("File"));
menuBar.add (new JMenu ("Edit"));
menuBar.add (new JMenu ("Search"));
menuBar.add (Box.createHorizontalGlue ());
menuBar.add (new JMenu ("Help"));
return menuBar;
}
}
If you comment the lines where i add other menus on the left, it will work as well.
I have an older stand alone java swing-based app that uses JFrame with JMenuBar containing multiple Jmenu elements (with respective JMenuItem items).
After upgrading to the latest 1.6.0_41 (or 1.7.x) JVM on Windows (7 and vista) I've noticed that the menu item with the shortcut Ctrl-C (or Ctrl-Insert) doesn't receive its ActionEvent anymore if JTable is added to the frame. The menu ActionListener is invoked if the menu is accessed by the mouse click however. The shortcut works if JTable is removed. If I change the shortcut combination to something other than Ctrl-C or Ctrl-Insert (i.e. Ctrl-L) the ActionListener is invoked.
The way it used to work (I've just confirmed it with jvm 1.4, on Windows Vista - I know it's been awhile since that environment got any serious attention :) is that Ctrl-C will perform the standard copy to clipboard function inside of the JTable if the focus was inside of an editable field. Otherwise my menu ActionListener was invoked via shortcut assigned through setAccelerator() method.
It looks like JTable implementation changed in 1.6.* to process Ctrl-C bound event differently on Windows.
Running this app on Mac OS (JVM 1.6.0_43) I can see ActionListener is invoked via Ctrl-C shortcut. Although it might be because the JTable uses Command-C instead of Ctrl-C to copy to the clipboard under Mac OS.
I've extracted the relevant portion of the code that demonstrates the problem. Any suggestions are greatly appreciated.
public class TestFrame extends JFrame {
public TestFrame(String title) {
super(title);
}
private void init() {
getContentPane().setLayout(new BorderLayout());
addMenu();
addTable();
// Change default exit operation
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private void addTable() {
JTable jTable = new JTable(createTableModel());
// Place table in JScrollPane
JScrollPane scrollPane = new JScrollPane(jTable);
// Add Table
add(scrollPane, BorderLayout.CENTER);
}
private TableModel createTableModel() {
Object[][] data = new Object[][]{
{new Date(), "First Row, 2nd column", "First Row, 3rd column"},
{new Date(), "Second Row, 2nd column", "Second Row, 3rd column"},
};
Object[] columnNames = new Object[]{"Date", "Type", "Description"};
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
public boolean isCellEditable(int row, int column) {
return column != 0;
}
};
return model;
}
private void addMenu() {
// Create the menu bar.
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu editMenu = new JMenu("Edit");
menuBar.add(editMenu);
TestActionListener listener = new TestActionListener();
JMenuItem menuItem = null;
menuItem = new JMenuItem("Copy 1");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, ActionEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);
menuItem = new JMenuItem("Copy 2");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);
menuItem = new JMenuItem("Copy 3");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);
}
public static void main(String[] args) {
TestFrame frame = new TestFrame("Test");
frame.init();
}
private static class TestActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("TestFrame.TestActionListener.actionPerformed(): e="+ e);
}
}
}
The problem is that your frame is not focused and there are no elements in your whole component hierarchy which has the focus, meaning that no one will "grab" the event and try to do something with it. Since JMenuItem's bind their shortcut to the input map JComponent.WHEN_IN_FOCUSED_WINDOW, your shortcut never "answers" the event.
To fix this, either put the focus on one of the component or directly on the JFrame (for example with frame.requestFocusInWindow();). Small example here:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class TestFrame extends JFrame {
public TestFrame(String title) {
super(title);
}
private void init() {
getContentPane().setLayout(new BorderLayout());
addMenu();
addTable();
// Change default exit operation
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private void addTable() {
JTable jTable = new JTable();
// Place table in JScrollPane
JScrollPane scrollPane = new JScrollPane(jTable);
// Add Table
add(scrollPane, BorderLayout.CENTER);
}
private void addMenu() {
// Create the menu bar.
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu editMenu = new JMenu("Edit");
menuBar.add(editMenu);
TestActionListener listener = new TestActionListener();
JMenuItem menuItem = null;
menuItem = new JMenuItem("Copy 1");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, KeyEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);
menuItem = new JMenuItem("Copy 2");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);
menuItem = new JMenuItem("Copy 3");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_MASK));
menuItem.addActionListener(listener);
editMenu.add(menuItem);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TestFrame frame = new TestFrame("Test");
frame.init();
frame.requestFocusInWindow();
}
});
}
private static class TestActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("TestFrame.TestActionListener.actionPerformed(): e=" + e);
}
}
}
Additional remarks:
Don't extend JFrame if not needed
Start your UI from the Event Dispatching Thread (EDT) by using SwingUtilities.invokeLater()
If you question is how to remove the Control+C binding from the table then you can do:
KeyStroke copy = KeyStroke.getKeyStroke("control C");
InputMap im = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
im.getParent().remove(copy);
However, this will remove the binding from all tables.
Any idea why the menu bar menuBar is not showing? everything looks fine to me.
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class mySticky extends JFrame implements ActionListener{
//weStart!
JFrame frame = new JFrame("Sticky Note");
JMenuBar menuBar = new JMenuBar();
JMenu noteMenu = new JMenu("Note");
JMenuItem newNote = new JMenuItem("New Note");
JMenuItem open = new JMenuItem("Open");
JMenuItem saveAs = new JMenuItem("Save As");
JMenuItem save = new JMenuItem("Save");
//Constructor
public mySticky(){
setSize(400,300);
setLocation(500,250);
setTitle("Sticky Note");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
menuBar.add(noteMenu);
noteMenu.add(newNote);
noteMenu.add(open);
noteMenu.add(saveAs);
noteMenu.add(save);
frame.setJMenuBar(menuBar);
}
public void actionPerformed (ActionEvent e){
}
public static void main (String [] args ){
mySticky sticky = new mySticky ();
sticky.setVisible(true);
}
}
You add the menubar to frame, which is never added to any UI. Replace
frame.setJMenuBar(menuBar);
by
setJMenuBar(menuBar);
and your menubar will become visible. Or you should add frame to the UI as well. Not sure what you tried to achieve.
And you should wrap the code of your main method in a Runnable and execute it on the EDT (for example using EventQueue.invokeLater)
Instead of frame.setJMenuBar(menuBar), try this.setJMenuBar(menuBar) in your constructor.
its a maybe a dumb question but i am curious to understand this thing....
The below code works but the one below that doesn't work.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Menu extends JFrame
{
public Menu()
{
JMenuBar menubar = new JMenuBar();
ImageIcon icon = new ImageIcon("exit.png");
JMenu file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);
JMenuItem fileClose = new JMenuItem("Close",icon);
fileClose.setMnemonic(KeyEvent.VK_C);
fileClose.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event)
{System.exit(0);}
});
file.add(fileClose);
menubar.add(file);
setJMenuBar(menubar);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300,200);
setLocationRelativeTo(null);
}
public static void main (String args[])
{
new Menu();
}
}
The below one doesn't work
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Menu extends JFrame
{
public Menu()
{
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300,200);
setLocationRelativeTo(null);
JMenuBar menubar = new JMenuBar();
ImageIcon icon = new ImageIcon("exit.png");
JMenu file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);
JMenuItem fileClose = new JMenuItem("Close",icon);
fileClose.setMnemonic(KeyEvent.VK_C);
fileClose.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event)
{System.exit(0);}
});
file.add(fileClose);
menubar.add(file);
setJMenuBar(menubar);
}
public static void main (String args[])
{
new Menu();
}
}
I thought Java supports free style coding !!! (that's what it says in my Book)
PS: Please Someone Edit the Tile to suit the question correctly, I am not sure what to put in Title.
The issue in your 2nd code sample is that you are calling setVisible before you actually add stuff to the GUI. Your saying "Here's some stuff, now show" while in the second one your saying "Show, now here's some stuff"
Fix: Move setVisible to the end of the constructor