在java applet中加载面板的内容

时间:2013-03-12 23:06:31

标签: java swing applet

我正在尝试将面板加载到java applet中,但是面板的内容不会填充。从下面的代码中可以看出,我设置了一个测试,以查看面板中的代码无法运行的位置,我的测试结果表明 getRootPane()。add(MyLabel)是触发异常的代码行。

重新创建此问题所需的所有代码如下所示。任何人都可以告诉我如何更改下面的代码,以便面板的内容加载到applet中?

以下是TestApplet.java的代码:

import javax.swing.JApplet;
import javax.swing.SwingUtilities;

public class TestApplet extends JApplet {

    public void init(){//Called when this applet is loaded into the browser.
        //Execute a job on the event-dispatching thread; creating this applet's GUI.
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    createGUI();
                }
            });
        } catch (Exception e) {
            System.err.println("createGUI didn't complete successfully");
        }
    }
    private void createGUI(){
        TestPanel myPanel = new TestPanel();
        myPanel.setOpaque(true);
        setContentPane(myPanel);
    }
}

以下是TestPanel.java的代码:

import javax.swing.JLabel;
import javax.swing.JPanel;

public class TestPanel extends JPanel{

    TestPanel(){
        System.out.println("Running in constructor.  ");
        JLabel myLabel = new JLabel("Hello World");
        getRootPane().add(myLabel);
        System.out.println("Still running in constructor.  ");
    }
}

修改

根据目前给出的建议,我按如下方式编辑了我的代码。使用this.add会导致JLabel加载,但是,内部类仍未加载,我已将其添加到下面的代码中。此外,下面更改的代码不再触发异常;它只是加载JLabel但不加载内部类。有关如何加载内部类的任何建议?

这是新的TestApplet.java:

import javax.swing.JApplet;
import javax.swing.SwingUtilities;

public class TestApplet extends JApplet {

    public void init(){//Called when this applet is loaded into the browser.
        //Execute a job on the event-dispatching thread; creating this applet's GUI.
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    createGUI();
                }
            });
        } catch (Exception e) {
            System.err.println("createGUI didn't complete successfully");
            System.err.println(e);
            e.printStackTrace();
        }
    }
    private void createGUI(){
        TestPanel myPanel = new TestPanel();
        myPanel.setOpaque(true);
        setContentPane(myPanel);
    }
}  

这是新的TestPanel.java:

import java.awt.Canvas;  
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JLabel;
import javax.swing.JPanel;

public class TestPanel extends JPanel{
    DrawingLines myDrawingLines = new DrawingLines();  

    TestPanel(){
        System.out.println("Running in constructor.  ");
        JLabel myLabel = new JLabel("Hello World");
        this.add(myLabel);
    this.add(myDrawingLines);  
    myDrawingLines.repaint();  
        System.out.println("Still running in constructor.  ");
    }

//inner class to override paint method
class DrawingLines extends Canvas{
   int width, height;

   public void paint( Graphics g ) {
      width = getSize().width;
      height = getSize().height;
      g.setColor( Color.green );
      for ( int i = 0; i < 10; ++i ) {
         g.drawLine( width, height, i * width / 10, 0 );
      }  
      System.out.println("Running in paint method.");  
   }
}//end of inner class   
}  

3 个答案:

答案 0 :(得分:1)

rootpane为null,因为尚未将Jpanel添加到任何组件。并添加到面板rootpane的东西是这样的..非常脏。

答案 1 :(得分:1)

将方法设置为:

 private void createGUI(){
        TestPanel myPanel = new TestPanel();
        getContentPane().add(myPanel);
    }

和TestPanel类

public class TestPanel extends JPanel{
    TestPanel(){
        super();
        System.out.println("Running in constructor.  ");
        JLabel myLabel = new JLabel("Hello World");
        add(myLabel);
        System.out.println("Still running in constructor.  ");
    }
}

答案 2 :(得分:1)

让我们从头开始......

public class TestPanel extends JPanel{
    TestPanel(){
        System.out.println("Running in constructor.  ");
        JLabel myLabel = new JLabel("Hello World");
        getRootPane().add(myLabel);
        System.out.println("Still running in constructor.  ");
    }
}

使用getRootPane向其中添加组件是不对的。您永远不需要向根窗格添加任何内容。相反,你应该使用内容窗格,但这不是你想要做的(或者应该从这个上下文做)。

相反,您只需致电add

public class TestPanel extends JPanel{
    TestPanel(){
        System.out.println("Running in constructor.  ");
        JLabel myLabel = new JLabel("Hello World");
        add(myLabel);
        System.out.println("Still running in constructor.  ");
    }
}

然后,这会将标签添加到TestPane

让我们来看看扩展......

public class TestPanel extends JPanel{
    DrawingLines myDrawingLines = new DrawingLines();  

    TestPanel(){
        System.out.println("Running in constructor.  ");
        JLabel myLabel = new JLabel("Hello World");
        this.add(myLabel);
        this.add(myDrawingLines);  
        myDrawingLines.repaint();  
        System.out.println("Still running in constructor.  ");
    }

    //inner class to override paint method
    class DrawingLines extends Canvas{
       int width, height;

       public void paint( Graphics g ) {
          width = getSize().width;
          height = getSize().height;
          g.setColor( Color.green );
          for ( int i = 0; i < 10; ++i ) {
             g.drawLine( width, height, i * width / 10, 0 );
          }  
          System.out.println("Running in paint method.");  
       }
    }//end of inner class   
}  

首先,你应该避免混合重型和轻量级组件(将Canvas放在JPanel上),这不值得它会造成的挫败感。

无需在构造函数中调用repaint。在调用构造函数时,无论如何都无法绘制组件。

相反,只需覆盖面板的paintComponent方法

即可
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    int width = getWidth;
    int height = getHeight();
    g.setColor( Color.green );
    for ( int i = 0; i < 10; ++i ) {
     g.drawLine( width, height, i * width / 10, 0 );
    }  
}

我强烈建议你看看