I have a Java JApplet that functions perfectly when eclipse runs it but dissapoints in a browser.
The applet is working fine in the browser up to the point at which the only JButton is pressed. At which point, something should happen, but, in the browser, nothing happens at all apart from the button shows it has been pressed. This doesn't happen when eclipse runs it.
Here is the code:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JTextArea;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
public class OverviewGenerator extends JApplet {
int state = 0;
JTextArea label = new JTextArea();
JButton button = new JButton();
String pluginYML;
YamlConfiguration yml = new YamlConfiguration();
String page;
public ActionListener buttonListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(state == 0) {
try {
pluginYML = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
} catch (HeadlessException e1) {
e1.printStackTrace();
} catch (UnsupportedFlavorException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
yml.loadFromString(pluginYML);
} catch (InvalidConfigurationException e1) {
e1.printStackTrace();
}
state = 1;
}else {
generatePage();
Toolkit toolkit = Toolkit.getDefaultToolkit();
Clipboard clipboard = toolkit.getSystemClipboard();
StringSelection strSel = new StringSelection(page);
clipboard.setContents(strSel, null);
state = 0;
}
refreshComponents();
}
};
/**
*
*/
private static final long serialVersionUID = 3470279389867972761L;
public void init() {
makeGui();
}
private void makeGui() {
label.setWrapStyleWord(true);
label.setLineWrap(true);
label.setBackground(Color.CYAN);
label.setEditable(false);
GridLayout layout = new GridLayout();
layout.setRows(2);
layout.setColumns(1);
getContentPane().setLayout(layout);
refreshComponents();
getContentPane().add(label);
getContentPane().add(button);
button.addActionListener(buttonListener);
}
private void refreshComponents() {
if(state==0) {
label.setText("Copy your plugin.yml into the clipboard then press done!");
button.setText("Done");
}else if(state == 1) {
label.setText("Now press the button to copy your template BukkitDev overview into your clipboard!");
button.setText("Copy");
}
}
private void generatePage() {
page = "";
page += "== "+yml.getString("name")+" ==\n";
if(yml.contains("description")) {
page += "\n//"+yml.getString("description")+"//\n\n\n";
}
if(yml.contains("commands")) {
page += "== Commands ==\n";
for(String command : yml.getConfigurationSection("commands").getKeys(false)) {
page += "\n=== "+command+" ===\n\n";
if(yml.contains("commands."+command+".description")) {
page += "//"+yml.getString("commands."+command+".description")+"//\n";
}
if(yml.contains("commands."+command+".usage")) {
page += "Usage: "+yml.getString("commands."+command+".usage")+"\n";
}
}
page += "\n";
}
if(yml.contains("permissions")) {
YamlConfiguration editedYml = new YamlConfiguration();
try {
editedYml.loadFromString(pluginYML.replace(".", "≠"));
} catch (InvalidConfigurationException e) {
e.printStackTrace();
}
ConfigurationSection permissions = editedYml.getConfigurationSection("permissions");
page += "== Permissions ==\n";
for(String permission : permissions.getKeys(false)) {
page += "\n=== "+permission.replace('≠', '.')+" ===\n\n";
if(editedYml.contains("permissions."+permission+".description")) {
page += "//"+editedYml.getString("permissions."+permission+".description").replace('≠', '.')+"//\n";
}
}
page += "\n\n\n";
}
page += "//Got any suggestions?//";
}
}
The code above is slightly outdated, I have added in the 'invoke later' code now! I am having trouble showing the Java console but I believe the error may be when the clipboard is accessed.
For security reasons, there are two ways that an applet can access the clip-board.
The applet is digitally signed by the developer, and trusted by the end user.
The applet uses the services of the JNLP API to access the clipboard. That is available in more recent JREs, Sun's 1.6.0_10+, for example.
There is potentially a 3rd way to get data to the applet that involves
having the user paste directly into an HTML form field
then use JS to transfer the data to the applet.
That could be done in a sand-boxed applet, and before the JRE that supports the JNLP API services. OTOH that would mean more clicks for the user, and more setting up.
//Got any suggestions?//
Beyond 'ask a more specific question' I might also suggest:
Enable the Java Console. That information is vital for debugging applets.
Read Copy in sand-boxed app. in 1.6.0_24+ for more details of the problem with clipboard access in applets, and strategies to copy data out of an applet using JS and other techniques.
Oracle released Java 6 Update 24 in February 2011 to remedy 21 vulnerabilities. As part of this security release, the ability to copy & paste from a computer's clipboard into a Java applet has been disabled.
To fix this issue there are 2 solutions:
Create a digital signature for the applet.
Work around: If you do not want to work with the digital signature, add to your java.policy file the following line: permission java.awt.AWTPermission "accessClipboard"
If you want to see an example of Java Applet working with a signed certificate you can looke here (the applet accepts paste action from clipboard which is not allowed to unsigned applets) : http://sqlinform.com/free_online_sw.html
Related
How to debug a JavaFX webview?
I find two ways,
one is to attach external chrome debugger to JavaFX webview.
Another is to inject firebug javascript.
Method#1 seems to use a bit of hacks like set access to private fields etc.
Method#2 depends on firebuglite which seems to be obsolete now.
How should this be done in 2022. Are there any other methods, or better methods?
I am trying firebug lite approach as of now, and have made the javascript part of the maven project and trying to inject it as a string versus an external URL, because firebug seems to be properly public hosted nowhere now.
Refering to https://stackoverflow.com/a/18396900/2448015
This is where I am right now :
package xyz.jphil.internal_browser;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpServer;
import java.net.InetSocketAddress;
import javafx.scene.web.WebEngine;
import netscape.javascript.JSObject;
/**
*
* #author Ivan
*/
public class WebkitDebugUtils {
private static int resourcesPort = 0;
public static void createHttpServerForLocalFiles() {
int portStart = 64321, endPort = 65534;
resourcesPort = portStart + (int) ((endPort * 1d - portStart * 1d) * Math.random());
System.out.println("Starting internal server on " + resourcesPort);
try {
HttpServer server = HttpServer.create(new InetSocketAddress(resourcesPort), 0);
HttpContext context = server.createContext("/");
context.setHandler((req) -> {
try (req) {
var p = req.getRequestURI();
System.out.println("Serving # localhost:"+resourcesPort+" "+p);
var s = WebkitDebugUtils.class.getResourceAsStream(p.toString()).readAllBytes();
req.sendResponseHeaders(200, s.length);
req.getResponseBody().write(s);
}catch(Exception a){
a.printStackTrace();
}
});
server.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static class JavaBridge {
public void log(String text) {
System.out.println(text);
}
}
// Maintain a strong reference to prevent garbage collection:
// https://bugs.openjdk.java.net/browse/JDK-8154127
private final static JavaBridge bridge = new JavaBridge();
public static void enableDebug(final WebEngine e) {
JSObject window = (JSObject) e.executeScript("window");
window.setMember("java", bridge);
e.executeScript("""
console.log = function(message)
{
java.log(message);
};""");
e.executeScript("console.log('console.log enabled');");
}
public static void enableFirebug(final WebEngine e) {
var firebugurl = "http://localhost:"+resourcesPort+"/firebug-lite/firebug-lite.js";
//https://raw.githubusercontent.com/stefanXO/firebug-lite/master/firebug-lite.js
//https://lupatec.eu/getfirebug/firebug-lite-compressed.js
var script= """
console.log("Inside script block");
if (!document.getElementById("FirebugLite")) {
E = document["createElement" + "NS"] && document.documentElement.namespaceURI;
E = E ?
document["createElement" + "NS"](E, "script") :
document["createElement"]("script");
E["setAttribute"]("id", "FirebugLite");
E["setAttribute"]("src", "{$firebugurl}#startOpened");
E["setAttribute"]("FirebugLite", "4");
(
document["getElementsByTagName"]("head")[0]
||
document["getElementsByTagName"]("body")[0]
).appendChild(E);
E = new Image();
E["setAttribute"]("src", "{$firebugurl}#startOpened");
}
console.log("executed script block");
""".replace("{$firebugurl}", firebugurl);
System.out.println("+++firebug thing+++");
System.out.println(script);
System.out.println("---firebug thing---");
e.executeScript(script);
}
}
Main method of the application
//...
public static void main(String[]args){
WebkitDebugUtils.createHttpServerForLocalFiles();
launch(args);
}
//...
In the JavaFx Stage initializing code section
#Override
public void start(final Stage primaryStage) throws Exception {
// ....
wv = new WebView();
// ....
javafx.scene.web.WebEngine e = wv.getEngine();
// ....
e.getLoadWorker().stateProperty().addListener((ov, t, t1) -> WebkitDebugUtils.enableDebug(e));
e.documentProperty().addListener((ov, t, t1) -> WebkitDebugUtils.enableFirebug(e));
// ....
}
I am serving the files for firebug from the resources folder of the jar
Snippter of the custom firebug.js file
console.log("inside firebug-lite");
(function(){
//...
//firebug lite 1.4.0 code
//..
})();
console.log("outside firebug-lite");
Output
Starting internal server on 65148
console.log enabled
console.log enabled
// some application specific output
+++firebug thing+++
if (!document.getElementById("FirebugLite")) {
E = document["createElement" + "NS"] && document.documentElement.namespaceURI;
E = E ?
document["createElement" + "NS"](E, "script") :
document["createElement"]("script");
E["setAttribute"]("id", "FirebugLite");
E["setAttribute"]("src", "http://localhost:65148/firebug-lite/firebug-lite.js#startOpened");
E["setAttribute"]("FirebugLite", "4");
(
document["getElementsByTagName"]("head")[0]
||
document["getElementsByTagName"]("body")[0]
).appendChild(E);
E = new Image();
E["setAttribute"]("src", "http://localhost:65148/firebug-lite/firebug-lite.js#startOpened");
}
---firebug thing---
Inside script block
executed script block
Serving # localhost:65148 /firebug-lite/firebug-lite.js
// some application specific output
console.log enabled
Summary:
nothing is happening, nothing is showing up in the console, I don't know the error, firebug is not even opening.
Update2:
I think I am using the wrong version of firebug 1.5 or something
and the old version I don't see any HTML file and thus it is dependent on the default website which is down at the moment.
You can simply inject firebug-lite after loading your webpage.
I've tested on windows 10 with correto 18.0.2 JDK.
Here's an example: (Page can take some time to load)
package com.example.demo;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.scene.web.WebEngine;
import javafx.concurrent.Worker.State;
public class HelloApplication extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage myStage) {
System.out.println("Demo for firebugLite");
WebView myWebView = new WebView();
myWebView.minHeight(1050);
myWebView.prefWidth(1950);
myWebView.prefHeight(1070);
myWebView.minWidth(1050);
final WebEngine myWebEngine = myWebView.getEngine();
myWebEngine.getLoadWorker().stateProperty()
.addListener((obs, oldValue, newValue) -> {
if (newValue == State.SUCCEEDED) {
System.out.println("finished loading");
myWebEngine.executeScript("var firebug=document.createElement('script');firebug.setAttribute('src','https://lupatec.eu/getfirebug/firebug-lite-compressed.js');document.body.appendChild(firebug);(function(){if(window.firebug.version){firebug.init();}else{setTimeout(arguments.callee);}})();void(firebug);");
}
});
myWebEngine.load("https://lupatec.eu/getfirebug/");
VBox myBox = new VBox(myWebView);
Scene myScene = new Scene(myBox, 1050, 600);
myStage.setScene(myScene);
myStage.show();
}
}
Result:
I am try to open a javadoc html file with my new application, however I can not get the javadoc file to open, I have a class name OpenUri, which when called is supposed to open the javadoc:
package gui;
import java.awt.Desktop;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import javax.swing.JFrame;
public class OpenUri extends JFrame {
public static void openWebpage(URI uri) {
Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
try {
desktop.browse(uri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void openWebpage(URL url) {
try {
openWebpage(url.toURI());
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
I am then calling and using this class from another class called Menu, where the help button has an action listener, etc. However when I run the code and press the help button, no javadoc appears, ie, it doesn't open the document, ie, nothing happens, no window, nothing ?
The only way I can open it is manually, by clicking on it in eclipse, here is the specific code from the Menu class I am Using:
//Help
JMenu helpMenu = new JMenu("Help");
helpMenu.setMnemonic(KeyEvent.VK_H);
helpMenu.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
try {
URI uri = new URI("file:///C:/Users/howhowhows/workspace/OPTICS_DROP_MENU/doc/index.html");
OpenUri.openWebpage(uri);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
});
If anyone has any ideas as to what I am doing wrong, ie what I need to add/change, it would be greatly appreciated.
Have you downloaded and tried the demo code from the Swing tutorial on How to Integrate With the Desktop Class.
When I used that code and pasted your URI into the text field no window is displayed and I get a "System cannot find the file" message as expected.
When I then enter a simple URI that I know exists: "c:/java/a.html" the browser opens as expected.
So I suggest you start with known working code and see if your URI works. If it does work then the problem is your code, so compare the working code to your code to see what the difference is. If it doesn't work then the problem is the URI.
If you still have problems then post a proper SSCCE that demonstrates the problem. Given that your OPenURI class extends JFrame for no reason we don't know what other strange things you might be doing in your code.
I used a screenshot plugin for ios when I developed an iphone/ipad app. I am now creating an android version of the app and am trying to implement the android version of the plugin.
My java part fo the plugin looks like this:
package org.apache.cordova;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import android.graphics.Bitmap;
import android.os.Environment;
import android.view.View;
public class Screenshot extends Plugin {
private PluginResult result = null;
#Override
public PluginResult execute(String action, JSONArray args, String callbackId) {
// starting on ICS, some WebView methods
// can only be called on UI threads
super.cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
View view = webView.getRootView();
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
try {
File folder = new File(Environment.getExternalStorageDirectory(), "Pictures");
if (!folder.exists()) {
folder.mkdirs();
}
File f = new File(folder, "screenshot_" + System.currentTimeMillis() + ".png");
FileOutputStream fos = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
result = new PluginResult(PluginResult.Status.OK);
} catch (IOException e) {
result = new PluginResult(PluginResult.Status.IO_EXCEPTION, e.getMessage());
}
}
});
// waiting ui thread to finish
while (this.result == null) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// ignoring exception, since we have to wait
// ui thread to finish
}
}
return this.result;
}
}
My Screenshot.js looks like this:
(function() {
/* Get local ref to global PhoneGap/Cordova/cordova object for exec function.
- This increases the compatibility of the plugin. */
var cordovaRef = window.PhoneGap || window.Cordova || window.cordova; // old to new fallbacks
/**
* This class exposes the ability to take a Screenshot to JavaScript
*/
function Screenshot() { }
/**
* Save the screenshot to the user's Photo Library
*/
Screenshot.prototype.saveScreenshot = function() {
cordovaRef.exec(null, null, "Screenshot", "saveScreenshot", []);
};
if (!window.plugins) {
window.plugins = {};
}
if (!window.plugins.screenshot) {
window.plugins.screenshot = new Screenshot();
}
})(); /* End of Temporary Scope. */
Now I try to call my screenshot.js function by using this code:
function takeScreenShot() {
cordovaRef.exec("Screenshot.saveScreenshot");
}
However all I get is JSON errors, I know somewhere im asking to to convert it to JSON from a java string but i just can't figure out how to change it. Ok well I think that is what is wrong...
My errors look like this:
ERROR: org.json.JSONException: Value undefined of type java.lang.String cannot be converted to JSONArray.
Error: Status=8 Message=JSON error
file:///android_asset/www/cordova-2.0.0.js: Line 938 : Error: Status=8 Message=JSON error
Error: Status=8 Message=JSON error at file:///android_asset_/www/cordova-2.0.0.js:938
Can anyone guide me where Im going wrong please?
Question resolved by:
Phonegap Screenshot plugin in Cordova 2.0.0
Answer provided by Simon MacDonald.
I'm trying to create a splash screen using LWUIT. I want a form to load and display text and an imagefor 5 seconds then continue to the next form. I have a code but fails to show the image. The class and the image are stored together int he same package. Instead, it shows an error.
java.io.IOException
What could be the problem? This is the code
package tungPackage;
import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.Image;
import com.sun.lwuit.Label;
import javax.microedition.midlet.MIDlet;
public class photoMidlet extends MIDlet {
public void startApp() {
Display.init(this);
try {
Form splashscreen = new Form();
// Label splashText = new Label("Baldy");
Image image = Image.createImage("/splash.png");
Label pictureLabel = new Label(image);
splashscreen.addComponent(pictureLabel);
splashscreen.show();
} catch (Exception ex) {
Form x = new Form("ERROR");
String y = ex.toString();
Label g = new Label(y);
x.addComponent(g);
x.show();
}
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Open your JAR file using a ZIP utility (e.g. 7-zip) and look in the root of the file. If splash.png isn't in the root of the jar that's your problem!
Place splash.png so it is in the root of the jar.
import java.awt.*;
import java.applet.*;
import java.net.*;
/*<applet code=CodeBase width=300 height=300>
</applet>*/
public class CodeBase extends Applet
{
String sn,br;
URL url;
public void start()
{
AppletContext ac=getAppletContext();
url=getCodeBase();
try{
ac.showDocument(new URL(url+"a.html"));
System.out.println("Hello");
// ac.showDocument(new URL("D:Java Programs//Applet//a.html"));
}
catch(MalformedURLException e)
{
showStatus("Url not found");
}
}
}
This code does not show the document of the a.html in applet. When we use AppletContext.showDocument() method then it display the document at the specified URL, but it not worked.
As a first suggestion, change:
ac.showDocument(new URL(url+"a.html"));
To:
ac.showDocument(new URL(url,"a.html"));
But even better, add some sanity checking to the before/after. Something like:
URL urlPlus = new URL(url+"a.html");
System.out.println(urlPlus);
URL urlComma = new URL(url,"a.html");
System.out.println(urlComma);
// ...
That last part is what I refer to as 'sanity check debugging'. It is easier to inspect with an IDE that has a debugger, but failing that use the principle "When in doubt, print out!"