gpt4 book ai didi

java - 在 Java Swing/Awt 中实现图像加载器

转载 作者:行者123 更新时间:2023-12-01 17:57:43 25 4
gpt4 key购买 nike

我正在实现一个从文件加载并可以编辑它的 Paint 应用程序。但是我的 Openfile 函数无法正确运行,它会正确加载图像并更改边界,但不会在 Jpanel 中绘制它。

这是我的代码。

public class OpenSave extends JPanel{

private static final long serialVersionUID = 1L;

protected BufferedImage imagem;

public OpenSave() {}

public void open(JPanel panel) throws IOException {
JFileChooser escolher = new JFileChooser();
escolher.setCurrentDirectory(new File("."));

escolher.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
return f.getName().toLowerCase().endsWith(".jpg") || f.isDirectory();
}
public String getDescription() {
return "Imagens JPG";
}
});

escolher.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
return f.getName().toLowerCase().endsWith(".png") || f.isDirectory();
}
public String getDescription(){
return "Imagens PNG";
}
});


JFrame frame = new JFrame();
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(OpenSave.class.getResource("/javax/swing/plaf/metal/icons/ocean/directory.gif")));
int r = escolher.showOpenDialog(frame);
if (r == JFileChooser.APPROVE_OPTION) {
imagem = ImageIO.read(new File(escolher.getSelectedFile().getAbsolutePath()));
panel.setBounds(77, 13, imagem.getWidth(this), imagem.getHeight(this));
}
}


@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(imagem, 0, 0, this);
repaint();
}
}

有了这个,我可以正确保存和加载,但加载的图像不会进入我的 JPanel 面板。

这里是简化的主类。

    private JPanel contentPane;
private Jpanel panel;

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TelaMain frame = new TelaMain();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

public TelaMain() {

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 600, 400);

JMenuBar menuBar = new JMenuBar();
menuBar.setFocusTraversalKeysEnabled(true);
setJMenuBar(menuBar);

JMenu mnArchive = new JMenu("Archive");
menuBar.add(mnArchive);
JMenuItem mntmOpen = new JMenuItem("Open");
mnArquivo.add(mntmOpen);

panel = new JPanel();
panel.setAutoscrolls(true);
panel.setBorder(new LineBorder(new Color(0, 0, 0)));
panel.setBackground(Color.WHITE);
panel.setBounds(77, 13, 498, 307);
contentPane.add(panel);

mntmAbrir.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent abrir) {
OpenSave a = new OpenSave();
try {
a.open(panel);
a.repaint();

} catch (IOException e) {
e.printStackTrace();
}
}

}
}
);

我愿意接受针对我的问题的任何其他编辑建议。

最佳答案

你的代码看起来很困惑。具体来说:

  • 您创建了一个 JFrame 但从未显示它,也许只是将其用作文件选择器的参数?
  • 您将 JPanel 传递到 open 方法中,只是为了更改其大小,但您不对其执行任何其他操作。
  • 我有一种感觉,您认为 JPanel 中传递的内容会以某种方式获得您正在阅读的图像,但如果是这样,您就错了。
  • 该图像可能会显示在 OpenSave JPanel 中,但我们永远不会知道,因为我们从未见过您将其添加到任何顶级窗口(例如 JFrame)中 - 因此您当前的代码给我们提供了关于您的内容的不完整图片正在做。
  • 您的paintComponent方法很危险,因为它尝试在OpenSave JPanel中绘制图像,而不首先检查图像是否为空。如果当前没有可用图像,则代码可能会抛出 NullPointerException。
  • 您使用 setBounds(...) 是一件危险的事情。虽然 null 布局和 setBounds() 对于 Swing 新手来说似乎是创建复杂 GUI 的最简单、最好的方法,但创建的 Swing GUI 越多,使用它们时遇到的困难就越严重。当 GUI 调整大小时,它们不会调整组件的大小,它们是增强或维护的皇家女巫,当放置在滚动 Pane 中时,它们会完全失败,在所有平台或与原始分辨率不同的屏幕分辨率上查看时,它们看起来非常糟糕.

建议:

  • 确保将 OpenSave JPanel 放入显示的 JFrame
  • 在其paintComponent方法中,仅在图像不为空时绘制图像。换句话说,在 if block 中检查 null 并仅绘制 if (imagem != null) {}
  • 向我们展示您的其余相关代码
  • 将当前显示的 JFrame 传递到 JFileChooser,而不是未显示的 JFrame。
  • 让您的 OpenSave JPanel 覆盖 getPreferredSize,并将该大小设为它所保存的图像的大小。
  • 就我个人而言,我会将图像文件打开和保存代码与 View 代码(GUI 代码)分开。

示例的部分内容:

public void setImagem(BufferedImage imagem) {
this.imagem = imagem;
repaint();
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (imagem != null) {
g.drawImage(imagem, 0, 0, this);
}
}

@Override
public Dimension getPreferredSize() {
Dimension sz = super.getPreferredSize();
if (imagem != null) {
sz = new Dimension(imagem.getWidth(), imagem.getHeight());
}
return sz;
}

private static void createAndShowGui() {
MyOpenSave openSave = new MyOpenSave();

JFrame frame = new JFrame("MyOpenSave");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(openSave);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
<小时/>

更完整的示例:

TestOpenSave.java——“驱动程序”类

public class TestOpenSave {

private static void createAndShowGui() {
OpenSave openSave = new OpenSave();
JFrame frame = new JFrame("OpenSave");

JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new GetImageAction("Open Image", frame, openSave)));

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(openSave);
frame.add(btnPanel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

OpenSave.java,显示图像的“ View ”类

@SuppressWarnings("serial")
public class OpenSave extends JPanel {
private BufferedImage imagem;

public void setImagem(BufferedImage imagem) {
this.imagem = imagem;
repaint();
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (imagem != null) {
g.drawImage(imagem, 0, 0, this);
}
}

@Override
public Dimension getPreferredSize() {
Dimension sz = super.getPreferredSize();
if (imagem != null) {
sz = new Dimension(imagem.getWidth(), imagem.getHeight());
}
return sz;
}
}

GetImageAction 文件加载类或“ Controller ”类。请注意,它与图像显示或“ View 类”是分开的

@SuppressWarnings("serial")
public class GetImageAction extends AbstractAction {
private JFrame myFrame;
private OpenSave openSave;

public GetImageAction(String name, JFrame myFrame, OpenSave openSave) {
super(name);
this.myFrame = myFrame;
this.openSave = openSave;
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}

@Override
public void actionPerformed(ActionEvent e) {
JFileChooser escolher = new JFileChooser();
escolher.setMultiSelectionEnabled(false);
escolher.setCurrentDirectory(new File("."));
escolher.setFileFilter(new FileFilter() {

@Override
public String getDescription() {
return "Imagens JPG and PNG";
}

@Override
public boolean accept(File f) {
String ext = f.getName().toLowerCase();
if (f.isDirectory() || ext.endsWith(".jpg") || ext.endsWith(".png")) {
return true;
}
return false;
}
});
int reply = escolher.showOpenDialog(myFrame);
if (reply == JFileChooser.APPROVE_OPTION) {
try {
BufferedImage img = ImageIO.read(escolher.getSelectedFile());
openSave.setImagem(img);
myFrame.pack();
myFrame.setLocationRelativeTo(null);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}

关于java - 在 Java Swing/Awt 中实现图像加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43313687/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com