I try to create an Image View Program and have a problem in Java Image's zoom in and zoom out :D
I create a JPanel and using BufferedImage to display an image in my computer. After clicking a button, it should be zoom .
But the problem in here that, I overload the method paintComponent() in the JPanel to display a image as I want. After searching in the Google, I think I should use Graphic2D to deal with this problem. Follow on this post, the line
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, newImageWidth , newImageHeight , null);
should be put in the overloaded method paintComponent(). Howerver, in my case, I want to zoom the image after clicking a button, so, how can i access to the paintComponent() to do the zoom ??
public class MiddlePanel extends JPanel {
private BufferedImage img;
private JButton jbtZoom = new JButton("Zoom");
public MiddlePanel(int width){
img = ImageIO.read(new FileInputStream(new File("C:\\Picture\\pic1.jpg")));
this.setPreferredSize(new Dimension(800,460));
}
public void paintComponent(Graphics g) {
g.drawImage(img......);
}
public void addComponentActionListener(){
jbtZoom.addActionListener(new ActionListener{
public void actionPerformed(){
//What should I do in here to zoom the image....
}
});
}
Thank for your help!
You need to change your design like so:
Store in a variable your zoom state and then your
overridden paintComponent method should look at that variable to
decide if/how much to zoom.
Your ActionListener will update the variable then call repaint() on
the panel.
Related
I've been working on a drinking game program for school.
//this is the game //http://sotallytober.com/games/verbal/mexican/
Anyway, I painted a image in an JPanel using the following code (it's an class that extends JPanel)
public class iconPanel extends JPanel {
ImageIcon image;
Image pic;
public iconPanel(String startScreenImage) {
image = new ImageIcon(startScreenImage);
pic = image.getImage();
this.setBackground(new Color(0, true));
}
#Override
public void paintComponent(Graphics g) {
//Paint background first
g.drawImage (pic, 0, 0, getWidth (), getHeight (), this);
}
Now in my other class, where I have the layout and all the components I declare on top my JPanels like this :
private JPanel pnDrinkPlayerBW;
Then in a method in the same class named MakeComponents I set the JPanel to :
pnDrinkPlayerBW = new iconPanel("img/glass.jpg");
pnDrinkPlayerBW.setPreferredSize(new Dimension(183,61));
Afterwards I add it to the Panel where it has to come, and that panel onto the frame in the method makeLayout() (I don't think that it's useful code, so if you want to see it, ask me)
Then if a button gets pressed, I want to change the glass.jpg image to another image, for example beerGlass0.png, so in the actionlistener in another method actionEvents() I do this:
pnDrinkPlayerBW = new iconPanel("img/beerGlass.png");
pnDrinkPlayerBW.setPreferredSize(new Dimension(183,61));
pnDrinkPlayerBW.repaint();
I'll put the constructor of this class also here, just if people need it :
public SpelScreen(){
makeComponents();
makeLayout();
actionEvents();
} // note : this is'nt the full constructor, just the call for the methods I talked about, SpelScreen extends JFrame..
So what I want to do, is to set in the class SpelScreen a new image for the iconPanel and repaint it using the same instance of the spelscreen.
I am quite new to Java, so don't expect me to rapidly understand complicated code :)
Thanks!
First off you're forgetting to call super.paintComponent in your paintComponent method. Also paintComponent should be protected not public
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(..);
}
Second, I don't think you want to create a new iconPanel and immediately call repaint on it. That will probably do nothing.
Instead have a setter for your pic, then just repaint(); inside that method.
public void setPic(Image pic) {
this.pic = pic;
repaint();
}
Then you can just call the setPic from the the class you created the iconPanel in. For example
iconPanel panel = new iconPanel("...");
... // then in some listener
public void actionPerformed(ActionEvent e) {
Image pic = null;
try {
pic = ImageIO.read(...);
panel.setPic(pic);
} catch ...
}
Another option is just to have an array of images you initialize in the iconPanel. Then in a a listener, you can just change the index the if the image array then call repaint. Something like this
Image[] images = new Image[5];
int imageIndex = 0;
// fill the array with images
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(images[imageIndex], ...);
}
Then you could just change the imageIndex and repaint()
Side Note
You should be using Java naming convention. Class names being with capital letters i.e. iconPanel → IconPanel
Update
Using ImageIcon
public void setImage(ImageIcon img) {
pic = img.getImage();
repaint();
}
I'm trying to overlay a background picture with a .png sample, and I don't know how it works.
I tried to create 2 JPanels, but didn't find out how to overlay them, then I tried to create 2 JLabels and once again, they just stay separated.
Have you any idea ?
Thanks !
You can use one jPanel.Override paint or paintComponent method and draw your picture with graphic object.
public class MyCustomPanel extends JPanel{
private Image img;
public MyCustomPanel(// use constructor to get img or load it directly from below){
//load image
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// Draws the img to the BackgroundPanel.
g.drawImage(img, 0, 0, this);
}
}
Then you can go to your main class and use this JPanel
MyCustomPanel mcp=new MyCustomPanel(//img path);
mcp.add(new JLabel("Hello"),BorderLayout.CENTER);
add(mcp),BorderLayout.CENTER);
//etc
I hope you understand
Next time post some code if you want to have answr faster and more complex/better suited for your case.
I'm having problems with putting a stable image background.
I successfully create/draw an image background but when I consecutively run it many times, the image is not showing. The background image seems to be not stable. When I drag the frame to a side of my laptop screen, the image is being erased. How do I create/draw a stable background image that doesn't flicker or erased when dragged?
This code below is what I used for my background image:
public void paint( Graphics g ) {
super.paint(g);
g.drawImage(img, -30, 0, null); //draw image to background
}
Use the JLabel.setIcon(Icon icon) method.
The benefit of this is you don't need to overwrite any method to put a background.
Indeed you can also use JLabel in alternative to JPanel, if you want a container that has an image background. Below can explain this trick in code:
public class JPanelWithBackground extends JLabel {
public JPanelWithBackground() {
add(new JButton("I can attached to JLabel? Isn't cool? "));
setBackgroundImage("path_to_image.png");
}
public void setBackgroundImage(String imagePath) {
setIcon(new ImageIcon(imagePath));
}
}
I am new in Java and I am currently creating a game with graphics. I have this class that extends from JFrame. In this class, I have many JPanels that needs an image as background. As I know, to be able to paint images in the JPanel, I need to have a separate class that extends from JPanel and that class's paintComponent method will do the work. But I don't want to make separate classes for each JPanel, I have too many of them; and with the fact that I am only concerned with the background. How can I do this? is it with an anonymous inner class? How?
For better understanding I provided some code:
public GUI extends JFrame {
private JPanel x;
...
public GUI() {
x = new JPanel();
// put an image background to x
}
Why not make a single class that takes a Image??
public class ImagePane extends JPanel {
private Image image;
public ImagePane(Image image) {
this.image = image;
}
#Override
public Dimension getPreferredSize() {
return image == null ? new Dimension(0, 0) : new Dimension(image.getWidth(this), image.getHeight(this));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(image, 0, 0, this);
g2d.dispose();
}
}
You would even provide hints about where it should be painted.
This way, you could simply create an instance when ever you needed it
Updated
The other question is, why?
You could just use a JLabel which will paint the icon for you without any additional work...
See How to use labels for more details...
This is actually a bad idea, as JLabel does NOT use it's child components when calculating it's preferred size, it only uses the size of the image and the text properties when determining it's preferred size, this can result in the component been sized incorrectly
You don't have to make another class for it? You could just do:
x = new JPanel(){
public void paintComponent(Graphics g){
super.paintComponent(g);
//draw background image
}
};
You can do this in single line:
panelInstance.add(new JLabel(new ImageIcon(ImageIO.read(new File("Image URL")))));
I hope it will work for you.
I need to make an image map using Swing that displays a background image, and then when the mouse hovers over (or clicks) specific hotspots, I need to pop up a 'zoomed-in' image and have it display.
I was thinking of extending JPanel to include an image reference and have that drawn thru the paintComponent(g) method. This part I have done so far, and here's the code:
public class ImagePanel extends JPanel
{
private static final long serialVersionUID = 1L;
private Image image;
public ImagePanel(Image image)
{
setImage(image);
}
public void setImage(Image newImage)
{
image = newImage;
}
#Override
public void paintComponent(Graphics g)
{
Dimension size = getSize();
g.drawImage(image, 0, 0, size.width, size.height, this);
}
Could anyone recommend how I might listen for / respond to mouse clicks over defined hot-spots? Could someone additionally recommend a method for displaying the pop-ups? My gut reaction was to extend JPopupMenu to have it display an image, similar to the above code.
Thanks for any help!
To listen to the mouse clicks implement the MouseListener interface, and add it to your panel. Then when the click is recieved you can use a JPopupMenu as you suggested, or you could even use a glass pane to show the zoomed in image.
I'm guessing you want to achieve something similar to this post by Joshua Marinacci, he has also posted the source here, I would take a look at that.
I would probably:
create some instance of Shape that represents each of your hotspots (could be a plain boring old Rectangle, or see GeneralPath if you need to create fancy shapes)
register a MouseListener which iterates through each of the Shapes and calls its contains() method to see if the clicked coordinate is inside the hotspot in question