Hoolean
Hoolean

Reputation: 29

JApplet lacking full functionality in browser

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.

Upvotes: 1

Views: 143

Answers (2)

Guido
Guido

Reputation: 958

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:

  1. Create a digital signature for the applet.
  2. 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

Upvotes: 0

Andrew Thompson
Andrew Thompson

Reputation: 168825

For security reasons, there are two ways that an applet can access the clip-board.

  1. The applet is digitally signed by the developer, and trusted by the end user.
  2. 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.

Upvotes: 1

Related Questions