1

それで、最近Javaを少しやっていて、ちょっとした問題に遭遇しました。2D 描画をいじって、プロジェクトに画像を追加しました。

問題は、ウィンドウのサイズが変更されると、画像が再描画されて複製されることです。少し回避策を講じましたが、理想的ではありません...では、なぜ画像が複製されるのでしょうか?

前: http://i.imgur.com/PmHRZBQ.png

(ウィンドウのサイズが変更されます)

変更後: http://i.imgur.com/bhsvVZz.png

コード

main.java

import javax.swing.JFrame;


public class main
{
    public static void main(String [] args) throws InterruptedException
    {
        JFrame f = new JFrame("Title");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Canvas testing = new Canvas();

        f.add(testing);
        f.setSize(800, 600);
        f.setVisible(true);
    }
}

キャンバス.java

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Canvas extends JPanel
{
    public void paintComponent (Graphics g)
    {



        super.paintComponent(g);
        this.setBackground(Color.WHITE);

        g.setColor(Color.BLACK);
        g.fillRect(25, 25, 100, 30);

        g.setColor(new Color(190,81,215));
        g.fillRect(25, 68, 10, 10);

        g.setColor(Color.RED);
        g.drawString("Matt is da best", 100, 10);


            try
            {
                BufferedImage image = ImageIO.read(new File("C:/face.png"));
                JLabel picLabel = new JLabel(new ImageIcon(image));
                System.out.println("Added pic");
                add(picLabel);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }       
    }

}
4

2 に答える 2

1

あなたのpaintComponent方法を見てください...

が呼び出されるたびpaintComponentに、新しいものを作成JLabelしてパネルに追加し直しています...

try
{
    BufferedImage image = ImageIO.read(new File("C:/face.png"));
    JLabel picLabel = new JLabel(new ImageIcon(image));
    System.out.println("Added pic");
    add(picLabel);
}
catch (IOException e)
{
    e.printStackTrace();
}       

これにより、別の再描画要求が生成され、同期が最初からやり直されます。

メソッド内からコンポーネントの状態を決して変更しないでpaintください。これは簡単です...あなたの顔を爆破します...

画像をロードし、コンストラクターまたは他のメソッド (paintXxx呼び出さない)内にラベルを追加する必要があります。

Swing での描画について覚えておくべき重要なことは、それを制御することはできないということです。再描画エンジンは、独自のニーズに基づいて、ユーザーの操作の有無にかかわらず、いつでもコンポーネントを更新できます。を呼び出してペイントを奨励することはできますがrepaint、いつ、または何が再ペイントされるかについての保証はありません。

于 2013-05-14T06:56:50.943 に答える
1
  1. paintComponent(Graphics)メソッドで画像を読み込まないでください。クラス属性として宣言し、コンストラクターにロードできます。
  2. paintComponentメソッドにもコンポーネントを追加しないでください。再描画がトリガーされます。

これはより確実に機能するはずです..

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class main
{
    public static void main(String [] args) throws InterruptedException
    {
        JFrame f = new JFrame("Title");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Canvas testing = new Canvas();

        f.add(testing);
        f.setSize(800, 600);
        f.setVisible(true);
    }
}

class Canvas extends JPanel
{

    BufferedImage image;

    Canvas() {
        image = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
        JLabel picLabel = new JLabel(new ImageIcon(image));
        System.out.println("Added pic");
        add(picLabel);
    }

    public void paintComponent (Graphics g)
    {
        super.paintComponent(g);
        this.setBackground(Color.WHITE);

        g.setColor(Color.BLACK);
        g.fillRect(25, 25, 100, 30);

        g.setColor(new Color(190,81,215));
        g.fillRect(25, 68, 10, 10);

        g.setColor(Color.RED);
        g.drawString("Matt is da best", 100, 10);
    }
}

その他のヒント

  • サイズを設定するのではなくCanvas、希望のサイズとフレームを返すようにします。pack()
  • EDT で Swing GUI を開始および更新します。
  • カスタム クラスに J2SE クラスと同じ名前を付けないでください。それは混乱を招く可能性があります。たぶんそれを呼び出しますJCanvas
于 2013-05-14T06:55:03.140 に答える