Online Pdf viewer with pinch zoom throws exception after close activity - android-studio

I want to open a PDF file from server in web-view with zoom facilities.
I am using webView.setBuiltInZoomControls(true) but it throws an exception after close activity.
I am using below code:
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setSupportZoom(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
webView.loadUrl(url);
return false;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
});
webView.loadUrl("http://docs.google.com/gview?embedded=true&url=" + data.getTypeUrl());
Exception is :
android.view.WindowLeaked: Activity has leaked window android.widget.ZoomButtonsController$Container that was originally added here

Try this:
// make sure your pinch zoom is enabled
webView.getSettings().setBuiltInZoomControls(true);
// don't show the zoom controls
webView.getSettings().setDisplayZoomControls(false);

Related

Revit Dockable pane does not react for min width

I have dockable pane with DockPosition=Rigth and MinWidth=300.
When pane is attached to Revit everything fine, but when i move it using mouse and DockPosition is changed to Floating , the panel do not react for MinWidth and change width to ~100.
xaml behind
xaml
How do you register the panel? You can try to register the panel after application is initialized if you haven't already tried that.
UIControlledApplication _uiControlledApplication = null;
public Result OnStartup(UIControlledApplication application)
{
_uiControlledApplication = application;
application.ControlledApplication.ApplicationInitialized += OnApplicationInitialized;
return Result.Succeeded;
}
private void OnApplicationInitialized(object sender, EventArgs e)
{
RegisterDockableWindow(_uiControlledApplication);
}
private void RegisterDockableWindow(UIControlledApplication app)
{
//app.RegisterDockablePane(....)
}

Can't handle browser window (htmlunit)

I want to download config.bin file from site. Work with htmlunit
final WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setTimeout(2000);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.setConfirmHandler(new ConfirmHandler() {
public boolean handleConfirm(Page page, String message) {
System.out.println(" -----------------------");
System.out.println("handle config");
System.out.println(" -----------------------");
return true;
}
});
final HtmlPage page = webClient.getPage("http://site");
final DomElement backup = mainFrame.getElementByName("Backup");
webClient.addWebWindowListener(new WebWindowListener()
{
public void webWindowClosed(WebWindowEvent event)
{
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1");
};
public void webWindowContentChanged(WebWindowEvent
event)
{
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2");
}
public void webWindowOpened(WebWindowEvent event)
{
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3");
}
});
InputStream input = backup.click().getWebResponse().getContentAsStream();
Then submited ckick() I think that get stream, but got submit page. I think that I have problem with browser window and I can't handle browser window. I insert sout in handler and see when this method to called but it didn't call
the problem was in period that i install. changed setTimeout and all work.
webClient.getOptions().setTimeout(15000);

Drag text from browser into JavaFX GUI

I can't find any question exactly like this: Is there a way in JavaFX to display a GUI (stage) that accepts text that a user drap-and-drops from a browser?
For instance, the user navigates to a certain URL, then copies all of the page's text and drags it into the JavaFX stage displayed. The text can then be used within the Java program. I'd prefer not to use Selenium so that my app doesn't perform any scrape-like activities.
I'm looking for a solution compatible with Windows XP+ and all browsers.
Any feedback regarding starting points, tutorials, posts or limitations is great. Thank you
You may try something like this:
public class MainApp extends Application {
#Override
public void start(Stage stage) throws Exception {
TextField textField = new TextField();
textField.setPromptText("Drag text here");
textField.addEventHandler(
DragEvent.DRAG_OVER,
event -> {
if (event.getDragboard().hasString()) {
event.acceptTransferModes(TransferMode.COPY);
}
event.consume();
});
textField.addEventHandler(
DragEvent.DRAG_DROPPED,
event -> {
Dragboard dragboard = event.getDragboard();
if (event.getTransferMode() == TransferMode.COPY &&
dragboard.hasString()) {
textField.setText(dragboard.getString());
event.setDropCompleted(true);
}
event.consume();
});
StackPane stackPane = new StackPane(textField);
stackPane.setPadding(new Insets(5));
stage.setScene(new Scene(stackPane, 300, 150));
stage.setTitle("Drag and Drop");
stage.show();
}
public static void main(String[] args) {
MainApp.launch(args);
}
}
Getting HTML content
TextArea textArea = new TextArea();
textArea.setPromptText("Drag text here");
textArea.addEventHandler(
DragEvent.DRAG_OVER,
event -> {
if (event.getDragboard().hasHtml()) {
event.acceptTransferModes(TransferMode.COPY);
}
event.consume();
});
textArea.addEventHandler(
DragEvent.DRAG_DROPPED,
event -> {
Dragboard dragboard = event.getDragboard();
if (event.getTransferMode() == TransferMode.COPY &&
dragboard.hasHtml()) {
textArea.setText(dragboard.getHtml());
event.setDropCompleted(true);
}
event.consume();
});

Downloads with JavaFX WebView

my web application offers a download. Javascript creats at the click the url (it depends on the user input) and the browser should open it, so that the page isn't reloaded.
For that, I think I have to alternatives:
// Alt1:
window.open(pathToFile);
// Alt2:
var downloadFrame = document.getElementById('downloads');
if (downloadFrame === null) {
downloadFrame = document.createElement('iframe');
downloadFrame.id = 'downloads';
downloadFrame.style.display = 'none';
document.body.appendChild(downloadFrame);
}
downloadFrame.src = pathToFile;
Both works under Firefox. Problem with open new window method: If the creation of the file at the server needs more time, the new empty tab will be closed late.
Problem with iframe: If there is an error at the server, no feedback is given.
I think at firefox the iframe is the better solution. But the web application must run with an JavaFX WebView, too. JavaFX haven't a download feature, I have to write it. One possible way is to listen on the location property:
final WebView webView = new WebView();
webView.getEngine().locationProperty().addListener(new ChangeListener<String>() {
#Override public void changed(ObservableValue<? extends String> observableValue, String oldLoc, String newLoc) {
if (newLoc.cotains("/download")) {
FileChooser chooser = new FileChooser();
chooser.setTitle("Save " + newLoc);
File saveFile = chooser.showSaveDialog(webView.getEngine().getScene().getWindow());
if (saveFile != null) {
BufferedInputStream is = null;
BufferedOutputStream os = null;
try {
is = new BufferedInputStream(new URL(newLoc).openStream());
os = new BufferedOutputStream(new FileOutputStream(saveFile));
while ((readBytes = is.read()) != -1) {
os.write(b);
}
} finally {
try { if (is != null) is.close(); } catch (IOException e) {}
try { if (os != null) os.close(); } catch (IOException e) {}
}
}
}
}
}
There are some problems:
The download start depends on a part of the url, because JafaFX supports no access to the http headers (that is bearable)
If the user starts the download with the same url two times, only the first download works (the change event only fires, if the url is new). I can crate unique urls (with #1, #2 and so on at the end). But this is ugly.
Only the "window.open(pathToFile);" method works. Loading an iframe don't fire the change location event of the website. That is expectable but I haven't found the right Listener.
Can someone help me to solve 2. or 3.?
Thank you!
PS: Sorry for my bad english.
edit:
For 2. I found a way. I don't know if it is a good one, if it is performant, if the new webview is deleted or is in the cache after download, ....
And the user don't get an feedback, when some a problem is raised:
webView.getEngine().setCreatePopupHandler(new Callback<PopupFeatures, WebEngine>() {
#Override public WebEngine call(PopupFeatures config) {
final WebView downloader = new WebView();
downloader.getEngine().locationProperty().addListener(/* The Listener from above */);
return downloader.getEngine();
}
}
I think you may just need to use copyURLtoFile to get the file...call that when the location changes or just call that using a registered java class. Something like this:
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
Using copyURLToFile the current page doesn't have to serve the file. I think registering the class is probably the easiest way to go... something like this:
PHP Code:
Download $filename
Java (in-line class in your javafx class/window... in this case my javafx window is inside of a jframe):
public class JavaApp {
JFrame cloudFrameREF;
JavaApp(JFrame cloudFrameREF)
{
this.cloudFrameREF = cloudFrameREF;
}
public void getfile(String filename) {
String newLoc = "http://your_web_site.com/send_file.php?filename=" + filename;
org.apache.commons.io.FileUtils.copyURLToFile(new URL(newLoc), new File(System.getProperty("user.home")+filename));
}
}
This part would go in the main javafx class:
Platform.runLater(new Runnable() {
#Override
public void run() {
browser2 = new WebView();
webEngine = browser2.getEngine();
appREF = new JavaApp(cloudFrame);
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
#Override public void changed(ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
JSObject win
= (JSObject) webEngine.executeScript("window");
// this next line registers the JavaApp class with the page... you can then call it from javascript using "app.method_name".
win.setMember("app", appREF);
}
}
});
You may not need the frame reference... I was hacking some of my own code to test this out and the ref was useful for other things...

Android - Back button behavior

I have a project with 2 activities, the first one is the "SplashActivity" - where I load some network data - the second one, the MainActivity.
Inside of my MainActivity I have a fragment and inside of this fragment a webview. My first point is, when the user clicks on back button, the SplashScreen is open again.
The back button should behave like:
When the user doesn't navigate inside of my webview, close the app.
When the user navigates in webview, use the back history of the browswer.
I read about back stack here: http://developer.android.com/training/implementing-navigation/temporal.html#back-webviews
I didn't understand at all how it should work, because I have all cases "mixed". Anyone knows what should I do to fix this problem?
Any idea or sample code will be appreciate!
Define Webview wb as a global variable. Then try this;
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN){
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
if(wb.canGoBack() == true){
wb.goBack();
}else{
new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle("Application will be closed")
.setMessage("Close app?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
System.exit(0);
}
}).setNegativeButton("No", null).show();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}

Resources