Reputation: 11
I'm implementing a Paint aplication that loads from a file and can edit it. But my Openfile function doesn't function correctely, it loads the image and changes the Bounds correctely but dont paint it in the Jpanel.
Here's my code.
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();
}
}
With this i can save and load correctly but the loaded image don't go to my JPanel panel.
here is the main class simplified.
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();
}
}
}
}
);
i'm open to any other edit sugestions to my question.
Upvotes: 0
Views: 508
Reputation: 285405
Your code looks confused. Specifically:
setBounds(...)
a dangerous thing to do. While null layouts and setBounds()
might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.Suggestions:
if (imagem != null) {}
Portions of an example:
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());
}
A more complete example:
TestOpenSave.java -- the "driver" class
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, the "view" class that displays the image
@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;
}
}
The GetImageAction file loading class or "controller" class. Note that it is separate from the image display or "view class"
@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();
}
}
}
}
Upvotes: 4
Reputation: 31
I'm not entirely sure, but the issue may be that you didn't include frame.add(this)
when you were initializing the JFrame, which tells the program to use the paint method in your class.
Upvotes: 0