Java 绘制图像 JPanel : Working but weird

标签 java swing drawing jframe bufferedimage

我知道到处都有关于如何绘制图像的教程。通常人们建议显示它添加一个加载该图像的对象。但就我而言,我不想每次更改图像中的某些内容时都实例化一个新对象。

所以,我使用 Graphics 类来做到这一点。 另外,我正在使用 MVC 方法来完成此操作。

问题: 正如我们所看到的,只绘制了图像的一小部分区域,如果我加载另一张图像,这个小区域会根据图片而变化。然后,我认为缓冲图像已正确加载。

所以,我寻找问题出在哪里: 这是我的代码:

import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class DisplayView extends JFrame implements Observer {

    private static final long serialVersionUID = 1L;
    /**
     * @param args
     */
    private static DisplayView instance;
    private DisplayControl control;
    private JFileChooser fileChooser;

    Panel imageLeft, imageRight;

    private DisplayView() {

        JMenuItem exit = new JMenuItem("Exit");
        exit.setMnemonic('E');
        exit.setToolTipText("Exit Application");
        exit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                System.exit(0);
            }
        });

        fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new ImageFileFilter());

        JMenuItem loadImage = new JMenuItem("Load Image");
        loadImage.setMnemonic('O');
        loadImage.setToolTipText("Loads an Image to Process");
        loadImage.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                int ret = fileChooser.showDialog(DisplayView.getInstance(),
                        "Open file");

                if (ret == JFileChooser.APPROVE_OPTION) {
                    System.out.println(fileChooser.getSelectedFile());
                    control.onFileChoose(fileChooser.getSelectedFile()
                            .getAbsolutePath());
                }
            }
        });

        JMenu file = new JMenu("File");
        file.setMnemonic('F');
        file.add(loadImage);
        file.add(exit);

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(file);

        imageLeft = new Panel();
        imageLeft.setSize(500, 500);
        imageLeft.setVisible(true);

        imageRight = new Panel();

        this.setLayout(new FlowLayout());
        this.add(imageLeft);
        // this.add(imageRight);

        this.setTitle("Test");
        this.setSize(300, 200);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setJMenuBar(menuBar);
    }

    static public DisplayView getInstance() {
        if (instance == null)
            instance = new DisplayView();
        return DisplayView.instance;
    }

    public void setControl(DisplayControl control) {
        this.control = control;
    }

    @Override
    public void update(Observable o, Object arg) {
        // TODO Auto-generated method stub
        if (o instanceof DisplayModel) {
            this.imageLeft.setImage(((DisplayModel) o).getOriginalImage());
            // this.imageRight.setImage(((DisplayModel) o).getProcessedImage());

        }
    }

}

class Panel extends JPanel {

    BufferedImage image;

    public void setImage(BufferedImage image) {
        if (image != null)
            this.image = image;
        this.repaint();
    }

    @Override
    public void paint(Graphics g) {
        // TODO Auto-generated method stub
        super.paint(g);
        if (image != null)
            g.drawImage(image, 0, 0, this);
    }
}

最佳答案

问题是您的 Panel 类不会重写 getPreferredSize(),因此它的首选大小实际上是 (0,0),因此 FlowLayout 将为您的 Panel 分配 (0,0) 的大小。

无论如何,我会考虑用简单的 JLabel 类替换您的 Panel 类,它将执行完全相同的操作并为您处理首选尺寸。

  • 当您还使用 LayoutManager 时(您应该这样做),调用 setSize() 是没有用的。一般来说,只需忘记 setSize/setLocation/setBounds/setPreferredSize 即可。答案总是相同的:“使用适当的 LayoutManager
  • 对于自定义绘画,请覆盖 paintComponent 而不是 paint

关于Java 绘制图像 JPanel : Working but weird,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16194590/

相关文章:

java - 通过其实例变量之一对对象的 ArrayList 进行排序

java - 错误映射@OneToMany与JPA和Hibernate的关系

javax.swing.text.ElementIterator 奇怪的行为

Java Swing : HTML form in JEditorPane - text input encoding problem

java - .pack() 之后的 JInternalFrame 不获取内部组件的大小

python - 在pyglet(python)中按像素绘制

c++ - 循环绘制特定坐标

java、泛型和 getAll

java - 修复 java.lang.module.ResolutionException : two modules export the same package to another module in a non-modular app

ios - 在 UIScrollView 中绘制 UIImageView