我有一个摇摆gui应用程序。我想键入图像路径,然后单击按钮将图像加载到jpanel。问题是它不会被加载,但如果我添加扩展的jpanel,它能够在我查看jframe时加载图像,可以正常加载图像。那是为什么?
相关代码:
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;
}
}
invoker类:
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
}
任何想法?我已经工作了两个小时。
答案 0 :(得分:1)
要更新面板,您应该在面板的父级上调用revalidate()方法,而不是在新面板上调用repaint(),因为您更改了内容本身(面板)而不是图像。在您的情况下,它的内容窗格,应该验证哪些内容。
但如果你问我,它仍然不是更新面板内图像的最佳方式...
你可以试试这个简单的例子(它更简单,效果很好):
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中的图形,则重新绘制整个面板)。 / p>
正如您所看到的,我甚至没有触摸面板本身 - 只是更改了图像源。