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

最初から始めましょう...

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 );
    }  
}

ぜひご覧になることをお勧めします

于 2013-03-13T02:02:58.693 に答える
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

Jpanel はまだどのコンポーネントにも追加されていないため、ルートペインは null です。そして、そのようなパネルのルートペインに何かを追加するのは..かなり汚いです。

于 2013-03-12T23:15:39.297 に答える