2012-05-10 10 views
2

jPanelに1つの問題があります。 文字列入力(数式)からPNG画像を取得し、jPanelで古い画像を再描画するボタンがあります。そしてそこに問題が起こります。画像が変更されましたが、jPanelは手動でアプリウィンドウのサイズを変更するまで再描画しません。アプリケーションウィンドウのサイズを変更するまでjPanelがリフレッシュされない

サイズ変更するまでパネルを再描画しないように見えます。しかし、私はどのようにそのボタンでそれを行うか分かりません。

私はthisthisを試しましたが、変更はありませんでした。

btw。私はnetbeansでGUIビルダーを使用しています。

私のコード...最初の試み:

public class ImagePanel extends JPanel { 

    private String path; 
    Image img; 
    public ImagePanel() { 
     try { 
      //save path 
      path = "Example5.png"; 
      //load image 
      img = ImageIO.read(new File(path)); 
     } catch (IOException ex) { 
     } 
    } 
    @Override 
    public void paint(Graphics g) { 
     //draw the image 
     if (show) { 
     try { 
      if (img != null) { 
       img = ImageIO.read(new File(path)); 
       g.drawImage(img, 0, 0, this); 
      } 
     } catch (IOException ex) { 
     } 
    } else { 
     show = true; 
    } 
    } 
} 

とWindowクラスで/ボタン方式:

imagePanel = new ImagePanel(); 
    imagePanel.repaint(); 
    imagePanel.updateUI(); 

第二の試み:

public class ImagePanel extends JPanel { 

    private String path; 
    Image img; 
    ImagePanel(Image img) { 
     this.img = img; 
    } 

    public void setImg(Image img) { 
     this.img = img; 
    } 

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

     // Draw image centered in the middle of the panel 
     g.drawImage(img, 0, 0, this); 
    } 

} 

とボタン:

imagePanel.setImg(new ImageIcon("2.png").getImage()); 
imagePanel.repaint(); 
+1

ウィンドウを開くときにパネルが描かれますしていますか?それとも完全に見えないのですか?レイアウトマネージャが境界をまだ計算していない場合、パネルのサイズは0/0です。 – Thomas

+0

画像を追加するときにjPanelが無効になっているかどうか確認できますか?サイズを変更するとvalidateTreeが呼び出され、レイアウトマネージャはその子を検証します – maress

+0

呼び出しrevalidate(); repaint();の前に? – StanislavL

答えて

4

これは、バックラウンドの再描画スレッドで処理できます。これをJPanelサブクラスのコンストラクタに配置することができます。

Thread repainter = new Thread(new Runnable() { 
    @Override 
    public void run() { 
     while (true) { // I recommend setting a condition for your panel being open/visible 
      repaint(); 
      try { 
       Thread.sleep(30); 
      } catch (InterruptedException ignored) { 
      } 
     } 
    } 
}); 
repainter.setName("Panel repaint"); 
repainter.setPriority(Thread.MIN_PRIORITY); 
repainter.start(); 
+0

これはほぼ完全に動作します。イメージは再描画されますが、ウィンドウのサイズを変更するまでは、古いものがバックラウンドに残ります。 – cMe

+0

nIce cOwが投稿されたので、パネルの 'paint'メソッドをオーバーライドしないでください。コンポーネントのペイントコードを 'paint'から' paintComponent'に移動する必要があります。 – Vulcan

+0

それは生きている!大変、ありがとう。私はjdocで 'paintComponent()'をオーバーライドするほうがよいと読んでいましたが、私はそれがこの大きな問題ではないと考えました。 – cMe

5

あなたのpaintComponent(...)メソッドをオーバーライドしようとし、可能な限りスイングであるため、実際にどのような方法で良い戦略ではありません、あなたのpaint(...)方法を、上書きされます。また、私はあなたが、あなたのこの更新されたコードにSwingUtilities.invokeLater(...) method.Tryあなたの手の内側にあなたのコードを入れて(画像フォルダ内)あなたの.classファイルと一緒に画像に場所を行うために見逃している可能性がありますので、構造は次のようになり、

PanelTest.class  ImagePanel.class  image(Folder) 
              |  |  | 
             image1 image2 image3(and so on) 
推測します

================================ ====================================

import java.awt.*; 
import java.awt.event.*; 
import java.net.URL; 
import javax.swing.*; 

public class PanelTest 
{ 
    private URL[] url = new URL[5]; 
    private int counter = 0; 
    private ImageIcon image; 
    private JButton updateButton; 

    public PanelTest() 
    { 
     try 
     { 
      for (int i = 0; i < 5; i++) 
      { 
       url[i] = getClass().getResource("/image/geek" + i + ".gif"); 
      } 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    private void createAndDisplayGUI() 
    { 
     JFrame frame = new JFrame("Panel Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     image = new ImageIcon(url[0]); 
     final ImagePanel ip = new ImagePanel(image.getImage()); 
     updateButton = new JButton("UPDATE"); 
     updateButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
       counter++; 
       if (counter < 5) 
       { 
        image = new ImageIcon(url[counter]); 
        ip.setImg(image.getImage()); 
       } 
       else 
        counter = -1; 
      } 
     }); 

     frame.getContentPane().add(ip, BorderLayout.CENTER); 
     frame.getContentPane().add(updateButton, BorderLayout.PAGE_END); 

     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String... args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new PanelTest().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 
class ImagePanel extends JPanel { 

    private String path; 
    private Image img; 
    ImagePanel(Image img) { 
     this.img = img; 
    } 

    public void setImg(Image img) { 
     this.img = img; 
     // Added by me, so as to update the image 
     // as a new Image is made available. 
     repaint(); 
    } 

    /* 
    * Added by me, make this a customary 
    * habbit to override this method too 
    * as you override paintComponent(...) 
    * method of the said JComponent. 
    */ 
    @Override 
    public Dimension getPreferredSize() 
    { 
     return (new Dimension(300, 300));  
    } 

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

     // Clears the previously drawn image.  
     g.clearRect(0, 0, getWidth(), getHeight()); 
     // Draw image centered in the middle of the panel 
     g.drawImage(img, 0, 0, this); 
    } 

} 

画像が必要な場合は、ここでare

GEEK0 GEEK1 GEEK2 GEEK3 GEEK4

関連する問題