JPopupMenu and JMenuItem general usage - java

I have a simple question; I am trying to add a menu to my program. This is what I have thus far:
public static void main(String args[]){
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {}
JFrame cipherGUIFrame = new CipherGUIFrame();
cipherGUIFrame.setVisible(true);
JMenuBar bar = new JMenuBar();;
JMenu file = new JMenu("File");
JMenu edit = new JMenu("Edit");
JMenuItem open = new JMenuItem("Open");
JMenuItem save = new JMenuItem("Save");
JMenuItem cut = new JMenuItem("Cut");
JMenuItem copy = new JMenuItem("Copy");
JMenuItem paste = new JMenuItem("Paste");
JSeparator sep = new JSeparator();
JMenuItem find = new JMenuItem("Find");
JPopupMenu options = new JPopupMenu("Options");
options.setVisible(true);
file.add(open);
file.add(save);
edit.add(cut);
edit.add(copy);
edit.add(paste);
edit.add(sep);
edit.add(find);
edit.add(options);
bar.add(file);
bar.add(edit);
cipherGUIFrame.setJMenuBar(bar);
}
I am trying to achieve an effect similar to this diagram: http://i.imgur.com/GYi0S9R.jpg .
Is "Options" not the JPopupMenu? It doesn't seem to show up! Or is it simply a JMenuItem and JPopupMenu is the new box that comes up when you hover over it?

A sub menu is just that, a menu which is contained within another menu
Try using something like...
JMenu options = new JMenu("Options");
options.add(new JRadioButtonMenuItem("Forward"));
options.add(new JRadioButtonMenuItem("Backward"));
options.addSeparator();
options.add(new JCheckBoxMenuItem("Case Sensetive"));
Take a closer look at How to Use Menus for more details

Related

Expand JMenu to left, while retaining default text alignment

I have a JMenu A within a JMenuBar aligned to the right of the screen. Within this menu are several JMenuItems, along with another JMenu B. Since menu A is right aligned, I need menu B to open to the left. In order to do this I found the code
setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);.
The issue however, is that this messes with the text alignment of menu 2, which I would like to stay exactly like the other menu items.
I have also tried manually aligning menu 2 using SwngConstants.leftAlign, however this is too severe:
How can I make the menu expand to the left, while retaining the default text alignment? Thanks in advance! The code I used to produce the above images is seen below:
import java.awt.*;
import javax.swing.*;
public class Test{
public Test(){
JFrame frame = new JFrame();
JMenuBar menuBar = new JMenuBar();
JMenu menu1 = new JMenu("Menu 1");
JMenu menu2 = new JMenu("Menu 2");
JMenuItem menuitem1 = new JMenuItem("Menu Item 1");
JMenuItem menuitem2 = new JMenuItem("Menu Item 2");
JMenuItem menuitem3 = new JMenuItem("Menu Item 3");
JMenuItem menuitem4 = new JMenuItem("Menu Item 4");
menuBar.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
menu1.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
menu2.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
menu2.setHorizontalAlignment(SwingConstants.LEFT);
menuBar.add(menu1);
menu1.add(menuitem1);
menu1.add(menuitem2);
menu1.add(menu2);
menu2.add(menuitem3);
menu2.add(menuitem4);
frame.setJMenuBar(menuBar);
frame.getContentPane().setBackground(Color.WHITE);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(270,170));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
try{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
UIManager.getLookAndFeelDefaults().put("Label.font", new Font("Arial", Font.PLAIN, 12));
UIManager.getLookAndFeelDefaults().put("Button.font", new Font("Arial", Font.PLAIN, 12));
UIManager.getLookAndFeelDefaults().put("ComboBox.font", new Font("Arial", Font.PLAIN, 12));
UIManager.getLookAndFeelDefaults().put("JTextField.font", new Font("Arial", Font.PLAIN, 12));
new Test();
} catch(Exception e){
JOptionPane.showConfirmDialog(null, e.getMessage());
}
}
}
UPDATE: If I remove the lines of code aligning the menus right to left and move the frame to the edge of the display screen, then the menus act as desired (i.e. the menu will not expand off the monitor). Perhaps there is a way to tell the menu not to expand off the JFrame rather than the monitor?
UPDATE: Thank you #StanislavL for the idea. Overriding menu 2 with the following code does the trick, it also gets rid of that unsightly overlap between the two menus. Note that menu 2 no longer needs ComponentOrientation.RIGHT_TO_LEFT.
JMenu menu2 = new JMenu("Menu 2"){
protected Point getPopupMenuOrigin(){
return new Point(-this.getPopupMenu().getPreferredSize().width, 0);
}
};
You can try to override
public ComponentOrientation getComponentOrientation()
method of JMenu to return your alignmnet
or JMenu has method you can override
protected Point getPopupMenuOrigin()

How to remove arrow on JMenuItem?

I need help with JMenuItem. I didn't write any line about arrow on JMenuItem. So how to disable that? Here's the image:
Let me try to reproduce the issue.
Add JMenuItem in JMenu and then in JMenuBar.
sample code: (No issues)
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("A Menu");
JMenu submenu = new JMenu("A submenu");
JMenuItem menuItem = new JMenuItem("Another item");
submenu.add(menuItem); //comment this line and look the output
menu.add(submenu);
menuBar.add(menu);
Add JMenu directly in JMenuBar without any JMenuItem.
sample code: (This creates problem)
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("A Menu");
JMenu submenu = new JMenu("A submenu");
menu.add(submenu);
menuBar.add(menu);
Add JMenuItem directly in JMenuBar.
sample code: (No issues)
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("A Menu");
JMenuItem menuItem = new JMenuItem("Another item");
menu.add(menuItem);
menuBar.add(menu);
Now the problem is crystal clear, if it's leaf node then add JMenuItem instead of JMenu in JMenuBar.
Read more...
I had the same issue with JavaFX with my MenuItems having arrows all over the place.
Thanks to #Braj response I realized that I was creating my items this way:
MenuItem saveMenu = new Menu();
instead of
MenuItem saveMenu = new MenuItem();
This, of course, works in Java thanks to polymorphism but created this side effect in my app. That being said, this can help you better organize your menus using a tree structure like Save > Save to File / Save to DB / Save As...

JMenuPopup not accurte?

Image of the problem:
http://gyazo.com/56c4f7f5fc10805695fc80de567b92c5.png
private JButton settingsButton = new JButton("Settings");
private JPopupMenu settings = new JPopupMenu();
private JMenuItem accounts = new JMenuItem("Accounts");
settings.add(accounts);
settingsButton.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
settings.show(e.getComponent(), 0, 0);
}
});
So as you have seen on the image, I don't think this is any accurate. Is there any (better) method to get it on a the right spot?
I have clicked on the JButton: "Settings" and it should popup just a tad down it.
You are better off using a JMenuBar and then adding JMenus with JMenuItems, there is no point on reinventing the wheel:
JMenuBar menubar = new JMenuBar();
JMenu settings = new JMenu("Settings");
JMenuItem accounts = new JMenuItem("Accounts");
settings.add(accounts);
menubar.add(settings);
myFrame.setJMenuBar(menubar);

a GUI java program needing an action event button

I am making a simple java program that represents a Microsoft Word menu bar, and in the file menu I add an exit button... it does nothing.
I need your help to tell me what to do to make the exit button actually exit and close the program.
Here is my code:
public class MicrosoftWordMenu {
public static void main(String [] args)
{
JPanel panel = new JPanel();
JFrame frame = new JFrame("Microsoft Word");
JMenuBar bar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenu menu1 = new JMenu("Edit");
JMenu menu2 = new JMenu("View");
JMenu menu3 = new JMenu("Insert");
JMenu menu4 = new JMenu("Format");
JMenu menu5 = new JMenu("Tools");
JMenu menu6 = new JMenu("Table");
JMenu menu7 = new JMenu("Window");
JMenu menu8 = new JMenu("Help");
frame.add(bar, BorderLayout.NORTH);
frame.add(panel);
bar.add(menu);
bar.add(menu1);
bar.add(menu2);
bar.add(menu3);
bar.add(menu4);
bar.add(menu5);
bar.add(menu6);
bar.add(menu7);
bar.add(menu8);
JMenuItem menuitem = new JMenuItem("New...");
JMenuItem menuitem1 = new JMenuItem("Open...");
JMenuItem menuitem2 = new JMenuItem("Close");
JMenuItem menuitem3 = new JMenuItem("Save");
JMenuItem menuitem4 = new JMenuItem("Save as...");
JMenuItem menuitem5 = new JMenuItem("Save as web page...");
JMenuItem menuitem6 = new JMenuItem("Web page preview ");
JMenuItem menuitem7 = new JMenuItem("Print ");
JMenuItem menuitem8 = new JMenuItem("Exit");
menu.add(menuitem);
menu.add(menuitem1);
menu.add(menuitem2);
menu.add(menuitem3);
menu.add(menuitem4);
menu.add(menuitem5);
menu.add(menuitem6);
menu.add(menuitem7);
menu.add(menuitem8);
frame.setSize(600,100);
frame.setVisible(true);
}
}
Also consider using Action to let components share functionality, as shown here.
Calling System.exit(0) on menu selection would do just fine.
At the moment you're just creating the GUI element, but they're basically empty shells. In particular, you've created items that appear on the menu, but you haven't added any behaviour to those items. (Since you haven't told your program anywhere what to do when an item is clicked, what did you think would happen)?
In order to provide this behaviour, you'll need to register an ActionListener, which will be called when something happens on an element, and will let you take an appropriate action at that point (such as calling System.exit(0). See the tutorial on Writing [Swing] Event listeners for details.
I always extend the AbstractAction class (which implements the ActionListener interface) which allows you to reuse your actions. By extending the AbstractAction, the actionPerformed(ActionEvent e) method will be invoked very time your button is clicked.
public class CloseAction extends AbstractAction {
public CloseAction() {
super("Close");
}
public actionPerformed(ActionEvent e) {
System.exit(1);
}
}
Now, to apply the above action to one of your buttons, you simply need to follow the below piece of code.
CloseButton.setAction(new CloseAction());
The close button will now shut down your application each time it gets pressed.
Use the ExitAction defined in Closing an Application. Then clicking on the Exit menu item will be just like clicking on the Close icon at the top right of the window. This allows for consistency when closing an application in case you ever need to do close processing.
Edit:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
...
// JMenuItem menuitem8 = new JMenuItem("Exit");
JMenuItem menuitem8 = new JMenuItem( new ExitAction() );

I have an instance of JMenuItem (let's say, TEMP). I want to find out, what is the name of JMenu to which a TEMP is added. How?

I have an instance of JMenuItem (let's say, TEMP). I want to find out, what is the name of JMenu to which a TEMP is added. How should I do it?
You can try the following code to get JMenu of given JMenuItem
JPopupMenu fromParent = (JPopupMenu)menuitem.getParent();
JMenu foo = (JMenu)fromParent.getInvoker();
System.out.println(foo.getName());
You may get the JMenu's name from JMenuItem using this approach:
JPopupMenu popup = new JPopupMenu();
popup.setName("popup");
JMenu jMenu= new JMenu("menu");
jMenu.setName("menu");
JMenuItem menuItem1 = new JMenuItem("sub1");
jMenu.add(menuItem1);
menuItem1.addActionListener(this);
popup.add(jMenu);
....
#Override
public void actionPerformed(ActionEvent e) {
JMenuItem source = (JMenuItem)(e.getSource());
try{
JMenuItem menuItem = (JMenuItem) e.getSource();
JPopupMenu popupMenu = (JPopupMenu) menuItem.getParent();
Component invoker = popupMenu.getInvoker();
// Print name of JMenu
System.out.println("NAME OF JMENU: "+invoker.getName());
JPopupMenu popup = (JPopupMenu) invoker.getParent();
// Print name of JPopupMenu
System.out.println("NAME OF POPMENU: "+popup.getName());
}catch(Exception ex){
ex.printStackTrace();
}
}

Categories