Java 为什么invokeAndWait()更适合小程序而不是独立应用程序?
java文档说: 在小程序中,必须使用invokeAndWait()从init()方法启动GUI创建任务;否则,init()可能会在创建GUI之前返回,这可能会导致web浏览器启动小程序时出现问题 如果Java 为什么invokeAndWait()更适合小程序而不是独立应用程序?,java,swing,applet,invokelater,invokeandwait,Java,Swing,Applet,Invokelater,Invokeandwait,java文档说: 在小程序中,必须使用invokeAndWait()从init()方法启动GUI创建任务;否则,init()可能会在创建GUI之前返回,这可能会导致web浏览器启动小程序时出现问题 如果init()在创建GUI之前返回,会有什么问题?浏览器可能会出现什么样的问题 文件还说: 在任何其他类型的程序中,调度GUI创建任务通常是初始线程做的最后一件事,因此不管它使用invokeLater()还是invokeAndWait() GUI创建任务作为最后一件事是如何改变任何事情的?此外,它还
init()
在创建GUI之前返回,会有什么问题?浏览器可能会出现什么样的问题
文件还说:
在任何其他类型的程序中,调度GUI创建任务通常是初始线程做的最后一件事,因此不管它使用invokeLater()还是invokeAndWait()
GUI创建任务作为最后一件事是如何改变任何事情的?此外,它还提到了通常的实践,如果GUI创建不是初始线程完成的最后一个任务,那么使用invokeAndWait()
还是invokeLater()
我想我明白他们想说什么,但我仍然想确定,因此,我发布了这个问题。
提前谢谢
如果init()
在创建GUI之前返回,会有什么问题?浏览器可能会出现什么样的问题
我主要关心的是在组件创建结束之前调用start()
方法。如果在start方法中引用组件,这将导致出现NullPointerException
…独立程序就不能发生同样的事情吗
桌面应用程序没有
start()
方法。该方法是的一部分,但不是应用程序的一部分。我将通过一个示例告诉您我的经验-假设我们有一个小程序(扩展JApplet),带有一个JMenuBar,有两个构造函数(一个调用super(),另一个调用this(),并根据其参数设置一个框架)。我们在类中还有一个main方法(applet不需要)
现在,invokeAndWait()机制(如教程中所述)可以作为小程序正常工作,因为小程序UI由单独的线程控制。作为一个应用程序运行,当我们调用System.exit()方法时,我们将遇到异常,因为当UI线程想要退出时,主线程将尝试挂起变量。如果我们从cmd/shell启动应用程序,读取这些JVM错误是很烦人的。这可能是不建议将其用于应用程序的一个原因。请查看以下代码-它既可以作为小程序也可以作为应用程序使用。方法init1()和init2()创建相同的UI。两者都有效。init2()创建一个单独的事件调度线程,不与浏览器中的任何其他线程竞争,建议用于小程序。但是,当单击“退出”按钮作为独立应用程序运行时,这会导致偶尔出现异常。这就是为什么建议应用程序使用init1()。无论如何,这是我的理解,我可能错了。但这种解释/理由现在有意义吗
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class P4 extends JApplet implements ActionListener {
private Frame frame; // null/applet, non-null/application
public P4 () { super(); }
public P4 (Frame f) { this(); frame = f; }
public void init () {
// init1(); // better for application
init2(); // better for applets
}
public void init1 () {
createGUI();
}
public void init2 () {
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception ex) {
ex.printStackTrace();
}}
private void createGUI () {
JPanel p = new JPanel();
JButton b = new JButton ("Click to say Hello to the world");
b.addActionListener (this);
p.add (b);
if (frame != null) { // application
b = new JButton ("Exit");
b.addActionListener (this);
p.add (b);
p.setPreferredSize (new Dimension (400, 50));
}
getContentPane().add(p);
}
public void actionPerformed (ActionEvent e) {
if ("Exit".equals (e.getActionCommand()))
System.exit (0);
JOptionPane.showMessageDialog (frame, "Hello, world!");
}
public void start () { }
public void stop () { }
public void paint (Graphics g) {
super.paint (g);
}
public static void main (String[] args) {
JFrame fr = new JFrame ("Appletication");
P4 p4 = new P4 (fr);
p4.init(); // initialize GUI
fr.add (p4); fr.pack(); fr.setVisible (true);
}}
@所以我加入了一个非空的start()方法,并添加了一个生成旋转正方形的JPanel(使用从start()开始的线程设置动画)。我仍然发现init1()和init2()的行为完全相同。请向OP(和我自己)解释一下,为什么在本例中您更喜欢调用EANDWAIT() @安德鲁:我明白我对上面的回答不正确。请详细说明我为什么不对,以及正确答案是什么。我试着跟随你的答案,找到了一个断开的链接 这是一个可编译的应用程序(是的,通常我会把它分为3个不同的类,但这里我们试图回答一个特定的问题)
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
公共类P4扩展JApplet实现ActionListener{
私有帧帧;//null/applet,非null/application
私人画家=新画家();
公共P4(){super();}
公共P4(帧f){this();帧=f;}
公共void init(){
//init1();//更适合应用程序
init2();//更适合小程序
}
公共void init1(){
createGUI();
}
公共void init2(){
试一试{
javax.swing.SwingUtilities.invokeAndWait(new Runnable()){
公开募捐{
createGUI();
}
});
}捕获(例外情况除外){
例如printStackTrace();
}}
私有void createGUI(){
JPanel p=newjpanel(newborderlayout());
JButton b=新JButton(“点击向世界问好”);
b、 addActionListener(此);
p、 加(b)“南方”);
p、 添加(油漆工,“中心”);
如果(frame!=null){//应用程序
b=新的按钮(“退出”);
b、 addActionListener(此);
p、 加上(b)“北部”);
}
getContentPane().add(p);
}
已执行的公共无效操作(操作事件e){
如果(“Exit”.equals(例如getActionCommand()))
系统出口(0);
JOptionPane.showMessageDialog(框架“你好,世界!”);
}
public void start(){new Thread(painter).start();}
公共无效停止(){}
公共空间绘制(图形g){
超级油漆(g);
}
公共静态void main(字符串[]args){
JFrame fr=新JFrame(“应用”);
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class P4 extends JApplet implements ActionListener {
private Frame frame; // null/applet, non-null/application
private Painter painter = new Painter();
public P4 () { super(); }
public P4 (Frame f) { this(); frame = f; }
public void init () {
// init1(); // better for application
init2(); // better for applets
}
public void init1 () {
createGUI();
}
public void init2 () {
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception ex) {
ex.printStackTrace();
}}
private void createGUI () {
JPanel p = new JPanel(new BorderLayout());
JButton b = new JButton ("Click to say Hello to the world");
b.addActionListener (this);
p.add (b, "South");
p.add (painter, "Center");
if (frame != null) { // application
b = new JButton ("Exit");
b.addActionListener (this);
p.add (b, "North");
}
getContentPane().add(p);
}
public void actionPerformed (ActionEvent e) {
if ("Exit".equals (e.getActionCommand()))
System.exit (0);
JOptionPane.showMessageDialog (frame, "Hello, world!");
}
public void start () { new Thread (painter).start(); }
public void stop () { }
public void paint (Graphics g) {
super.paint (g);
}
public static void main (String[] args) {
JFrame fr = new JFrame ("Appletication");
P4 p4 = new P4 (fr);
p4.init(); p4.start(); // initialize GUI
fr.add (p4); fr.pack(); fr.setVisible (true);
}
public class Painter extends JPanel implements Runnable {
private int state, px[] = new int[4], py[] = new int[4];
public Painter () {
super();
setPreferredSize (new Dimension (300, 200));
}
public void run () {
for ( ; ; ) {
if (++state == 45)
state = 0;
repaint();
try {
Thread.sleep (25);
} catch (InterruptedException ex) {
}}}
public void paint (Graphics g) {
int w = getWidth(), h = getHeight(),
cx = w/2, cy = h/2, halfD = (cx < cy) ? cx : cy;
halfD -= 10;
Graphics2D g2 = (Graphics2D) g;
g2.setPaint (Color.white); g2.fillRect (0,0,w,h);
for (int i = 0 ; i < 4 ; i++) {
double theta = (i*90 + 2*state) * Math.PI / 180;
px[i] = (int) Math.round (cx + halfD * Math.cos (theta));
py[i] = (int) Math.round (cy - halfD * Math.sin (theta));
}
g2.setPaint (Color.red);
g2.fillPolygon (px, py, 4);
}}}