Blocking/disabling JavaFX 2 WebView right click - webview

I'm looking for a way to block/disable right click in javafx.scene.web.WebView. To be more specific I don't want the context menu to show up on right click. I'm new to the technology and can't find the way to do it.

Just for the record, it is implemented in JavaFX 2.2. See documentation for setContextMenuEnabled (JavaFX 2) and setContextMenuEnabled (JavaFX 8)

I've came up with working, but ugly, inelegant and, I'd say, partisan solution, which I don't really like, but actually I have no (or just can't find) other way out.
It includes modifying EventDispatcher of WebView.
So my implementation of EventDispatcher needs a reference to original WebView EventDispatcher and looks like that:
public class MyEventDispatcher implements EventDispatcher {
private EventDispatcher originalDispatcher;
public MyEventDispatcher(EventDispatcher originalDispatcher) {
this.originalDispatcher = originalDispatcher;
}
#Override
public Event dispatchEvent(Event event, EventDispatchChain tail) {
if (event instanceof MouseEvent) {
MouseEvent mouseEvent = (MouseEvent) event;
if (MouseButton.SECONDARY == mouseEvent.getButton()) {
mouseEvent.consume();
}
}
return originalDispatcher.dispatchEvent(event, tail);
}
}
Everytime event is dispatched it goes through our dispatcher and I check if it's right click. If it is I just consume it and proceed further.
To make it work you have to use WebView like that:
WebView webView = new WebView();
EventDispatcher originalDispatcher = webView.getEventDispatcher();
webView.setEventDispatcher(new MyEventDispatcher(originalDispatcher));
Every comment, clue and so on are appreciated.

With JavaFX 2.2+ it's now possible to set WebView's ContextMenuEnabled to false:
webView.setContextMenuEnabled(false);
WebView API Doc.

You can style context menus away using the following css.
.context-menu { -fx-background-color: transparent; }
.menu-item { -fx-background-color: transparent; }
.menu-item .label { -fx-text-fill: transparent; }
.menu-item:show-mnemonics .mnemonic-underline { -fx-stroke: -transparent; }
This will make all context menus and menu items transparent. I'm not sure of the css selector you could use to make this only apply to WebView context menus. If you don't have other menus in your application, that may not be a big deal.

You can do it with js (jquery used)
$(document).ready( function() { document.oncontextmenu = function() { return false } } );

Unfortunately it's not yet possible. There is a feature request for that, which you may want to track: http://javafx-jira.kenai.com/browse/RT-15684

This will will remove the context menu for the entire stage:
primaryStage.getScene().addEventFilter(MouseEvent.MOUSE_RELEASED,
new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
if (event.getButton() == MouseButton.SECONDARY) {
event.consume();
}
}
});

Related

Flutter: How to prevent banner ad from showing if view is already disposed

I am currently experimenting with banner ads from the firebase_admob plugin. The process to show and dispose them is pretty straightforward, I do it in initState() and dispose().
The code to create and display the add looks like this:
_bannerAd = createBannerAd();
_bannerAd
..load().then((loaded) {
if (loaded) {
_bannerAd..show();
}
});
However, as I am calling show() asynchronously, it is possible that the view was already closed when the ad is being shown (i.e. by clicking back button really fast). In that case, the dispose() method will never be called and the ad will be "stuck" on the bottom of the screen.
How can I solve this problem? Am I using the banner ad wrong or is it possible to detect if the view was already changed? I tried using the "mounted" property of the state but it didn't seem to work.
Just check "this.mounted" property of state class before showing the add.
_bannerAd = createBannerAd();
_bannerAd
..load().then((loaded) {
if (loaded && this.mounted) {
_bannerAd..show();
}
});
From https://github.com/flutter/flutter/issues/21474#issuecomment-535188820, that's a little hack but it works for me.
You can add a little delay in your dispose method like this:
static void hideBannerAd() {
Future.delayed(Duration(milliseconds: 500), () {
if (_bannerAd != null) _bannerAd.dispose();
_bannerAd = null;
});
}
500 milliseconds is enough.

How to add Header Click Listner in Java Vaadin Table?

I am trying to add a very simple listener to my table header as specified in the book of Vaadin. I am using vaadin 6.4.5 in a liferay portlet. But the listener is never called...
table.addListener(new Table.HeaderClickListener() {
public void headerClick(HeaderClickEvent event) {
System.out.println("Column header clicked");
}
// Disable the default sorting behavior
});
table.setSortDisabled(true);
I am also unable to add footer to my table like this..
table.setFooterVisible(true);
table.setColumnFooter("Name", "Average");
table.setColumnFooter("Died At Age", String.valueOf(avgAge));
Both these code snippets were taken from the book of vaadin but they just don't work in my portlet application. please help
I have working Listener Yeah !
table.addHeaderClickListener(new HeaderClickListener() {
#Override
public void headerClick(HeaderClickEvent event) {
System.out.println("click Header");
Object object= event.getPropertyId();
}
});

Click listener on image broken in Vaadin 7

I run this code to make a button then add it to a GridLayout.
private Image makeButton(String text) {
final Image imageButton = new Image(text);
imageButton.setIcon(new ExternalResource("https://cdn2.iconfinder.com/data/icons/ios7-inspired-mac-icon-set/128/_app_store_128.png"));
imageButton.addClickListener(new MouseEvents.ClickListener() {
#Override
public void click(MouseEvents.ClickEvent event) {
Notification.show("Hello World");
}
});
return imageButton;
}
However the click event is never called. Any idea how/why this could happen?
Use setSource() instead of setIcon().

How to open custom dialog box / popup using Xamarin.Forms?

I am newbie to Xamarin.Forms and stuck with a situation where I want to open up a popup box with my control details [e.g. View Employee Details] on click of parent page.
How can I open custom dialog box / popup using Xamarin.Forms?
Any example code will be appreciated?
Thanks in advance!
If you still want to have your popup's code in its own Page you can set up some custom renderers along the following logic.
1. A ModalPage & corresponding renderer
public class ModalPage : ContentPage { }
public class ModalPageRenderer : PageRenderer {
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
this.View.BackgroundColor = UIColor.Clear;
this.ModalPresentationStyle = UIModalPresentationStyle.OverCurrentContext;
}
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
SetElementSize (new Size (View.Bounds.Width, View.Bounds.Height));
}
}
2. HostPage
public class ModalHostPage : ContentPage, IModalHost
{
#region IModalHost implementation
public Task DisplayPageModal(Page page)
{
var displayEvent = DisplayPageModalRequested;
Task completion = null;
if (displayEvent != null)
{
var eventArgs = new DisplayPageModalRequestedEventArgs(page);
displayEvent(this, eventArgs);
completion = eventArgs.DisplayingPageTask;
}
// If there is no task, just create a new completed one
return completion ?? Task.FromResult<object>(null);
}
#endregion
public event EventHandler<DisplayPageModalRequestedEventArgs> DisplayPageModalRequested;
public sealed class DisplayPageModalRequestedEventArgs : EventArgs
{
public Task DisplayingPageTask { get; set;}
public Page PageToDisplay { get; }
public DisplayPageModalRequestedEventArgs(Page modalPage)
{
PageToDisplay = modalPage;
}
}
}
3. HostPage renderer
public class ModalHostPageRenderer: PageRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if(e.OldElement as ModalHostPage != null)
{
var hostPage = (ModalHostPage)e.OldElement;
hostPage.DisplayPageModalRequested -= OnDisplayPageModalRequested;
}
if (e.NewElement as ModalHostPage != null)
{
var hostPage = (ModalHostPage)e.NewElement;
hostPage.DisplayPageModalRequested += OnDisplayPageModalRequested;
}
}
void OnDisplayPageModalRequested(object sender, ModalHostPage.DisplayPageModalRequestedEventArgs e)
{
e.PageToDisplay.Parent = this.Element;
var renderer = RendererFactory.GetRenderer (e.PageToDisplay);
e.DisplayingPageTask = this.PresentViewControllerAsync(renderer.ViewController, true);
}
}
Then it is as simple as calling
await ModalHost.DisplayPageModal(new PopUpPage());
from your host page or in this particular case from the ViewModel behind.
What Pete said about PushModalAsync / PopModalAsync still remains valid for this solution too (which in my opinion is not a disadvantage), but your popup would appear with transparent background.
The main advantage of this approach, in my opinion, is that you can have your popup XAML/code definition separate from the host page and reuse it on any other page where you wish to show that popup.
The general purpose of what you are trying to achieve can be accomplished by using the PushModalAsync and PopModalAsync methods of Xamarin.Forms Navigation object.
The chances are that this is good enough for what you are needing - However - this isn't truely modal. I will explain after a small code snippet:-
StackLayout objStackLayout = new StackLayout()
{
};
//
Button cmdButton_LaunchModalPage = new Button();
cmdButton_LaunchModalPage.Text = "Launch Modal Window";
objStackLayout.Children.Add(cmdButton_LaunchModalPage);
//
cmdButton_LaunchModalPage.Clicked += (async (o2, e2) =>
{
ContentPage objModalPage = new ContentPage();
objModalPage.Content = await CreatePageContent_Page2();
//
await Navigation.PushModalAsync(objModalPage);
//
// Code will get executed immediately here before the page is dismissed above.
});
//
return objStackLayout;
private async Task<StackLayout> CreatePageContent_Page2()
{
StackLayout objStackLayout = new StackLayout()
{
};
//
Button cmdButton_CloseModalPage = new Button();
cmdButton_CloseModalPage.Text = "Close";
objStackLayout.Children.Add(cmdButton_CloseModalPage);
//
cmdButton_CloseModalPage.Clicked += ((o2, e2) =>
{
this.Navigation.PopModalAsync();
});
//
return objStackLayout;
}
The problem with the above is that the
await Navigation.PushModalAsync(objModalPage);
will immediately return after the animation.
Although you can't interact with the previous page, as we are displaying a new NavigationPage with a Close button shown - the parent Navigation Page is still executing behind the scenes in parallel.
So if you had any timers or anything executing these still would get called unless you stopped those.
You could also use the TaskCompletionSource approach as outlined in the following post also How can I await modal form dismissal using Xamarin.Forms?.
Note - that although you can now await the 2nd page displaying and then when that page is dismissed allowing code execution to continue on the next line - this is still not truely a modal form. Again timers or anything executing still will get called on the parent page.
Update 1:-
To have the content appear over the top of existing content then simply include it on the current page, however make this section of content invisible until you need it.
If you use an outer container such like a Grid that supports multiple child controls in the same cell, then you will be able to achieve what you want.
You will also want to use something like a filled Box with transparency that will cover the entire page also, to control the visible, see through section, that surrounds your inner content section.
I followed above approach and found it impossible to run on iOS 7.
I found this library BTProgressHUD which you can modify and use.
I Use its methods by Dependency service.
Actual library for popups.
https://github.com/nicwise/BTProgressHUD
Following example uses BTProgressHUD library internally.
https://github.com/xximjasonxx/ScorePredictForms

How to customize the Device charm bar using C#/XAML in windows 8?

I have an requirement that, need to customize the Device charm bar in windows 8?
I need to add a button or any other control in Device charm bar.
Is it possible?
If yes, how can we customize it?
Thanks in advance.
You can certainly add commands to Device's charms bar like this:
I assume you want to add to Settings Charms bar.
Create a Class example AppSettings
public AppSetting()
{
SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;
SizeChanged += AppSettingSizeChanged;
}
private void OnCommandsRequested(SettingsPane settingsPane, SettingsPaneCommandsRequestedEventArgs eventArgs)
{
eventArgs.Request.ApplicationCommands.Clear();
UICommandInvokedHandler handler = new UICommandInvokedHandler(OnSettingsCommand);
// Some command
SettingsCommand someCommand = new SettingsCommand("uniqueID", "NameofLabel", handler);
eventArgs.Request.ApplicationCommands.Add(someCommand);
}
private void OnSettingsCommand(IUICommand command)
{
Logger.Log("Called");
SettingsCommand settingsCommand = (SettingsCommand)command;
string id = settingsCommand.Id as string;
switch (id)
{
case someID:
{
ShowSomeUI();
} break;
case otherID:
{
ShowSomeOtherUI();
} break;
}
}
protected void ShowSomeUI()
{
//Implement anything you want here
}
Use the above class and make the very first class of your Application inherit from this class so that the commands are added to charms bar and implement anything on their clicks.
P.S let me know if this is not clear or doesnt answer your question.

Resources