3

こんにちは、ググったのですが、私の paintComp メソッドが呼び出されない理由がわかりません

次のコード パッケージ com.vf.zepto.view があります。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import com.vf.zepto.view.interfaces.ProcessorPanel;

public class CountryDetailsPanel extends JPanel implements ProcessorPanel, Runnable {
    private GridBagConstraints c = new GridBagConstraints();
    private String countryName;
    private Properties prop = new Properties();
    private BufferedImage image;

    public CountryDetailsPanel() {
        try {
            prop.load(new FileInputStream("country.props"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //this.setLayout(new GridBagLayout());

        c.gridx = 0;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(5, 5, 5, 5);

        this.setPreferredSize(new Dimension(200, 200));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        try {
            if(countryName != null) {
                String asset = prop.getProperty(countryName+".flag");

                if(!asset.equals(null)) {
                    image = ImageIO.read(new File(asset));
                    g.drawImage(image, 0, 0, null);
                }
            }
        } 
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateDetails(Object o) {
        countryName = (String)o;
        SwingUtilities.invokeLater(this);
    }

    @Override
    public void run() {
        this.repaint();
    }
}

そして、呼び出すときにメソッドが呼び出されることをthis.repaint()期待paintComponentしますが、愛やお金のためにはそうではありません。

問題だったがそうではない場合に備えて、EDTを使用するように強制しようとしました。

何か案は?

4

2 に答える 2

5
  • コンポーネントを変更するためにすべてのリクエストを統合paintComponent()するメソッドを決して呼び出さないでください(画面の更新の間にいくつかの再描画リクエストが発生する場合があります)。repaint()更新が他の GUI アクションと適切に調整されるように、更新要求を GUI イベント キューに追加します (Swing と AWT はスレッドセーフではありません)。この更新リクエストは、処理されるupdate()paint()、 を呼び出します。これは を呼び出します。paintComponent()

  • なぜこれがあるのですか:

    @Override
    public void run() {
        this.repaint();
       }
    

それは何の役にも立たないようです(一度再描画するために新しいスレッドを作成しますか?言うまでもなく、スレッドはEDTではなくインスタンスを呼び出します(それ以外の外部で変更された場合は心配する必要さえありません)。ただし、変更したスレッドを開始するにrepaint()JPanelUI コンポーネントは s SwingTimer/ SwingWorkerorを使用しますSwingUtilities#invokeXXX()

  • これは関係ないかもしれませんが、あなたのコードでは次のように表示されます:

            if(!asset.equals(null)) {
                image = ImageIO.read(new File(asset));
                g.drawImage(image, 0, 0, null);
            }
    

equals()値と比較するために使用しないでください。これは、null ポインターを参照しようとしているために をnullスローする可能性があるためです。たとえば、このコードは をスローします。NullPointerExceptionNPE

    String s=null;
    if(!s.equals(null)) {//throws NPE
        System.out.println("Here");//is never printed
    }
  • また、mKorbelが言ったように(彼に+1)paintComponent()、グローバルに宣言して長時間実行されるタスクを実行しないでください。Imageコンストラクターで割り当ててからpaintComponent(). フィ

むしろ行う:

public class TestPanel extends JPanel {

private Image image;

public TestPanel() {
image = ImageIO.read(new File(asset));
}

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
                if(asset!=null) {
                    g.drawImage(image, 0, 0, null);
                }
    }
}
于 2012-10-02T14:35:34.190 に答える
5
  1. 画像やその他のハードまたは長時間実行されるコードをロードしないでくださいpaintComponent

  2. Objectこれをローカル変数としてロードし、一度だけ

  3. paintComponent()と呼ばれる

    • 暗黙的に、JComponent再描画が必要な場合、または

    • paintComponent()から呼び出す場合は、マウスイベントごとに明示的にMouseMotionListener

  4. アニメーションがある場合は、Swing Timer を使用して を呼び出しますrepaint()

于 2012-10-02T14:33:10.937 に答える