-2

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

4

4 回答 4

3

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

您可以 exec() 新进程(如果它有一个 main() 入口)点,或者使用类加载将其加载到您的 JVM 中。请注意,如果您参加后一门课程,您可能每次都必须实例化一个新的类加载器 - 请参阅此处了解更多详细信息。

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

于 2012-10-18T10:06:22.957 回答
2

Re. JavaCompiler API & Applet or Swing launched with JWS.

To compile source supplied in a text area, or by URL from the code-base would not require trust. OTOH the JavaCompiler is only available if the code is running in the JVM of a JDK (it requires the tools.jar to be on the run-time class-path). Applets and JWS based apps. are never run using a JDK and never have the tools.jar available.

See also

Example code

To avoid 'link rot', here is the code seen in that linked thread.

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;
  }
}
于 2012-10-18T11:03:30.613 回答
0

使用Java Compiler API将源代码转换为字节码。之后使用动态类加载将编译后的字节码加载到 jvm 并启动它(以获取输出)。
此外,如果您想从 java 小程序内部执行此操作,则必须解决安全问题。

于 2012-10-18T10:11:09.767 回答
0

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

于 2012-10-18T10:12:27.283 回答