0

I am trying to create a panel where I will have the possibility to zoom on custom made JComponent objects. I have tried to call the scale() method in the AffineTransform class with different values, but I have not succeeded. My objects just disappear.

Below is my component that is used in the main frame class. Everything works except the zooming. Could some of you explain the concepts of AffineTransform. I don´t think the JavaDoc explenation is enough for me.

Here is an executable SSCCE:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import javax.swing.JComponent;
import javax.swing.JFrame;


public class JavaApplication1 extends JFrame {

    public static void main(String[] args) {
        new JavaApplication1();
    }

    private MyComponent myComponent = new MyComponent();

    public JavaApplication1() throws HeadlessException {
        this.setSize(400,400);
        this.setVisible(true);
        this.add(myComponent);
    }
    class MyComponent extends JComponent {

        private int x, y;
        private double scale=1;
        private MouseAdapter mouseAdapter = new MouseAdapter();
        private AffineTransform transform = new AffineTransform();

        public MyComponent() {
            this.addMouseListener(mouseAdapter);
            this.addMouseWheelListener(mouseAdapter);
            this.addMouseMotionListener(mouseAdapter);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D)g;
            g2.setColor(Color.DARK_GRAY);
            g2.fillRect(0, 0, 400, 400);
            g2.setColor(Color.RED);
            g2.setTransform(transform);

            transform.scale(scale, scale); 
            g2.drawString("My String!", x, y);
        }

        private class MouseAdapter implements MouseWheelListener, MouseListener, MouseMotionListener {

            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                if(e.getWheelRotation() == 1) {
                    scale+=0.1;
                }else {
                    scale-=0.1;
                }
            }

            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {            
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                x = e.getX();
                y = e.getY();
                repaint();
            }

            @Override
            public void mouseMoved(MouseEvent e) {
            }        
        }
    }   
}
Rox
  • 2,647
  • 15
  • 50
  • 85
  • For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Jan 26 '13 at 11:34
  • Take a look at `JLayer` (`JXLayer` had the capacity to do this use PBJar's extended library, it shouldn't be impossible to apply those same techniques to `JLayer`). You should also be calling `super.paintComponent`. You have a bunch of other considerations as well, including scaling the size (or preferred size) of the component – MadProgrammer Jan 26 '13 at 11:38
  • @AndrewThompson: Ok, I have updated my post with a SSCCE now. – Rox Jan 26 '13 at 11:40
  • 1
    Note that `new AffineTransform()` gives you the [_identity transformation_](http://en.wikipedia.org/wiki/Identity_function). – trashgod Jan 26 '13 at 12:02

1 Answers1

3

transform.scale accepts two double parameters, one for the x axis and the other for the y axis, being 1 the neutral value (no change in scale), and the two parameters the multipliers.

Ex: transform.scale(2,2) will show the component twice as big, while transform.scale(0.5,0.5) will show it twice as small.

http://docs.oracle.com/javase/6/docs/api/java/awt/geom/AffineTransform.html#scale(double, double)

Gothmog
  • 871
  • 1
  • 8
  • 20
  • I tried to hardcode it to `scale(1.1, 1.1)` but the object just disappears after a while on every repaint. – Rox Jan 26 '13 at 12:06
  • The parameters act as multiplier, so if you call scale (1.1, 1.1) each time you repaint, it's expected behaviour the component will grow eacht time. – Gothmog Jan 26 '13 at 12:09
  • @Gothmog: Then I expect that the object will decrease in size if I call the scale() with negative numbers? I tried but it didn´t work (look at my code above, I changed the mouseWheelMoved method). – Rox Jan 26 '13 at 12:18
  • 2
    @Rox, not negative numbers, but numbers between 0 and 1 (eg: 0.5) – Gothmog Jan 26 '13 at 15:00
  • @Gothmog: The object also moves to another location. Do I have to take `AffineTransform.translate` in mind when calling `scale()`? – Rox Jan 27 '13 at 19:47