Show an desktop menu bar

I try to add a menu bar on the top of my desktop, i’m close but I fail :slight_smile
Obviously I don’t want open a new frame, but I cannot figure the way to do that.

my code is here

Menu_bar mp;

void setup() {
	buildMenuBar();
}

void draw() {
}

void buildMenuBar() {
	mp = new Menu_bar("Media", 100,100);
	mp.exec();
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
 
public class Menu_bar extends JFrame {
	String name;
	int width;
	int height;

	public Menu_bar(String name, int width, int height) {
		System.setProperty("apple.laf.useScreenMenuBar", "true");
		this.name = name;
		this.width = width;
		this.height = height;
		setTitle(name);
		setSize(this.width,this.height);
		
		// Creates a menubar for a JFrame
		JMenuBar menu_bar = new JMenuBar();
		// Add the menubar to the frame
		setJMenuBar(menu_bar);
		// Define and add two drop down menu to the menubar
		JMenu import_menu = new JMenu("import");
		JMenu text_menu = new JMenu("text");
		JMenu shape_menu = new JMenu("shape");
		JMenu image_menu = new JMenu("image");
		JMenu video_menu = new JMenu("video");

		menu_bar.add(import_menu);
		menu_bar.add(text_menu);
		menu_bar.add(shape_menu);
		menu_bar.add(image_menu);
		menu_bar.add(video_menu);

		// Create and add simple menu item to one of the drop down menu
		JMenuItem new_file = new JMenuItem("Import file");
		JMenuItem new_folder = new JMenuItem("Import folder");
		JMenuItem action_exit = new JMenuItem("Exit");

		import_menu.add(new_file);
		import_menu.add(new_folder);
		import_menu.addSeparator();
		import_menu.add(action_exit);

		// Add a listener to the New menu item. actionPerformed() method will
		// invoked, if user triggred this menu item
		new_file.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("You have clicked on the new action");
			}
		});
	}

	public void exec() {
		Menu_bar me = new Menu_bar(this.name, this.width, this.height);
		me.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		me.setVisible(true);
	}  
}

46

1 Like

The trick here is not to extend JFrame to create the menubar, rather use the one created by Processing for the sketch.

This will not work with P2D and P3D because they use OpenGL so the sketch is shown in a GLWindow not a JFrame

Menu_bar mp;

void setup() {
  buildMenuBar();
}

void draw() {
}

void buildMenuBar() {
  mp = new Menu_bar(this, "Media", 100, 100);
}

Menubar tab

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class Menu_bar {
  JFrame frame;

  public Menu_bar(PApplet app, String name, int width, int height) {
    System.setProperty("apple.laf.useScreenMenuBar", "true");
    frame = (JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas)app.getSurface().getNative()).getFrame();
    frame.setTitle(name);

    // Creates a menubar for a JFrame
    JMenuBar menu_bar = new JMenuBar();
    // Add the menubar to the frame
    frame.setJMenuBar(menu_bar);
    // Define and add two drop down menu to the menubar
    JMenu import_menu = new JMenu("import");
    JMenu text_menu = new JMenu("text");
    JMenu shape_menu = new JMenu("shape");
    JMenu image_menu = new JMenu("image");
    JMenu video_menu = new JMenu("video");

    menu_bar.add(import_menu);
    menu_bar.add(text_menu);
    menu_bar.add(shape_menu);
    menu_bar.add(image_menu);
    menu_bar.add(video_menu);

    // Create and add simple menu item to one of the drop down menu
    JMenuItem new_file = new JMenuItem("Import file");
    JMenuItem new_folder = new JMenuItem("Import folder");
    JMenuItem action_exit = new JMenuItem("Exit");

    import_menu.add(new_file);
    import_menu.add(new_folder);
    import_menu.addSeparator();
    import_menu.add(action_exit);

    // Add a listener to the New menu item. actionPerformed() method will
    // invoked, if user triggred this menu item
    new_file.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent arg0) {
        System.out.println("You have clicked on the new action");
      }
    }
    );
    frame.setVisible(true);
  }
4 Likes

thanks, but here ( Raspberry Pi ) i must use

//    frame = (JFrame) (processing.awt.PSurfaceAWT.SmoothCanvas)app.getSurface().getNative()).getFrame();
    frame = (JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas)app.getSurface().getNative()).getFrame();

and in setup to see something, like

void setup() {
  size(500,500);
  buildMenuBar();
}

2019-03-27_00-04-50_snap

Sorry accidentally deleted a ‘(’ I have corrected the code above :wink:

You can always put the statement

frame.setVisible(true);

as the last line of the constructor, if fact it makes sense. I will modify the code above to do that.

Thx @quark that’s great because in my case I don’t need P2D or P3D but if I need one day to do that with an OPENGLrendering is not possible if I understand well ?

It should be possible. But you’re gonna need to grab a diff. datatype which would correspond to the JAVA2D’s own JFrame:

JFrame and JMenubar are part of the Java Swing frame work and is incompatible with OpenGL and GLWindow, so it won’t be possible to do it this way. As GoToLoop pointed out you would need to find the OpenGL equivalent of menubars, but as far as I know there isn’t one.

There is an alternative to using P2D and P3D, and that is to use JAVA2D for the main sketch and then use OpenGL off-screen buffers for drawing which are then copied to the main sketch display in the draw() method. G4P uses this in its latest version for the GView control.

1 Like

Thx for the advice @GoToLoop and @quark I think stay on classic renderer. But if I need I know now there is a trick !!!

Now the problem very very important is catching the information and I don’t any possibility to do that.

How catch something in this part to use in other place of my code. I try to pass argument, but the arg need to be static :frowning:
And I don’t find on the internet a method to catch something the JMenuItem like boolean statement .
I figure the probleme is around this part:

public void actionPerformed(ActionEvent arg0) {
   println("happen when is clicked");
}

Refactoring code:

Crope_Bar cb;
void setup() {
	cb = new Crope_Bar(this);
	cb.help();
	cb.set("about","file,load,load recent,|,save,save as","import,file,folder","help,controler,prescene,scene");
	cb.show();
}

void draw() {
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
 
public class Crope_Bar {
	JFrame frame;
	JMenuBar menu_bar;

	public Crope_Bar(PApplet app) {
		System.setProperty("apple.laf.useScreenMenuBar", "true");
		frame = (JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas)app.getSurface().getNative()).getFrame();
		menu_bar = new JMenuBar();
		frame.setJMenuBar(menu_bar);
	}

  ArrayList<JMenuItem> menu_item_list = new ArrayList<JMenuItem>();
	void set(String... data) {
		menu_item_list.clear();
		build(data);
		set_listen();
	}

	void build(String... data) {
		JMenu [] menu = new JMenu [data.length];
		for(int i = 0 ; i < data.length ; i++) {
			println(data[i]);
			String[] content = split(data[i],",");
			menu[i] = new JMenu(content[0]);
			menu_bar.add(menu[i]);
			if(content.length > 1) {
				for(int k = 1 ; k < content.length ; k++) {
					if(content[k].equals("|")) {
						menu[i].addSeparator();
					} else {
						JMenuItem menu_item = new JMenuItem(content[k]);
						menu_item_list.add(menu_item);
						menu[i].add(menu_item);
					}
				}
			}
		}
	}
  
	void set_listen() {
		if(menu_item_list.size() > 0) {
			for(JMenuItem mi : menu_item_list) {
				mi.addActionListener(new ActionListener() { 
					public void actionPerformed(ActionEvent arg0) { 
						println("You have clicked on menu but how use it out this line ?????, because I just can pass a static variable here :(");
					}
		    });
			}
		}
	}

	void show() {
		frame.setVisible(true);
	}
}

I believe it’d be much clear for us to figure out your code if you’d post it fully on some GitHub repo. :thinking:

et voilà ! https://github.com/StanLepunK/Crope
you just need to dowload my little Rope library to performe the sketch.
the problem is on this tab: https://github.com/StanLepunK/Crope/blob/master/crope_gui/menu_bar_default_render.pde

Finally i need to make a bridge from P3D / P2D to JFrame but you example is very hard to understand… after I catch that : com.jogamp.newt.opengl.GLWindow glw = (com.jogamp.newt.opengl.GLWindow)app.getSurface().getNative();what the next step ?

On that CanvasResizeWatcher.java , the only thing it uses getNative() for, regardless of the renderer, is to add & remove listeners to the sketch’s canvas. :framed_picture:

I’m afraid if you need to do more stuff to it, you’re gonna need to study the JOGL API: :anguished:
JogAmp.org/deployment/jogamp-next/javadoc/jogl/javadoc/

BtW, many of your code’ classes can be easily converted from “.pde” to “.java”. :coffee:

Which part of my code you talk to converter in Java ? If I remenber the Java code need to put in folder code?

Any file w/ a class which accepts a PApplet can easily be renamed & turned into a “.java” file. :coffee:

1 Like