{"id":646,"date":"2012-12-19T14:59:28","date_gmt":"2012-12-19T12:59:28","guid":{"rendered":"http:\/\/www.pellissier.co.za\/hermien\/?p=646"},"modified":"2013-02-10T08:45:36","modified_gmt":"2013-02-10T06:45:36","slug":"adding-a-custom-component-to-the-menu-bar","status":"publish","type":"post","link":"https:\/\/www.pellissier.co.za\/hermien\/?p=646","title":{"rendered":"Adding a Custom Component to the Menu Bar"},"content":{"rendered":"<p>The open space on the menu bar of a NetBeans Platform application is often wasted. In the NetBeans IDE, the quick search bar is positioned in that handy location. And your application <a href=\"http:\/\/www.pellissier.co.za\/hermien\/?p=389\">can have that too<\/a> of course. However, the question was raised on the <a href=\"http:\/\/forums.netbeans.org\/topic52822.html\">forums<\/a> recently how one would go about adding your own component there. Here is the promised post explaining the steps in detail. The result will look like the screenshot below, with the new User label introduced in the space where the quick search would have been.<\/p>\n<figure id=\"attachment_654\" aria-describedby=\"caption-attachment-654\" style=\"width: 818px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.pellissier.co.za\/h\/wp-content\/uploads\/sites\/2\/2012\/12\/complete-screenshot1.png\"><img loading=\"lazy\" class=\"size-full wp-image-654\" title=\"Screenshot showing the standalone module running in the IDE\" alt=\"Screenshot showing the standalone module running in the IDE\" src=\"http:\/\/www.pellissier.co.za\/h\/wp-content\/uploads\/sites\/2\/2012\/12\/complete-screenshot1.png\" width=\"828\" height=\"561\" srcset=\"https:\/\/www.pellissier.co.za\/hermien\/wp-content\/uploads\/sites\/2\/2012\/12\/complete-screenshot1.png 828w, https:\/\/www.pellissier.co.za\/hermien\/wp-content\/uploads\/sites\/2\/2012\/12\/complete-screenshot1-300x203.png 300w, https:\/\/www.pellissier.co.za\/hermien\/wp-content\/uploads\/sites\/2\/2012\/12\/complete-screenshot1-624x422.png 624w\" sizes=\"(max-width: 828px) 100vw, 828px\" \/><\/a><figcaption id=\"caption-attachment-654\" class=\"wp-caption-text\">Screenshot showing the standalone module running in the IDE<\/figcaption><\/figure>\n<p><strong>Step 1: The Module.<\/strong> We need a NetBeans Platform module to work with. So if you don&#8217;t have one yet, create one now. It can be either a standalone module or exist as a part of a suite. I created a standalone module. When you run a standalone module, it basically gets installed into an instance of the IDE. That is why the screenshot shows all the bits of the IDE.<\/p>\n<p><strong>Step 2: The Component.<\/strong> Create a new JPanel form (I called mine CustomComponent) and add a JLabel to it. Specify and icon for the label if you wish. The important point to take note of is that you need to specify a size for the panel (resize it in the GUI builder) and then specify that same size as the minimum and maximum size of the panel too. Otherwise the size of the panel will not be what you expected.<\/p>\n<figure id=\"attachment_658\" aria-describedby=\"caption-attachment-658\" style=\"width: 174px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.pellissier.co.za\/h\/wp-content\/uploads\/sites\/2\/2012\/12\/custom-component.png\"><img loading=\"lazy\" class=\"size-full wp-image-658\" title=\"Custom component in the GUI builder\" alt=\"Custom component in the GUI builder\" src=\"http:\/\/www.pellissier.co.za\/h\/wp-content\/uploads\/sites\/2\/2012\/12\/custom-component.png\" width=\"184\" height=\"160\" \/><\/a><figcaption id=\"caption-attachment-658\" class=\"wp-caption-text\">Custom component in the GUI builder<\/figcaption><\/figure>\n<p><strong>Step 3: The Action.<\/strong> Just as the <a href=\"http:\/\/platform.netbeans.org\/tutorials\/nbm-google.html\">NetBeans IDE 7.2 Plugin Quick Start tutorial<\/a> describes, create a new Action. Just as the tutorial describes, choose Global Toolbar Button on the GUI Registration page (this will be changed later). Change the action to extend from AbstractAction and implement Presenter.Toolbar, all still as in the tutorial. And in the getToolbarPresenter() method return an instance of CustomComponent.<\/p>\n<p>Then change the @ActionReference annotation&#8217;s path to just be &#8220;Menu&#8221; and position to be 10000.<\/p>\n<p>So at the end of this step we now have the action class below.<\/p>\n<p>[java]import java.awt.Component;<br \/>\nimport java.awt.event.ActionEvent;<br \/>\nimport javax.swing.AbstractAction;<br \/>\nimport org.openide.awt.ActionID;<br \/>\nimport org.openide.awt.ActionReference;<br \/>\nimport org.openide.awt.ActionRegistration;<br \/>\nimport org.openide.util.NbBundle.Messages;<br \/>\nimport org.openide.util.actions.Presenter;<\/p>\n<p>@ActionID(category = &#8220;Build&#8221;,<br \/>\nid = &#8220;za.co.pellissier.componentinmenubar.CustomComponentActionListener&#8221;)<br \/>\n@ActionRegistration(<br \/>\ndisplayName = &#8220;#CTL_CustomComponentActionListener&#8221;)<br \/>\n@ActionReference(path = &#8220;Menu&#8221;, position = 10000)<br \/>\n@Messages(&#8220;CTL_CustomComponentActionListener=CustomComponent&#8221;)<br \/>\npublic final class CustomComponentActionListener<br \/>\nextends AbstractAction implements Presenter.Toolbar {<\/p>\n<p>@Override<br \/>\npublic void actionPerformed(ActionEvent e) {<br \/>\n}<\/p>\n<p>@Override<br \/>\npublic Component getToolbarPresenter() {<br \/>\nreturn new CustomComponent();<br \/>\n}<br \/>\n}[\/java]<\/p>\n<p><strong>Step 4. Alignment.<\/strong> In order to force the component to be right-aligned, we can add a spacer just to the left of it. Here the <a href=\"http:\/\/platform.netbeans.org\/tutorials\/nbm-quick-search.html\">NetBeans Quick Search Integration Tutorial<\/a> has a handy example (in the very last section). Create an XML Layer file in your module. The file should be opened on creation. Now add a spacer like in the tutorial, resulting in the layer.xml file looking like this:<\/p>\n<p>[xml]<?xml version=\"1.0\" encoding=\"UTF-8\"?><br \/>\n<!DOCTYPE filesystem PUBLIC \"-\/\/NetBeans\/\/DTD Filesystem 1.2\/\/EN\" \"http:\/\/www.netbeans.org\/dtds\/filesystem-1_2.dtd\"><br \/>\n<filesystem><br \/>\n    <file name=\"Spacer.instance\"><br \/>\n        <attr name=\"instanceCreate\" methodvalue=\"javax.swing.Box.createHorizontalGlue\"\/><br \/>\n        <attr name=\"position\" intvalue=\"9999\"\/><br \/>\n    <\/file><br \/>\n<\/filesystem>[\/xml]<\/p>\n<p>Note the position of 9999, which is just to the left of the 10000 of the component.<\/p>\n<p><strong>Step 5. Hiding Quick Search.<\/strong> In practice you could have the quick search and your own component next to one another. However, for the purpose of this tutorial I decided to hide the quick search feature. Modify the layer file once more, so that it looks like this:<\/p>\n<p>[xml]<?xml version=\"1.0\" encoding=\"UTF-8\"?><br \/>\n<!DOCTYPE filesystem PUBLIC \"-\/\/NetBeans\/\/DTD Filesystem 1.2\/\/EN\" \"http:\/\/www.netbeans.org\/dtds\/filesystem-1_2.dtd\"><br \/>\n<filesystem><br \/>\n    <folder name=\"Menu\"><br \/>\n        <file name=\"org-netbeans-modules-quicksearch-QuickSearchAction.shadow_hidden\"\/><br \/>\n    <\/folder><br \/>\n    <file name=\"Spacer.instance\"><br \/>\n        <attr name=\"instanceCreate\" methodvalue=\"javax.swing.Box.createHorizontalGlue\"\/><br \/>\n        <attr name=\"position\" intvalue=\"9999\"\/><br \/>\n    <\/file><br \/>\n<\/filesystem>[\/xml]<\/p>\n<p>That is it. Now you have a custom component being displayed in the empty space on the menu bar.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The open space on the menu bar of a NetBeans Platform application is often wasted. In the NetBeans IDE, the quick search bar is positioned in that handy location. And your application can have that too of course. However, the question was raised on the forums recently how one would go about adding your own &#8230; <a title=\"Adding a Custom Component to the Menu Bar\" class=\"read-more\" href=\"https:\/\/www.pellissier.co.za\/hermien\/?p=646\" aria-label=\"More on Adding a Custom Component to the Menu Bar\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[3,5],"tags":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p1v8WL-aq","_links":{"self":[{"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=\/wp\/v2\/posts\/646"}],"collection":[{"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=646"}],"version-history":[{"count":1,"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=\/wp\/v2\/posts\/646\/revisions"}],"predecessor-version":[{"id":676,"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=\/wp\/v2\/posts\/646\/revisions\/676"}],"wp:attachment":[{"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=646"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=646"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pellissier.co.za\/hermien\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=646"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}