[英]Implementing a Image loader in Java Swing/Awt
我正在实现从文件加载并可以对其进行编辑的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();
}
}
}
}
);
我愿意接受我的问题的任何其他编辑建议。
您的代码看起来很混乱。 特别:
setBounds(...)
做一件危险的事情。 尽管null布局和setBounds()
似乎是Swing新手喜欢创建复杂GUI的最简单和最佳方法,但您创建的Swing GUI越多,使用它们时将遇到的困难就越大。 当GUI调整大小时,它们不会重新调整组件的大小;它们是需要增强或维护的皇家女巫;放置在滚动窗格中时,它们会完全失败;在所有平台或与原始分辨率不同的屏幕分辨率下查看时,它们看起来都是令人毛骨悚然的。 建议:
if (imagem != null) {}
示例的一部分:
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,显示图像的“视图”类
@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文件加载类或“控制器”类。 请注意,它与图像显示或“视图类”是分开的
@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();
}
}
}
}
我不确定,但是问题可能是初始化JFrame时没有包含frame.add(this)
,这告诉程序在类中使用paint方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.