我们可以在applet窗口或Swing窗口中运行Java程序吗?我们如何才能看到已编译程序的输出?
答案 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
。
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文件。