How to add a JPopupMenu to a JMenuBar? - swing

I have an application with a popup menu. I'd like to use the popup in the usual way (i.e., it should appear when the user right-clicks anywhere in the window), but I'd also like to attach it to the main MenuBar at the top of the window. I'm not sure how to do this.
I'd thought it would as simple as calling
myJMenuBar.add(myPopupMenu)
but this doesn't work.
JMenuBar.add() wants a JMenu parameter, not a JPopupMenu.
Does anyone have any suggestions?

Instead of trying to reuse the JPopupMenu object, the best approach would be to encapsulate the actions that the menus perform, and reuse those. The popup would trigger those actions, as would the menu items.
From the Action JavaDoc:
In addition to the actionPerformed method defined by the ActionListener interface, this interface allows the application to define, in a single place:
One or more text strings that describe the function. These strings can be used, for example, to display the flyover text for a button or to set the text in a menu item.
One or more icons that depict the function. These icons can be used for the images in a menu control, or for composite entries in a more sophisticated user interface.
The enabled/disabled state of the functionality. Instead of having to separately disable the menu item and the toolbar button, the application can disable the function that implements this interface. All components which are registered as listeners for the state change then know to disable event generation for that item and to modify the display accordingly.
and
JPopupMenu, JToolBar and JMenu all provide convenience methods for creating a component and setting the Action on the corresponding component. Refer to each of these classes for more information.

I had the same issue. A right-mouse-click as well as a top menu with exactly the same (complicated) set of menu items. The 'Action' class is something to consider if you are talking about enablement choices, but it's not dealing with visibility and in my case there was also a dynamic list of entries based on a current selection that I wanted to reuse.
So I ended up implementing a 'Bridge' design pattern (I think) for the methods I actually use (add() and addSeparator()):
public static class MenuBridge
{
private JPopupMenu popupMenu;
private JMenu menu;
public MenuBridge(JPopupMenu popupMenu)
{
this.popupMenu = popupMenu;
}
public MenuBridge(JMenu menu)
{
this.menu = menu;
}
public void addSeparator()
{
if(popupMenu!=null) popupMenu.addSeparator();
else menu.addSeparator();
}
public void add(JMenuItem item)
{
if(popupMenu!=null) popupMenu.add(item);
else menu.add(item);
}
}
So then I can write a reusable method that computes the menu items and synchronize my right mouse click with the top-level menu:
public void addTaskMenuItems(DefaultMenu menu, List<MDProcTask> taskList)
{
...
menu.add()/menu.addSeparator()
...
}
addTaskMenuItems(new DefaultMenu(popupMenu),taskList);
...
taskMenu.addMenuListener( new MenuListener() {
public void menuCanceled(MenuEvent menuevent)
{
}
public void menuDeselected(MenuEvent menuevent)
{
}
public void menuSelected(MenuEvent menuevent)
{
taskMenu.removeAll();
addTaskMenuItems( new DefaultMenu(taskMenu),getSelectedTasks());
taskMenu.revalidate();
}});

Related

Want to create an automation that switches between two tabs

I am new to automation and want to create an automation test which can do following:
Open one tab --- click and get some info from that tab
Switch to another tab --- click and get some info from this tab now.
Compare the infos.
We use Page Object Model to get info from one page. However the moment, I switch to another tab -- it switches the tab successfully but does not locate any element on it.
Any idea ?
Questions I would ask is,
Is the element locator correct?
Is this a unique element locator?
Is this a synchronization issue? Are you waiting enough for the page to load before finding the element?
Is this problem particular to a browser? Is it consistent across?
Also make sure you pass on the driver object from one page object to the other. Like,
public class PageOne {
public PageOne(WebDriver driver) {
//do something in constructor
}
public void someMethodInPage1() {
driver.findElement(By.id("button1")).click();
PageTwo pageTwo = new PageTwo(driver);
pageTwo.someMethodInPage2();
}
}
public class PageTwo {
private WebDriver driver;
public PageTwo(WebDriver driver) {
//do something in constructor
this.driver = driver;
}
public void someMethodInPage2() {
driver.findElement(By.id("button2")).click();
}
}

Adding MenuItems in many Pages in Windows Phone application

I need to add menuItems in Windows phone page. I know how to add it in single page.
However is it possible to add a menuItems to couple of pages by assigning it in single page/somewhere (ie Common menuItem (Say Home) which should be appears in all pages)
I think you should go for a USER CONTROL. You can have it to multiple pages. You can have Reference to create it here Why and how to create a User Control in Windows Phone
You could create a helper/factory class that creates your base app bar and/or individual menu items.
public class AppBarHelper
{
public static ApplicationBar CreateCommmonAppBar()
{
// return app bar with common menu items..etc.
}
public static ApplicationBarMenuItem CreateHomeMenuItem()
{
// return your menu item
}
}
And then in your pages you could call it like this in the constructor
public MainPage()
{
ApplicationBar = AppBarHelper.CreateCommonAppBar();
}

Create custom presenter for my mvvmcross project

I'm working on a project for iOS using mvvmcross.
App navigation goes like this: first it starts from the splash screen (1), them it navigates to (2), a view to select between 3 options, in view (3) and (4) you get a list and also could navigate back to (2), if you select an item in (3) you navigate to (5) in a modal way.
Lastly, all navigation end up in (6), a view with an hamburger menu.
So I have traditional navigation(with back button), modal views and a hamburger menu at the end.
It would be great if someone could help me or guide me to see how to create a custom presenter for this navigation scheme.
I'm using MvxModalNavSupportTouchViewPresenter and a SlidingPanelsNavigationViewController, but don't know how to swap them when I navigate from (2,4,5) to (6)
A presenter is just something that implements https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross/Core/Core/Views/IMvxViewPresenter.cs
public interface IMvxViewPresenter
{
void Show(MvxViewModelRequest request);
void ChangePresentation(MvxPresentationHint hint);
}
This is are really simple interface and it allows shared portable code like ViewModels to request changes in the display.
For the case where you want a Show request to change the entire UI from one display paradigm (modal navigation controller) to another (sliding panels), then one way to do this is to implement a presenter which has two child presenters and which simply switches them over.
In pseudo code this might look like:
public class MyPresenter : IMvxViewPresenter
{
private IMvxViewPresenter _currentPresenter;
private ModalPresenter _modalPresenter;
private SlidingPresenter _slidingPresenter;
private enum Style
{
Modal, Panels
}
private Style _currentStyle;
public MyPresenter()
{
// do whatever you need to do here to:
// - construct _modalPresenter and _slidingPresenter
// - make _modalPresenter attached to the window (via root view controller)
// - make _slidingPresenter hidden/unattached
_currentStyle = Style.Modal;
_currentPresenter = _modalPresenter;
}
public void Show(MvxViewModelRequest request)
{
if (_currentStyle == Style.Modal &&
request.ViewModelType == typeof(WhateverViewModelIndicatesTheSwitchIsNeeded))
{
DoSwitch(request);
return;
}
_currentPresenter.Show(request);
}
public void ChangePresentation(MvxPresentationHint hint)
{
_currentPresenter.ChangePresentation(hint);
}
private void DoSwitch(MvxViewModelRequest request)
{
// do whatever is necessary to:
// - remove _modalPresenter from the window
// - add _panelPresenter to the window
// - show `request` within _panelPresenter
_currentPresenter = _panelPresenter;
_currentStyle = Style.Panelsl
}
}
Obviously, there are some details to fill in within this pseudo-code - e.g. there are some viewcontrollers to be added and removed from the window - but this is just standard iOS manipulation - e.g. see lots of questions and answers like Changing root view controller of a iOS Window and Change rootViewController from uiviewcontroller to uinavigationcontroller

actionscript, drag and drop an object from a list of objects

I'm creating an application where the user can select an object from a list of objects, and then put it on the main window.
I want to have the list of objects presented like in the web app :
http://builds.balsamiq.com/b/mockups-web-demo/
The user can select a category, then the list of objects of that category is displayed, then he can drag and drop an object to the main window.
How is it possible to do this, having a list of objects?
Thanks
You should write a class for every list of objects, add your items in your class and then write your drag and drop function for that class.
public class DragDrop extends MovieClip
{
public function DragDrop()
{
this.addEventListener(MouseEvent.MOUSE_DOWN, drag);
}
private function drag(event:MouseEvent):void
{
this.startDrag();
this.addEventListener(MouseEvent.MOUSE_UP,drop);
}
}
Coordy is a nice little toolkit for constructing and keeping track of things laid out in lists:
http://somerandomdude.com/projects/coordy/
The main examples are for 3D spiral layouts and such, but Coordy works well for simpler linear layouts too.

How do you manage this inheritance problem?

Lets's say you have 2 classes ToolBar and DrawingToolBar. ToolBar is to serve as a base class for various other toolbars, for various tools. ToolBar handles the basic 'toolbar-y' stuff like opening, closing, dragging, dropping, etc. The DrawingToolBar adds functionality that is specific to a particular tool - tool-specific buttons, etc.
public class ToolBar extends Sprite {
public var closeBtn:Sprite
public function ToolBar():void {
addChild(closeBtn)
closeBtn.addEventListener(MouseEvent.CLICK, closeBtn_onClick)
}
protected function closeBtn_onClick(e:Event):void {
close()
}
public function open():void {
// blah
}
public function close():void {
// blah
}
}
and:
public class DrawingToolBar extends ToolBar{
public var penBtn: Sprite
public var paintbrushBtn: Sprite
public var colorPicker: ColorPicker
public function DrawingToolBar():void {
super()
}
public function getColour():int {
return colorPicker.color;
}
}
Now, we also have another 2 classes - Tool and DrawingTool. Again, Tool is a base class for various tools (incl. DrawingTool). If I make a ToolBar member in Tool (typed as ToolBar), we can delegate common tasks, eg. when the Tool is enabled, it adds the ToolBar to the stage, etc. The DrawingTool can instantiate the ToolBar as a DrawingToolBar so the correct library asset is used (but the instance is still typed as ToolBar).
public class Tool {
public var toolBar:ToolBar
public function Tool():void {
initToolBar()
}
protected function initToolBar():void {
addChild(toolBar)
}
}
and:
public class DrawingTool extends Tool {
public function DrawingTool():void {
super()
}
override protected function initToolBar():void {
toolbar = new DrawingToolBar() // this is probably very naughty
super.initToolBar()
}
public function getColor():int {
return toolBar.getColor() // this fails because toolBar is type as ToolBar not DrawingToolBar
}
}
The problem comes when, in DrawingTool I want to call a method of DrawingToolBar. Because the toolbar is typed as ToolBar, I can't call methods of DrawingToolBar on it. What do I do?
cast it every time I want to call a method of DrawingToolBar?
create a member in DrawingTool (eg. var drawingToolBar: DrawingToolBar), instantiate that and then make toolBar = drawingToolBar?
The first seems clunky, I don't even know if it would work. The second seems better but it feels a bit 'wrong'.
Is there another way? Or am I mis-using inheritance here?
You are probably mixing too many functionnalities into your toolbar. If you think MVC, you are missing a Model.
More precisely, the color picker should not be a property of your toolbar. The color picker is a property of your tool. Each drawing tool should be self contained and have its own color picker. If all drawing tools need to share the same color, you'll need a Drawing model that is shared by all drawing tools.
I would also change the relation between the Toolbar and its tools in the other direction. A toolbar has tools, but the tools themselves should be self contained and not have a reference to their containing toolbar.
The Java / Swing model is very clean on how it works with toolbars. You could get some inspiration from it : http://download.oracle.com/javase/tutorial/uiswing/components/toolbar.html