Zoom in and zoom out function in Jpanel - java

I have to add Zoom In and Zoom Out functionality to JPanel, which contains components like JLabel with ImageIcon.
I want to Zoom JPanel with their components appropriately
I tried with following code snippet but it did not work properly.
The JPanel which is having null layout and is itself placed inside an Applet.
I am unsure of the reason as to why it is not working either because of Applet or something else !!
cPanel is my JPanel which contains JLabel
Following code snippet on Zoom Button click,
it shows blink screen on button click after that as original
Graphics g = cPanel.getGraphics();
Graphics2D g2d = (Graphics2D) g;
AffineTransform savedXForm = g2d.getTransform();
g2d.scale(1.0, 1.0);
g2d.setColor(Color.red);
super.paint(g);
g2d.setTransform(savedXForm);
cPanel.validate();
cPanel.repaint();

You can have a look into this link:
http://blog.sodhanalibrary.com/2015/04/zoom-in-and-zoom-out-image-using-mouse_9.html#.Vz6iG-QXV0w
Source Code to Refer(Here it has been accomplished using MouseWheelListener):
import java.awt.EventQueue;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import com.mortennobel.imagescaling.ResampleOp;
import java.awt.event.MouseWheelListener;
import java.awt.event.MouseWheelEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageZoom {
private JFrame frmImageZoomIn;
private static final String inputImage = "C:\\my-pfl-pic.jpg"; // give image path here
private JLabel label = null;
private double zoom = 1.0; // zoom factor
private BufferedImage image = null;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ImageZoom window = new ImageZoom();
window.frmImageZoomIn.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
* #throws IOException
*/
public ImageZoom() throws IOException {
initialize();
}
/**
* Initialize the contents of the frame.
* #throws IOException
*/
private void initialize() throws IOException {
frmImageZoomIn = new JFrame();
frmImageZoomIn.setTitle("Image Zoom In and Zoom Out");
frmImageZoomIn.setBounds(100, 100, 450, 300);
frmImageZoomIn.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scrollPane = new JScrollPane();
frmImageZoomIn.getContentPane().add(scrollPane, BorderLayout.CENTER);
image = ImageIO.read(new File(inputImage));
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
// display image as icon
Icon imageIcon = new ImageIcon(inputImage);
label = new JLabel( imageIcon );
panel.add(label, BorderLayout.CENTER);
panel.addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation();
double temp = zoom - (notches * 0.2);
// minimum zoom factor is 1.0
temp = Math.max(temp, 1.0);
if (temp != zoom) {
zoom = temp;
resizeImage();
}
}
});
scrollPane.setViewportView(panel);
}
public void resizeImage() {
System.out.println(zoom);
ResampleOp resampleOp = new ResampleOp((int)(image.getWidth()*zoom), (int)(image.getHeight()*zoom));
BufferedImage resizedIcon = resampleOp.filter(image, null);
Icon imageIcon = new ImageIcon(resizedIcon);
label.setIcon(imageIcon);
}
}

Related

Animation Constructor not working in Java GUI

Hello I am new to Java GUI I made a second.java which is as below:
package theproject;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay=50, totalFrames=8, currentFreames=1;
public second()
{
imageArray= new ImageIcon[totalFrames];
System.out.println(imageArray.length);
for(int i=0; i<imageArray.length;i++)
{
imageArray[i]=new ImageIcon(i+1+".png");
System.out.println(i+1);
}
animator= new Timer(delay, this);
animator.start();
}
public void paintComponent(Graphics g )
{
super.paintComponent(g);
if(currentFreames<8)
{
imageArray[currentFreames].paintIcon(this, g, 0, 0);
currentFreames++;
System.out.println(currentFreames);
}
else{
currentFreames=0;
}
}
#Override
public void actionPerformed(ActionEvent arg0) {
repaint();
}
}
And a Gui calling the constructor second and output is not showing . Can you please guide me what should I do and the gui is given below:
package theproject;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.SwingConstants;
import javax.swing.JTextField;
public class Sav {
private JFrame frame;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sav window = new Sav();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sav() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
textField = new JTextField();
textField.setBounds(10, 0, 261, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("Submit");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
second s= new second();
frame.add(s);
}
});
btnNewButton.setBounds(273, -1, 89, 23);
frame.getContentPane().add(btnNewButton);
}
}
The gui has to basically call the constructor and which will showcase the animation on the screen If someone what i am doing wrong or if something that has to be done please let me know .
First, don't update the state within the paintComponent method, paint can occur for a number of reasons at any time, mostly without your interaction. Painting should simple paint the current state. In your ActionListener, you should advance the frame and make decisions about what should occur (like resetting the frame value)
Second, you never actually add second to anything, so it will never be displayed.
Third, you don't override getPreferredSize in second, so the layout managers will have no idea what size the component should be and will simply be assigned 0x0, making it as good as invisible as makes no difference
Fourth, you're using null layouts. This is going to make you life impossibly hard. Swing has been designed and optimised around the use of layout managers, they do important work in deciding how best to deal with differences in font metrics across different rendering systems/pipelines, I highly recommend that you take the time to learn how to use them
Fifthly, paintComponent has no business been public, no one should ever call it directly
Example
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Sav {
private JFrame frame;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sav window = new Sav();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sav() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
textField = new JTextField(20);
frame.getContentPane().add(textField, gbc);
JButton btnNewButton = new JButton("Submit");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
second s = new second();
frame.add(s, gbc);
frame.getContentPane().revalidate();
frame.pack();
frame.setLocationRelativeTo(null);
}
});
frame.getContentPane().add(btnNewButton, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay = 50, totalFrames = 8, currentFreames = 1;
public second() {
imageArray = new ImageIcon[totalFrames];
for (int i = 0; i < imageArray.length; i++) {
imageArray[i] = new ImageIcon(getImage(i));
}
animator = new Timer(delay, this);
animator.start();
}
protected Image getImage(int index) {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
FontMetrics fm = g2d.getFontMetrics();
g2d.dispose();
String text = Integer.toString(index);
int height = fm.getHeight();
int width = fm.stringWidth(text);
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
g2d.setColor(getForeground());
g2d.drawString(text, 0, fm.getAscent());
g2d.dispose();
return img;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imageArray[0].getIconWidth(), imageArray[1].getIconHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
imageArray[currentFreames].paintIcon(this, g, 0, 0);
}
#Override
public void actionPerformed(ActionEvent arg0) {
currentFreames++;
if (currentFreames >= imageArray.length) {
currentFreames = 0;
}
repaint();
}
}
}
Your code is also not working. It increment the values of image set but do not displays the images
Works just fine for me...
imageArray[i]=new ImageIcon(i+1+".png"); will not generate any errors if the image can't be loaded for some reason (and it will load the images in the background thread, which is just another issue).
Instead, I would recommend using ImageIO.read instead, which will throw a IOException if the image can't be read for some reason, which is infinitely more useful. See Reading/Loading an Image for more details

Can I change the location of the ImageIcon that I put on a JLabel in my code?

I tried using, "label.setBounds(100,100,250,250)" and "label.setLocation(100,100)" but the image does not move from the top and center of the JLabel.
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Machine extends JPanel
{
public Machine()
{
ImageIcon imageIcon = new ImageIcon("res/robot.png");
JLabel label = new JLabel(imageIcon);
add(label);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add(new Machine());
frame.setVisible(true);
frame.setSize(new Dimension(1080, 720));
}
}
What are you trying to do?
The default layout of a JPanel is a FlowLayout with center alignment and the label is displayed at its preferred size. So the label is displayed in the center.
You have a couple of options:
Change the alignment of the FlowLayout to be either LEFT or RIGHT
Don't add the label to the panel. Just add it directly to the frame which uses a BorderLayout.
Then you can do something like:
label.setHorizontalAlignment(JLabel.LEFT);
label.setVerticalAlignment(JLabel.CENTER);
Edit:
was just trying to get the image to be in the middle of the frame
Then post your actual requirement when you ask a question. We don't know what "can I change the location" means to you.
So you would either use the BorderLayout and adjust the horizontal/vertical alignment as already demonstrated.
Or, you could set the layout manager of the frame to be a GridBagLayout and then add the label directly to the frame and use:
frame.add(label, new GridBagConstraints());
Now the label will move dynamically as the frame is resized.
If you want to place an image in a certain location, perhaps best is to draw it directly in your JPanel in a paintComponent method override, using one of Graphics drawImage(...) methods, one that allows placement of the image.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Machine extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/"
+ "thumb/f/f2/Abraham_Lincoln_O-55%2C_1861-crop.jpg/"
+ "250px-Abraham_Lincoln_O-55%2C_1861-crop.jpg";
private BufferedImage img;
private int x;
private int y;
public Machine() {
setPreferredSize(new Dimension(1080, 720));
x = 100; // or wherever you want to draw the image
y = 100;
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Machine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
Version 2: MouseListener / MouseMotionListener so that the image can be moved
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class Machine extends JPanel {
private static final String IMG_PATH = "https://upload.wikimedia.org/"
+ "wikipedia/commons/thumb/f/f2/"
+ "Abraham_Lincoln_O-55%2C_1861-crop.jpg/"
+ "250px-Abraham_Lincoln_O-55%2C_1861-crop.jpg";
private BufferedImage img;
private int x;
private int y;
public Machine() {
setPreferredSize(new Dimension(1080, 720));
x = 100; // or wherever you want to draw the image
y = 100;
MyMouse mouse = new MyMouse();
addMouseListener(mouse);
addMouseMotionListener(mouse);
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
private class MyMouse extends MouseAdapter {
private Point offset;
#Override
public void mousePressed(MouseEvent e) {
// check if left mouse button pushed
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// get bounds of the image and see if mouse press within bounds
Rectangle r = new Rectangle(x, y, img.getWidth(), img.getHeight());
if (r.contains(e.getPoint())) {
// set the offset of the mouse from the left upper
// edge of the image
offset = new Point(e.getX() - x, e.getY() - y);
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (offset != null) {
moveImg(e);
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (offset != null) {
moveImg(e);
}
offset = null;
}
private void moveImg(MouseEvent e) {
x = e.getX() - offset.x;
y = e.getY() - offset.y;
repaint();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Machine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

Swing splash screen not working, Unexpected result

Downloaded some code to display Splash Screen from O'Reilly, but When I do some modified some text to display as per need.
I did some investigation, and debug the program but found nothing.
Is that any windows platform issue?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
public class SplashScreen extends JWindow {
private int duration;
byte[] msg = new byte[]{65,112,114,105,108,32,70, 111, 111,108};
String text = "";
public SplashScreen(int d) {
duration = d;
}
// A simple little method to show a title screen in the center
// of the screen for the amount of time given in the constructor
public void showSplash() throws Exception {
JPanel content = (JPanel)getContentPane();
content.setBackground(Color.white);
// Set the window's bounds, centering the window
int width = 450;
int height =300;
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
int x = (screen.width-width)/2;
int y = (screen.height-height)/2;
setBounds(x,y,width,height);
JLabel txt = new JLabel
(new String(msg), JLabel.CENTER);
txt.setFont(new Font("Sans-Serif", Font.BOLD, 32));
// Build the splash screen
JLabel label = new JLabel(new ImageIcon("oreilly.gif"));
JLabel copyrt = new JLabel
(new String(msg), JLabel.CENTER);
URL url = new URL("http://findicons.com/files/icons/360/emoticons/128/satisfied.png");
BufferedImage img = ImageIO.read(url);
ImageIcon icon = new ImageIcon(img);
JLabel iconL = new JLabel(icon);
copyrt.setFont(new Font("Sans-Serif", Font.BOLD, 12));
content.add(label, BorderLayout.CENTER);
content.add(txt, BorderLayout.CENTER);
content.add(iconL, BorderLayout.CENTER);
content.add(copyrt, BorderLayout.SOUTH);
Color oraRed = new Color(156, 20, 20, 255);
content.setBorder(BorderFactory.createLineBorder(oraRed, 10));
// Display it
setVisible(true);
// Wait a little while, maybe while loading resources
try { Thread.sleep(duration); } catch (Exception e) {}
setVisible(false);
}
public void showSplashAndExit() {
try {
showSplash();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.exit(0);
}
public static void main(String[] args) {
// Throw a nice little title page up on the screen first
SplashScreen splash = new SplashScreen(10000);
// Normally, we'd call splash.showSplash() and get on with the program.
// But, since this is only a test...
splash.showSplashAndExit();
}
}

Can I add an animated gif file to JButton?

I'm trying to add a .gif file into a JButton, but seems like it doesn't work - the gif file didn't move, it displayed like a normal Image.
Here are my codes:
+The ImageButton Class:
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
/**
* Button which display a png or gif image.
* */
public class ImageButton extends JButton {
private static final long serialVersionUID = 1L;
private ImageIcon defaultIcon;
private ImageIcon hoverIcon;
/**
* Create a normal JButton.
* */
public ImageButton(){
super();
}
/**
* Create a new ImageButton Object.
* #param img1 url of normal image of the button
* #param img2 url hover image of the button
* #param width button width
* #param height button height
* */
public ImageButton(String img1, String img2, int width, int height){
super();
BufferedImage defaultIcon = null;
BufferedImage hoverIcon = null;
try {
defaultIcon = ImageIO.read(getClass().getResource(img1));
hoverIcon = ImageIO.read(getClass().getResource(img2));
} catch (IOException e) {
e.printStackTrace();
}
this.defaultIcon = new ImageIcon(defaultIcon);
this.hoverIcon = new ImageIcon(hoverIcon);
setIcon(this.defaultIcon);
setPreferredSize(new Dimension(width,height));
setBorder(null);
setOpaque(false);
setContentAreaFilled(false);
setBorderPainted(false);
}
/**
* Hover the button.
* */
public void hover(){
setIcon(hoverIcon);
}
/**
* Return the button to normal.
* */
public void down(){
setIcon(defaultIcon);
}
}
+The Test Class:
import java.awt.FlowLayout;
import javax.swing.JFrame;
public class TestGifButton {
public static void main(String[] args) {
ImageButton button = new ImageButton("level3.gif","level3.gif", 150, 150);
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.add(button);
frame.pack();
frame.setVisible(true);
}
}
I used a looping .gif file.
So how can I fix it ? thanks a lot :'(
JButton button = new JButton(new ImageIcon(getClass().getClassLoader().getResource("Images/BBishopB.gif")));
OR
Full Example :
import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.*;
public class ImageSwapOnButton {
public static void main( String[] args ) throws Exception {
URL url = new URL("http://1point1c.org/gif/thum/plnttm.gif");
Image image = Toolkit.getDefaultToolkit().createImage(url);
ImageIcon spinIcon = new ImageIcon(image);
JOptionPane.showMessageDialog(null, new JLabel(spinIcon));
// create a static version of this icon
BufferedImage bi = new BufferedImage(150,150,BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.getGraphics();
g.drawImage(image,0,0,null);
g.dispose();
ImageIcon staticIcon = new ImageIcon(bi);
JButton button = new JButton(staticIcon);
button.setRolloverIcon(spinIcon);
JOptionPane.showMessageDialog(null, button);
}
}
well, you might try this for your animation...
File file = new File("img/ani.gif");
URL url = file.toURI().toURL();
Icon icon = new ImageIcon(url);
JButton aniButt = new JButton(icon);
maybe you must also set the mouseover and pressed icons as well..
but read the https://stackoverflow.com/a/18271876/714968 ... (as mKorbel metioned!)

paintComponent not called when calling JScrollPane

I'm trying to load a background image with a JFileChooser, but when the operation ends, the paintcomponent() method is not called as expected.
[EDIT] for this reason, instead of having a red ball over the background image, I have the red ball only.
I read in several other topics that the instance of my Mappa Object should be added to the frame:
Why is paint()/paintComponent() never called?
paintComponent not being called at the right time
PaintComponent is not being called
But this does not solve my problem: I created a JScrollPane that gets my component in the constructor and linked the JScrollPane and added it in the main frame with
frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER);
This is the code of the main Gui
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
public class Gui implements ActionListener {
private JFrame frmEditor;
Mappa content;
private JMenuItem mntmSfondo;
private JScrollPane scrollabile;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Gui window = new Gui();
window.frmEditor.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Gui() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmEditor = new JFrame();
frmEditor.setFont(UIManager.getFont("TextArea.font"));
frmEditor.setBounds(50, 50, 1024, 768);
frmEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmEditor.getContentPane().setLayout(new BorderLayout(0, 0));
JPanel panelTile = new JPanel();
panelTile.setLayout(new BorderLayout(0, 0));
JPanel panelStrum = new JPanel();
panelStrum.setLayout(new GridLayout(15, 2));
content = new Mappa(null);
content.setMinimumSize(new Dimension(150, 150));
scrollabile = new JScrollPane(content);
scrollabile
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollabile
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER);
inizializzaMenu();
}
/**
* Initialize the menu.
*/
private void inizializzaMenu() {
JMenuBar menuBar = new JMenuBar();
frmEditor.setJMenuBar(menuBar);
JMenu mnFile = new JMenu("File");
mnFile.setFont(UIManager.getFont("TextArea.font"));
JMenu mnAltro = new JMenu("Modify");
mnAltro.setFont(UIManager.getFont("TextArea.font"));
menuBar.add(mnAltro);
mntmSfondo = new JMenuItem("Load Background");
mntmSfondo
.setIcon(new ImageIcon(
Gui.class
.getResource("/com/sun/java/swing/plaf/windows/icons/TreeOpen.gif")));
mntmSfondo.setFont(UIManager.getFont("TextArea.font"));
mntmSfondo.addActionListener(this);
mnAltro.add(mntmSfondo);
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == mntmSfondo) {
JFileChooser fc = new JFileChooser("tuttiSfondi");
int result = fc.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
try {
content = new Mappa(file);
} catch (Exception ex) {
}
}
if (result == JFileChooser.CANCEL_OPTION) {
}
}
}
}
while this is the code of the class Mappa, that I would like to use to load the background from the JFileChooser.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Mappa extends JPanel {
Image immagine;
public Mappa(File fileImmagine) {
if (fileImmagine != null ) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(fileImmagine.getPath()));
} catch (IOException e) {
e.printStackTrace();
}
this.immagine = img;
}
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, 4000, 4000);
g.drawImage(immagine, 0, 0, null);
g.setColor(Color.red);
g.fillOval(170, 170, 150, 150);
System.out.println("Called Repaint() on Mappa");
}
}
The problem is not in an incorrect image path, since it loads if I set the path on the Mappa class "manually", by giving the path instead of using new File(fileImmagine.getPath()) in the ImageIO.read, but that paintComponent is called only once, when the constructor of Mappa is called from the Gui class
When you set the background, you only allocate the new Mappa instance, but not actually adding it to any container. Try adding the following:
scrollabile.setViewportView(content);
Or instead, replace an image in the Mappa class. Ie:
public void setImage(File file) throws IOException {
this.immagine = ImageIO.read(file);
repaint();
}
Also, in paintComponent(), you could use panel dimensions to fill the whole area:
g.drawImage(immagine, 0, 0, getWidth(), getHeight(), this);
And don't forget to use a valid ImageObserver as JPanel implements one.
You aren't actually modifying the Mapa instance that you've added to the frame. The line
content = new Mappa(file);
in actionPerformed() doesn't change the panel in the frame, it reassigns the local variable only. You should instead put a method such as updateImage() in Mapa that will update the image that Mapa displays. You will also need to call repaint() after this so that it redraws the new image.

Categories