2012-04-09 11 views
1

私はスイングGUIアプリケーションを持っています。私はイメージパスに入力し、ボタンをクリックしてイメージをjpanelにロードします。問題はロードされないことですが、jframeをインスタンス化するときイメージをロードできる拡張jpanelを追加するとイメージが正常にロードされます。何故ですか?関連JPanelに背景イメージを動的に読み込むには?

コード:

package com.xdg.graphic; 

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 

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

public class ImageLoader extends JPanel { 
    private String imgPath; 
    private BufferedImage image; 


    public ImageLoader(String imgPath) { 
     this.imgPath = imgPath; 
     try { 
      this.image=ImageIO.read(new File(imgPath)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void paint(Graphics g) { 
     g.drawImage(image, 0, 0, null); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     g.drawImage(image, 0, 0, null); 
    } 

    public Dimension getPreferredSize() { 
     if (image == null) { 
      return new Dimension(100,100); 
     } else { 
      return new Dimension(image.getWidth(null), image.getHeight(null)); 
     } 
    } 

    public String getImgPath() { 
     return imgPath; 
    } 

    public void setImgPath(String imgPath) { 
     this.imgPath = imgPath; 
    } 



} 

呼び出しクラス:

package com.xdg.image; 

import com.xdg.graphic.ImageLoader; 
import sun.awt.windows.ThemeReader; 

import java.awt.*; 

public class FrmImgCropper extends javax.swing.JFrame { 
    private ImageLoader imageLoader; 

    /** Creates new form FrmImgCropper */ 
    public FrmImgCropper() { 
     initComponents(); 
    } 

    /** This method is called from within the constructor to 
    * initialize the form. 
    * WARNING: Do NOT modify this code. The content of this method is 
    * always regenerated by the Form Editor. 
    */ 
    //GEN-BEGIN:initComponents 
    // <editor-fold defaultstate="collapsed" desc="Generated Code"> 
    private void initComponents() { 

     jPanel2 = new javax.swing.JPanel(); 
     tfImagePath = new javax.swing.JTextField(); 
     btnPreview = new javax.swing.JButton(); 
     tfRatioW = new javax.swing.JTextField(); 
     tfRatioH = new javax.swing.JTextField(); 
     jLabel1 = new javax.swing.JLabel(); 
     btnLoad = new javax.swing.JButton(); 
     jLabel2 = new javax.swing.JLabel(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     btnPreview.setText("Preview"); 

     jLabel1.setText(":"); 

     btnLoad.setText("Load"); 
     btnLoad.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       btnLoadActionPerformed(evt); 
      } 
     }); 

     jLabel2.setText("Image Path:"); 

     javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); 
     jPanel2.setLayout(jPanel2Layout); 
     jPanel2Layout.setHorizontalGroup(jPanel2Layout 
       .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(
         jPanel2Layout 
           .createSequentialGroup() 
           .addGap(34, 34, 34) 
           .addComponent(tfRatioW, javax.swing.GroupLayout.PREFERRED_SIZE, 55, 
             javax.swing.GroupLayout.PREFERRED_SIZE) 
           .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
           .addComponent(jLabel1) 
           .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 
           .addComponent(tfRatioH, javax.swing.GroupLayout.PREFERRED_SIZE, 53, 
             javax.swing.GroupLayout.PREFERRED_SIZE) 
           .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 123, 
             Short.MAX_VALUE) 
           .addComponent(btnLoad, javax.swing.GroupLayout.PREFERRED_SIZE, 82, 
             javax.swing.GroupLayout.PREFERRED_SIZE).addGap(46, 46, 46) 
           .addComponent(btnPreview).addGap(276, 276, 276)) 
       .addGroup(
         jPanel2Layout.createSequentialGroup().addGap(66, 66, 66).addComponent(jLabel2) 
           .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 
           .addComponent(tfImagePath, javax.swing.GroupLayout.DEFAULT_SIZE, 593, Short.MAX_VALUE) 
           .addGap(29, 29, 29))); 
     jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(
         javax.swing.GroupLayout.Alignment.TRAILING, 
         jPanel2Layout 
           .createSequentialGroup() 
           .addContainerGap(20, Short.MAX_VALUE) 
           .addGroup(
             jPanel2Layout 
               .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 
               .addComponent(jLabel2) 
               .addComponent(tfImagePath, javax.swing.GroupLayout.PREFERRED_SIZE, 
                 javax.swing.GroupLayout.DEFAULT_SIZE, 
                 javax.swing.GroupLayout.PREFERRED_SIZE)) 
           .addGap(18, 18, 18) 
           .addGroup(
             jPanel2Layout 
               .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) 
               .addComponent(jLabel1) 
               .addComponent(tfRatioW, javax.swing.GroupLayout.PREFERRED_SIZE, 
                 javax.swing.GroupLayout.DEFAULT_SIZE, 
                 javax.swing.GroupLayout.PREFERRED_SIZE) 
               .addComponent(tfRatioH, javax.swing.GroupLayout.PREFERRED_SIZE, 
                 javax.swing.GroupLayout.DEFAULT_SIZE, 
                 javax.swing.GroupLayout.PREFERRED_SIZE) 
               .addComponent(btnPreview).addComponent(btnLoad)).addGap(20, 20, 20))); 

     getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH); 

     pack(); 
    }// </editor-fold> 
    //GEN-END:initComponents 

    private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) { 
     if (imageLoader == null) { 
      imageLoader = new ImageLoader(tfImagePath.getText()); 
      imageLoader.setBackground(Color.green); 

      getContentPane().add(imageLoader, BorderLayout.CENTER); 
      getContentPane().repaint(); 
      this.repaint();//image does not show up this way dnamically 
     } else { 
      imageLoader.setImgPath(tfImagePath.getText()); 
      imageLoader.repaint(); 
     } 

    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 

       FrmImgCropper cropper = new FrmImgCropper(); 
       cropper.getContentPane().add(new ImageLoader("i:\\temp4\\car.jpg")); //if I add the image loader here directly,image shows up 
       cropper.setSize(800, 900); 
       cropper.setVisible(true); 
      } 
     }); 
    } 

    //GEN-BEGIN:variables 
    // Variables declaration - do not modify 
    private javax.swing.JButton btnLoad; 
    private javax.swing.JButton btnPreview; 
    private javax.swing.JLabel jLabel1; 
    private javax.swing.JLabel jLabel2; 
    private javax.swing.JPanel jPanel2; 
    private javax.swing.JTextField tfImagePath; 
    private javax.swing.JTextField tfRatioH; 
    private javax.swing.JTextField tfRatioW; 
    // End of variables declaration//GEN-END:variables 

} 

任意のアイデア?私は2時間作業しています。

+1

あなたの古い質問の回答を受け入れるようにしてください。そうすれば、この質問に答えられる可能性が高まります。 –

答えて

1

パネルを更新するには、コンテンツ自体(パネル)を変更するので、新しいパネルのrepaint()ではなくパネルの親に対してrevalidate()メソッドを呼び出す必要があります。あなたのケースでは、そのコンテンツペインを検証する必要があります。あなたは(そのはるかにシンプルにし、完璧に動作します)この単純な例を試すことができます

しかし、あなたは私に言わせれば、パネル内の画像を更新するために、そのまだない最善の方法...:

private static BufferedImage image = null; 

public static void main (String[] args) 
{ 
    final JFrame imageFrame = new JFrame(); 
    imageFrame.setLayout (new BorderLayout()); 

    final JPanel panel = new JPanel() 
    { 
     protected void paintComponent (Graphics g) 
     { 
      super.paintComponent (g); 

      if (image != null) 
      { 
       g.drawImage (image, getWidth()/2 - image.getWidth()/2, 
         getHeight()/2 - image.getHeight()/2, this); 
      } 
     } 
    }; 
    imageFrame.add (panel, BorderLayout.CENTER); 

    imageFrame.add (new JButton ("Load image") 
    { 
     { 
      addActionListener (new ActionListener() 
      { 
       public void actionPerformed (ActionEvent e) 
       { 
        JFileChooser fc = new JFileChooser(); 
        fc.setDialogType (JFileChooser.OPEN_DIALOG); 

        if (fc.showOpenDialog (imageFrame) == JFileChooser.APPROVE_OPTION) 
        { 
         try 
         { 
          image = ImageIO.read (fc.getSelectedFile()); 
          panel.repaint(); 
         } 
         catch (IOException e1) 
         { 
          // 
         } 
        } 
       } 
      }); 
     } 
    }, BorderLayout.SOUTH); 

    imageFrame.setSize (500, 500); 
    imageFrame.setLocationRelativeTo (null); 
    imageFrame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
    imageFrame.setVisible (true); 
} 

あなたがパネル内の画像を変更した場合は、実際に唯一行う必要があります - 影響を受けたパネルの矩形を再描画してください(または、Swingのグラフィックスの仕方を深く知りたくない場合はパネル全体を再描画してください)。

私はパネル自体に触れていないことがわかりました - イメージソースを変更しました。

+0

はい、あなたは正しいです。しかし、getContentPane()。validateはうまく動作しませんが、イメージが表示されますが、画像によって余分なテキストフィールドのようなものもあります。最初にパネルを追加してから、イメージパスを動的に変更する場合は、提案したように、2番目のオプションを使用します。ありがとう。 – user1231111

+1

@AndrewThompson "元のコードについて強く感じたら" - 本当にありがとう、変更のために:) –

+0

よろしくお願いします。 :) –

関連する問題