0

我正在尝试将面板加载到 java 小程序中,但面板的内容没有填充。从下面的代码中可以看到,我设置了一个测试,看看面板中的代码在哪里运行失败,我的测试结果表明getRootPane().add(MyLabel)是触发的代码行例外。

重新创建此问题所需的所有代码都包含在下面。谁能告诉我如何更改下面的代码,以便将面板的内容加载到小程序中?

下面是 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   
}  
4

3 回答 3

1

rootpane 为空,因为 Jpanel 尚未添加到任何组件。像这样在面板根窗格中添加东西是..很脏。

于 2013-03-12T23:15:39.297 回答
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.  ");
    }
}
于 2013-03-12T23:47:35.220 回答
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   
}  

首先,您应该避免混合使用重型和轻型组件(将 aCanvas放在a 上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 );
    }  
}

我强烈建议你看看

于 2013-03-13T02:02:58.693 回答