When I create a menu in java GUI by using JMenuBar it puts all JMenus from Left-to-right direction like this:
I want to change it to Right-to-left like this:
I want do this in an English OS, so suggestions of an Arabic or Right-to-Left solution aren't what I'm looking for.
You can use Component.applyComponentOrientation to change the orientation of the JMenuBar:
import javax.swing.*;
import java.awt.*;
public class R_L_MenuBar_Demo
{
public static void main(String[] args){
SwingUtilities.invokeLater(() -> createAndShowGUI());
}
private static void createAndShowGUI()
{
JMenuBar mb = new JMenuBar();
JMenuItem item_1 = new JMenuItem("First Item");
JMenu menu_2 = new JMenu("Second Menu");
JMenuItem item_3 = new JMenuItem("First Item in Second");
menu_2.add(item_3);
mb.add(item_1);
mb.add(menu_2);
//switch the orientation of the menubar to right to left
JButton btn_r_to_l = new JButton("Switch menubar to r_to_l");
btn_r_to_l.addActionListener(e -> {
mb.invalidate();
mb.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
mb.validate();
});
//switch the orientation of the menubar to left to right
JButton btn_l_to_r = new JButton("Switch menubar to l_to_r");
btn_l_to_r.addActionListener(e -> {
mb.invalidate();
mb.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
mb.validate();
});
JFrame frame = new JFrame("R_L_MenuBar");
frame.setLayout(new FlowLayout());
frame.add(btn_r_to_l);
frame.add(btn_l_to_r);
frame.setJMenuBar(mb);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200 , 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
This will look like this:
The Default look (left to right)
And after switching to right-to-left:
Related
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'm working on a simple app and I need to access JFrame created when initializing a program from different places where it's not always possible to access it directly (e.g. contentPane is empty so SwingUtilities.getWindowAncestor(Component) won't work). Is there any other way to do this? For example, this is a class resposinble for initialization:
public final class Application{
public static void start(){
//Empty screen with menu
SwingUtilities.invokeAndWait(() -> {
JFrame frame = new JFrame("Main frame");
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Start");
menuBar.add(menu);
frame.setJMenuBar(menuBar);
});
}
}
And I need to use it from some other places, e.g.
JPanel panel = new JPanel();
//initialize the panel
//push it to the content pane of Main frame
So, in order to share the main frame I tend to wrap it in a singleton class and then provide a static method. Maybe there is another way of doing that?
You can store it in a static reference:
public final class Application{
static JFrame mainFrame; //static attribute
public static void start(){
//Empty screen with menu
SwingUtilities.invokeAndWait(() -> {
JFrame frame = new JFrame("Main frame");
mainFrame = frame; //Storing in static attribute
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Start");
menuBar.add(menu);
frame.setJMenuBar(menuBar);
});
}
}
An call it as follows:
JPanel panel = new JPanel();
//initialize the panel
Application.mainFrame.getContentPane().add(panel);
This is a ugly solution maybe you can review Design Patterns for a better solution:
http://www.tutorialspoint.com/design_pattern/
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);
}
}
}
}
This is my code so far:
public static void main(String[] args){
JFrame frame = new JFrame("Breakout!");
frame.setLocation(300, 300);
//Making the menubar
JMenuBar mb = new JMenuBar();
frame.setJMenuBar(mb);
JMenu fileMenu = new JMenu("File");
mb.add(fileMenu);
JMenuItem newAction = new JMenuItem("About");
fileMenu.add(newAction);
newAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println("open new window here");
}
});
BreakoutCourt c = new BreakoutCourt();
frame.add(c);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
I am making a Breakout game. I want to make an About window that displays information about the game (like, how to play it and so on). How would I go about doing that? Thank you for the help! I'm very new to Java Swing, so yeah.
You could do a simple one with the message type of JOptionPane:
JOptionPane.showMessageDialog(frame, "Breakout! v1.0");
(You'll need to make the frame final to do this, since it's being accessed from within the anonymous action listener).
For more control over what is displayed, and whether it should be modal or not, you could look at JDialog. There's an overview of using dialogs in Swing here: http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html.
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.