Eclipse not displaying JMenu items after adding to and setting JMenuBar visible? - java

Not getting any errors however the program only displays the word "menu" at the top in the program. It doesn't display the 3 JMenu items: "home", "about" and "explore".
JPanel p5 = new JPanel(new GridBagLayout());
p5.setVisible(true);
fw.add(p5, BorderLayout.PAGE_START);
JMenu menu = new JMenu("Menu");
menu.setVisible(true);
menu.add("home");
menu.add("about");
menu.add("explore");
JMenuBar menubar = new JMenuBar();
fw.setJMenuBar(menubar); //ADDED THIS LINE. STILL DOESN'T WORK.
menubar.setVisible(true);
menubar.add(menu);
p5.add(menu);
I've added JMenu to JMenuBar (everything JMenu, JMenubar and JPanel is set to visible). Also I added JPanel (p5) to "first window (fw) and added menu to p5. I'm not sure why my menu items are not being displayed.
UPDATE: MCVE (Minimal Complete and Verifiable Example) as requested.
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
public class TestingClass extends JFrame {
public static void main(String[] args) {
FirstWindow fw = new FirstWindow();
fw.setSize(400, 600);
fw.setDefaultCloseOperation(EXIT_ON_CLOSE);
fw.setVisible(true);
JPanel p5 = new JPanel(new GridBagLayout());
p5.setVisible(true);
fw.add(p5);
JMenu menu = new JMenu("Menu");
menu.setVisible(true);
menu.add("home");
menu.add("about");
menu.add("explore");
JMenuBar menubar = new JMenuBar();
fw.setJMenuBar(menubar); // THE UPDATED LINE OF CODE.
menubar.setVisible(true);
menubar.add(menu);
p5.add(menu);
}
}
As you run the program, you will see the words "menu" displayed. The items: "home, about and explore" from JMenu are not displayed. Does anybody know what I'm doing wrong?

An MCVE of a run-time problem should compile cleanly. That shows 3 compilation errors. One is a missing import (easily fixable), but the other two relate to the missing FirstWindow.
Nevertheless, once a few tweaks were made, the problem becomes clear. A component can only appear in one place. By adding it to the panel as well (commented out below), it cannot appear in the menu.
import java.awt.*;
import javax.swing.*;
public class TestingClass extends JFrame {
public static void main(String[] args) {
JFrame fw = new JFrame();
fw.setSize(400, 200); // for screenshot
fw.setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel p5 = new JPanel(new GridBagLayout());
p5.setVisible(true);
fw.add(p5);
JMenu menu = new JMenu("Menu");
//menu.setVisible(true);
menu.add("home");
menu.add("about");
menu.add("explore");
JMenuBar menubar = new JMenuBar();
fw.setJMenuBar(menubar); // THE UPDATED LINE OF CODE.
//menubar.setVisible(true);
menubar.add(menu);
//p5.add(menu); // WTF?
fw.setVisible(true); //should be done after all components are added
}
}

You need to add the menuBar to the frame:
frame.setJMenuBar( menuBar );
Also, you don't need do make Swing components visible since they are visible by default (except for top level contains, like JFrame which you do need to set visible).

You need to call setVisible() after adding component! So first add all components. Add the highest level component to the JFrame(JPanel in your case) and the only call setVisible() for the JFrame. No need to call on every component.
JMenu menu = new JMenu("Menu");
menu.add("home");
menu.add("about");
menu.add("explore");
//rest of the components
//add panelto the frame
frame.getContentPane.add(p5);
//set menubar for the frame
frame.setJMenuBar( menuBar );
//set visibility for frame to true
frame.setVisible(true);

Related

Learning Java GUIs -

I'm learning GUI programming in java, and trying to modify an existing programme to add a new menu bar at the top of the frame.
The main method is below. The MainPanel class extends JPanel and contains the main components of the programme (a basic game).
public static void main(String[] args) {
JFrame frame = new JFrame("Sokuban");
MainPanel panel = new MainPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
}
I'm not sure if I should add a new JPanel, add it to the JFrame, and then within that add buttons? Or create a JMenuBar, within the existing panel, or frame, and then use BorderLayout.NORTH to arrange it?
Just playing around with things I found on google, I've tried the following snippets separately (haven't put all code in):
JMenuBar menuBar = new JMenuBar();
frame.add(new Button("Button"), BorderLayout.SOUTH);
panel.BorderLayout.SOUTH;
JPanel frame2 = new JPanel();
window.add(frame2, BorderLayout.NORTH);
JButton b1 = new JButton();
frame2.setSize(500,500);
b1.setSize(400,400);
b1.setVisible(true);
b1.setText("Button");
frame2.add(b1);
frame2.setVisible(true);
I can't figure out which direction I should be going in. Any pointers v much appreciated!
First : https://docs.oracle.com/javase/tutorial/uiswing/components/menu.html :)
This is quite easy tutorial of JMenuBar. :)
And if you one want to only a button on JBarMenu :
How to make a JMenu have Button behaviour in a JMenuBar
I'm not sure if I should add a new JPanel, add it to the JFrame, and then within that add buttons? Or create a JMenuBar, within the existing panel, or frame, and then use BorderLayout.NORTH to arrange it?
Here are some personal experience that I can share with you:
I will usually plan the appearance of my user interface first (Either on paper on in my mind). After that, decide a suitable layout manager for the container.
I can have nested panels with more than 1 layout if the UI is complicated.
But ultimately, I will usually have a main panel which hold every other components (subpanels / buttons / textFields..).
Add the main panel into the JFrame. (You can have a customized JPanel, and we rarely need a customized JFrame).
As for the menu bar:
Add JMenuItem to JMenu
Add JMenu to JMenuBar
Add JMenuBar to the Frame using frame.setJMenuBar(menuBar);
The following image should help you in understanding of the hierarchy:
Don't do that, check this out it's what you're looking for
This link is for a JMenuBar
https://docs.oracle.com/javase/7/docs/api/java/awt/MenuBar.html
This link is for a JMenu https://docs.oracle.com/javase/7/docs/api/javax/swing/JMenu.html
This link is for a JMenuItem
https://docs.oracle.com/javase/7/docs/api/javax/swing/JMenuItem.html
You don't need a new JFrame to create a menu, you can use the JMenuBar();
JMenuBar myMenu = new JMenuBar();
//The above snippet does not create or add menus it's simply the container that holds them
JMenu fileMenu = new JMenu("File"); // This will create a menu named file
JMenuItem openChoice = new JMenuItem("Open"); /* This will create an option under
the fileMenu named open*/
//To Actually add these things you would do this
setJMenuBar(myMenu);
myMenu.add(fileMenu); // This adds fileMenu to the menubar
fileMenu.add(openChoice); // This adds openChocie to the JMenu named fileOption
Now the above code was a very basic example as to how to setup a menu I would sugesst following the code I outlined here and as you learn to improve upon this as this is just a starting point for you!

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()

java JMenuBar not visible? Why?

I cannot figure out why my menu bar isn't visible. I have following code:
//Main
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Menu extends JFrame{
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(500,350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
menuBar mbObj = new menuBar();
mbObj.menuBar(frame);
}
}
//Menu Bar class
public class menuBar{
private JMenu file,edit;
private JMenuItem nFile ,oFile,sFile,saFile,exit;
private JMenuItem undo,copy,paste;
private JMenuBar bar;
public void menuBar(JFrame frame){
bar = new JMenuBar();
frame.setJMenuBar(bar);
bar.setVisible(true);
file = new JMenu("File");
edit = new JMenu("Edit");
bar.add(file);
bar.add(edit);
}
}
Call setVisible(true) on the top-level window, here a JFrame, only after adding all components, including the JMenuBar. You will also want to avoid calling setSize(...) on anything, and instead use layout managers and call pack() on the JFrame after adding all components and before calling setVisible(true).
So the order should be:
// create JFrame
JFrame frame = new JFrame("Foo");
// here add all components to the JFrame
// .....
// done adding components
frame.pack();
// frame.setLocationRelativeToPlatform(true); // if you wish
frame.setVisible(true);
As an aside class names should begin with an upper case letter, and dont have methods with the exact same name as the class, as that creates a "pseudo"-constructor and will confuse everyone.

Creating a JPanel

My main class displays a JMenuBar. This JMenuBar is managed from "calculator.ui.MenuBar."
public JMenuBar createMenuBar()
{
JMenuBar menuBar = new JMenuBar();
new calculator.ui.MenuBar(menuBar);
return menuBar;
}
MenuBar creates my "File" JMenu and "Insert" JMenu.
public MenuBar(JMenuBar menuBar)
{
new FileMenu(menuBar);
new InsertMenu(menuBar);
}
FileMenu contains all the options for "File." In the File class, there is a JMenuItem called "New Calculator." Now, when you click "New Calculator," I want the JPanel in my main class to create an instance of Calculator in my main class.
newFileSubMenu = new JMenu("New...");
calculatorFileSubMenu = new JMenuItem("New Calculator");
calculatorFileSubMenu.getAccessibleContext().setAccessibleDescription(
"New Calculator");
newFileSubMenu.add(calculatorFileSubMenu);
ActionListener newCalculatorListener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
newCalculator();
}
};
calculatorFileSubMenu.addActionListener(newCalculatorListener);
This is the code for my main class JPanel:
public Container createContentPane() {
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setOpaque(true);
JTabbedPane tabbedPane = new JTabbedPane();
return contentPane;
}
My questions are related to the design of my program. For each instance of Calculator, I want to:
Create a JPanel within the main JPanel that contains my Calculator (what stumps me here is how do I - from my FileMenu class - create a JPanel that's in my main class?).
Make sure that the Calculator object refreshes.
Note: I also want my JPanels to be in TabbedPanes (if that changes anything; if it doesn't, then I can figure that part out once I know the answer for the first question.)
Thanks for your help, I hope I've been clear enough in what I want to do.
In your menu item's Action, you can use setSelectedIndex() on your JTabbedPane to select the pane holding an existing calculator instance. You can use setComponentAt() to replace the content of any tab with an instance of your calculator.
There's a related example here.

JMenuBar not showing

I am trying to get my JMenuBar to display in the GUI, however it just appears as a 1-pixel line at the top.
This is my code...
public LibraryView() {
setBounds(100,100,640,480);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JMenuBar b1 = new JMenuBar();
JMenu m1 = new JMenu("Test");
JMenuItem i1 = new JMenuItem("Item1");
this.setJMenuBar(b1);
}
Could someone please help me to understand what is wrong.
You need to add the JMenu and JMenuItem to the JMenuBar. You also need to pack() and setVisible(true); at the end of the method, just before the GUI is shown...
public LibraryView() {
setBounds(100,100,640,480);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JMenuBar b1 = new JMenuBar();
JMenu m1 = new JMenu("Test");
JMenuItem i1 = new JMenuItem("Item1");
m1.add(i1); // ADDED
b1.add(m1); // ADDED
this.setJMenuBar(b1);
pack(); // ADDED
setVisible(true); // MOVED
}
You should call setVisible(true) only after adding all components to the top level window. Also don't forget to use layout managers, to let these managers and your component's preferredSize set the sizes of components, and don't forget to call pack().
call repaint() right before you call set visible(true) this NEVER FAILS.
setJMenuBar(menuBar);
menuBar.add(jMenuItem);
repaint(); //then
setVisible(true); //Assured NEVER FAILS

Categories