我们可以在applet或Swing窗口中编译Java程序吗?

时间:2012-10-18 10:05:17

标签: java swing compilation applet

我们可以在applet窗口或Swing窗口中运行Java程序吗?我们如何才能看到已编译程序的输出?

4 个答案:

答案 0 :(得分:3)

您可以使用Compiler API(在Java 6中提供)来编译源代码。

您可以执行exec()新进程(如果它有一个main()条目),或使用类加载将其加载到JVM中。请注意,如果您选择后一种课程,则每次都可能需要实例化一个新的类加载器 - 有关详细信息,请参阅here

您可能有安全问题。从applet访问文件系统。因此,可能只使用标准的Swing应用程序(可能使用Java Web Start加载?)

答案 1 :(得分:2)

重新。 JavaCompiler API&使用JWS启动Applet或Swing。

编译文本区域中提供的源代码或来自代码库的URL不需要信任。 OTOH JavaCompiler仅在代码在JDK的JVM中运行时才可用(它要求tools.jar位于运行时类路径上)。基于Applet和JWS的应用程序。永远不会使用JDK运行,永远不会有tools.jar

另见

示例代码

为了避免链接腐败,这里是在该链接线程中看到的代码。

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.EventQueue;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;

import java.util.ArrayList;

import java.net.URI;

import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;

import javax.tools.ToolProvider;
import javax.tools.JavaCompiler;
import javax.tools.SimpleJavaFileObject;

/** A simple Java compiler with a GUI.  Java 1.6+.
@author Andrew Thompson
@version 2008-06-13
*/
public class GuiCompiler extends JPanel {

  /** Instance of the compiler used for all compilations. */
  JavaCompiler compiler;

  /** The name of the public class.  For 'HelloWorld.java',
  this would be 'HelloWorld'. */
  JTextField name;
  /** The source code to be compiled. */
  JTextArea sourceCode;
  /** Errors and messages from the compiler. */
  JTextArea output;

  JButton compile;

  static int pad = 5;

  GuiCompiler() {
    super( new BorderLayout(pad,pad) );
    setBorder( new EmptyBorder(7,4,7,4) );
  }

  /** A worker to perform each compilation. Disables
  the GUI input elements during the work. */
  class SourceCompilation extends SwingWorker<String, Object> {
    @Override
    public String doInBackground() {
      return compileCode();
    }

    @Override
    protected void done() {
      try {
        enableComponents(true);
      } catch (Exception ignore) {
      }
    }
  }

  /** Construct the GUI. */
  public void initGui() {
    JPanel input = new JPanel( new BorderLayout(pad,pad) );
    Font outputFont = new Font("Monospaced",Font.PLAIN,12);

    sourceCode = new JTextArea("Paste code here..", 15, 60);
    sourceCode.setFont( outputFont );
    input.add( new JScrollPane( sourceCode ),
      BorderLayout.CENTER );
    sourceCode.select(0,sourceCode.getText().length());

    JPanel namePanel = new JPanel(new BorderLayout(pad,pad));
    name = new JTextField(15);
    name.setToolTipText("Name of the public class");
    namePanel.add( name, BorderLayout.CENTER );
    namePanel.add( new JLabel("Class name"), BorderLayout.WEST );

    input.add( namePanel, BorderLayout.NORTH );

    compile = new JButton( "Compile" );
    compile.addActionListener( new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
          (new SourceCompilation()).execute();
        }
      } );
    input.add( compile, BorderLayout.SOUTH );

    this.add( input, BorderLayout.CENTER );

    output = new JTextArea("", 5, 40);
    output.setFont( outputFont );
    output.setEditable(false);
    this.add( new JScrollPane( output ), BorderLayout.SOUTH );
  }

  /** Compile the code in the source input area. */
  public String compileCode() {
    output.setText( "Compiling.." );
    enableComponents(false);
    String compResult = null;
    if (compiler==null) {
      compiler = ToolProvider.getSystemJavaCompiler();
    }
    if ( compiler!=null ) {
      String code = sourceCode.getText();
      String sourceName = name.getText().trim();
      if ( sourceName.toLowerCase().endsWith(".java") ) {
        sourceName = sourceName.substring(
          0,sourceName.length()-5 );
      }
      JavaSourceFromString javaString = new JavaSourceFromString(
        sourceName,
        code);
      ArrayList<JavaSourceFromString> al =
        new ArrayList<JavaSourceFromString>();
      al.add( javaString );

      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      OutputStreamWriter osw = new OutputStreamWriter( baos );

      JavaCompiler.CompilationTask task = compiler.getTask(
        osw,
        null,
        null,
        null,
        null,
        al);

      boolean success = task.call();

      output.setText( baos.toString().replaceAll("\t", "  ") );
      compResult = "Compiled without errors: " + success;
      output.append( compResult );
      output.setCaretPosition(0);
    } else {
      output.setText( "No compilation possible - sorry!" );
      JOptionPane.showMessageDialog(this,
        "No compiler is available to this runtime!",
        "Compiler not found",
        JOptionPane.ERROR_MESSAGE
        );
      System.exit(-1);
    }
    return compResult;
  }

  /** Set the main GUI input components enabled
  according to the enable flag. */
  public void enableComponents(boolean enable) {
    compile.setEnabled(enable);
    name.setEnabled(enable);
    sourceCode.setEnabled(enable);
  }

  public static void main(String[] args) throws Exception {

    Runnable r = new Runnable() {
      public void run() {
        JFrame f = new JFrame("SSCCE text based compiler");
        f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        GuiCompiler compilerPane = new GuiCompiler();
        compilerPane.initGui();

        f.getContentPane().add(compilerPane);

        f.pack();
        f.setMinimumSize( f.getSize() );
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    };
    EventQueue.invokeLater(r);
  }
}

/**
* A file object used to represent source coming from a string.
* This example is from the JavaDocs for JavaCompiler.
*/
class JavaSourceFromString extends SimpleJavaFileObject {
  /**
  * The source code of this "file".
  */
  final String code;

  /**
  * Constructs a new JavaSourceFromString.
  * @param name the name of the compilation unit represented
    by this file object
  * @param code the source code for the compilation unit
    represented by this file object
  */
  JavaSourceFromString(String name, String code) {
    super(URI.create(
      "string:///" +
      name.replace('.','/') +
      Kind.SOURCE.extension),
      Kind.SOURCE);
    this.code = code;
  }

  @Override
  public CharSequence getCharContent(boolean ignoreEncodingErrors) {
    return code;
  }
}

答案 2 :(得分:0)

使用Java Compiler API将源代码翻译成字节码。之后使用dynamic class loading将已编译的字节码加载到jvm并启动它(以获得输出)。
另外,如果你想从java applet中做到这一点,你将不得不解决安全问题。

答案 3 :(得分:0)

好applet是在后台运行的程序。为了编译java程序,你需要访问客户端的本地磁盘IS NOT ALLOWED用于applet(据我所知)由于安全原因。 你想要实现什么目标?我曾经尝试使用applet访问img文件。