2012-04-09 3 views
1

У меня есть приложение поворотного gui. Я хочу ввести путь к изображению и нажать кнопку, чтобы загрузить изображение в jpanel. Проблема в том, что он не будет загружен, но если я добавлю расширенный jpanel, который может загружать изображение, когда я запускаю jframe, изображение может быть загружено нормально. почему это?Как загрузить фоновое изображение в 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 

} 

какие-либо идеи? Я работаю над этим два часа.

+1

Примите ответы на свои старые вопросы - если они вам помогли. Это улучшит ваши шансы получить ответ на этот вопрос. –

ответ

1

Чтобы обновить панель, вы должны вызвать метод 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); 
} 

Единственное, что вам нужно сделать, если вы измените изображение внутри панели - перерисуйте затронутую панель rect (или всю панель, если вам не нравится углубляться в то, как работает графика в Swing).

Как вы можете видеть, я даже не касался самой панели - просто изменил источник изображения.

+0

Да, вы правы. Но getContentPane(). Validate работает не очень хорошо, хотя изображение появляется, но изображение также имеет некоторые дополнительные текстовые поля. Если сначала добавить панель, то динамически измените путь изображения, это нормально, как и вы, я возьму второй вариант. Благодарю. – user1231111

+1

@AndrewThompson «если вы сильно чувствуете оригинальный код» - не совсем, спасибо за изменение :) –

+0

Добро пожаловать. :) –

Смежные вопросы