1

SWING を使用して GUI を設計しようとしています。私の問題は、paintComponent メソッドがどのように機能するかがわからないことです。2 つの画像を表示しようとしていますが、PanClass の画像のみが表示されます。関連するコード (2 クラス) は次のとおりです。

import javax.swing.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.Image;

public class LP3 extends JPanel
{
    public static BufferedImage image;
    public static BufferedImage image2;
    private JFrame frame=new JFrame();
    private PanClass Panel=new PanClass();

    public LP3()
    {
        try
        {               
            image2=ImageIO.read(new File("New Game.png"));     
        }
        catch (IOException e)
        {
            //Nothing
        }
        frame.setSize(1000,100);
        frame.setResizable(true);
        frame.add(Panel);
        Panel.setOpaque(true);
        frame.pack();
        frame.setVisible(true);     
    }

    public void paintComponent(Graphics g)
    {
        g.drawImage(image2,0,0,null);
    }
}

クラス No2:

import javax.swing.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.Image;

public class PanClass extends JPanel
{
    private static BufferedImage theimage;
    private static BufferedImage image2;
    private JPanel a=new JPanel();

    public PanClass()
    {
        a.setLayout(null);
        a.setOpaque(true);
        try
        {                 
            theimage = ImageIO.read(new File(design4.jpg"));
        }
        catch (IOException e)
        {
            //Not handled.
        }
    }

    public void paintComponent(Graphics g)
    {
        g.drawImage(theimage,0,0,null);
    }
}

このままのコードでは、PanClass からの画像のみが表示されます。PanClass で実行される両方の画像の描画を追加すると、両方が正しく描画されます。仕事を成し遂げることよりも、それがどのように機能するかを学ぶことに興味があるので、なぜこれが起こるのかを知ることに興味があります. また、クラスに JFrame と JLayered ペインを作成する場合は、paintComponent() で画像を描画するクラスをさらに 2 つ作成し (上記と同様のコードを使用)、別のレイヤーのレイヤード ペインに各クラスのインスタンスを追加します。最初のクラスの、なぜ何も表示されないのですか?

(私のメイン メソッドは LP3 にあるはずですが、学習に使用されるメイン メソッドがなくても、インスタンスで直接メソッドを呼び出すことができる IDE を使用しているだけです)

4

2 に答える 2

3

に LP3 を追加していませんが、追加しJFrameただけPanClass です。したがって、は呼び出されませLP3paintComponent()

LayoutManager両方のコンポーネントを追加して(たとえば適切に定義することができますGridLayout)、両方を呼び出すことができますpaintComponent()

于 2013-06-24T13:54:55.480 に答える
1

プログラムで間違っている点:

  • コードで使用される命名規則は、Java を意味するものではありません。詳細については、 Java 命名規則を参照してください。2 つの簡単な方法として、クラス名に Pascal 表記法を使用し、変数名に Camel 表記法を使用します。
  • スーパークラスのメソッドをオーバーライドする必要があるときはいつでも、 ACCESS SPECIFIER可能な限り同じに保つのが最善です。あなたの場合、paintComponent(...)メソッドのアクセス指定子はありません。protectedpublic
  • 特に をオーバーライドpaintComponent(...)している間は、オーバーライドsuper.paintComponent(...)されたメソッドでを呼び出すのが最適です。
  • PanClassyour which extendsの内部でJPanelは、新しいJPanel aを作成しています。これは、よく見ると、必要なものではありません。あなたはPanClassそれ自体が欲しい。
  • のgetPreferredSize()を、JPanel/JComponent任意のクラスに拡張するときはいつでもオーバーライドする習慣をつけてください。
  • JFrameX ボタンが押されたときにどのように動作する必要があるかを常に定義します。詳細情報JFrame.setDefaultCloseOperation(...)
  • スーパークラスのメソッドをオーバーライドするときはいつでも、注釈を前に付けるのが最善です。Java アノテーション チュートリアルの詳細
  • Swing の Concurrency に関連する小さな情報に言及する価値があることを願っています:-)
  • 最後になりましたが、答えは@StanislavLによって非常に多く提供されています

詳細については、次のコードを検討してください。

import javax.swing.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.Image;
import java.net.URL;

public class LP3 extends JPanel
{
    public static BufferedImage image;
    public static BufferedImage image2;
    private JFrame frame = new JFrame();
    private PanClass panel = new PanClass();

    public LP3()
    {
        setOpaque(true);
        try
        {               
            image2=ImageIO.read(new URL(
                "https://encrypted-tbn1.gstatic.com/images?q=tbn:" + 
                "ANd9GcQCluuYpyVQYZuADHAYIfpkRO7SaWMn0OCM_nGH6Tr2SCFtGtE_"));     
        }
        catch (IOException e)
        {
            //Nothing
            e.printStackTrace();
        }           
    }

    @Override
    public Dimension getPreferredSize()
    {
        return (new Dimension(300, 300));
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(image2,0,0,this);
    }

    private void displayGUI()
    {
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setResizable(true);
        JPanel contentPane = new JPanel();
        contentPane.setLayout(new GridLayout(0, 1, 5, 5));
        contentPane.add(panel);
        contentPane.add(this);
        frame.setContentPane(contentPane);
        frame.pack();
        frame.setVisible(true); 
    }

    public static void main(String[] args)
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                new LP3().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

class PanClass extends JPanel
{
    private static BufferedImage theimage;
    private static BufferedImage image2;

    public PanClass()
    {
        setOpaque(true);
        try
        {                 
            theimage = ImageIO.read(
                new URL(
                    "https://encrypted-tbn0.gstatic.com/" + 
                    "images?q=tbn:ANd9GcR5PNwAcLVjphhST_" + 
                    "S-K_dU0CEAuXM0g4oc1-v1r-z5VJFuemOD"));
        }
        catch (IOException e)
        {
            //Not handled.
            e.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize()
    {
        return (new Dimension(300, 300));
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(theimage, 0, 0, this);
    }
}

編集 : !

  • ImageObserver部分にg.draw(...)使用nullしている の使用に関して、前回、非常に重要な点を 1 つ忘れていました。JPanelnull
于 2013-06-24T16:44:05.590 に答える