1

私はswing guiアプリケーションを持っています。画像パスに入力し、ボタンをクリックして画像を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

}

何か案は?私はそれに2時間取り組んできました。

4

1 に答える 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 のグラフィックスの動作方法に深く入りたくない場合は、パネル全体を再描画します)。

ご覧のとおり、パネル自体には触れていません。画像ソースを変更しただけです。

于 2012-04-09T15:16:15.027 に答える