如何旋转JXImagePanel?

时间:2011-08-09 08:39:50

标签: java image swing rotation swingx

我想旋转JXImagePanel。它应该是可能的 - 这是关于JXImagePanel

虽然JLabelJButton允许您轻松地将图像添加到Swing应用程序, JXImagePanel可以轻松地将任何BufferedImageIcon添加到您的Swing应用程序中。

如果可编辑,它还为用户提供了更改图像的方法。此外,JXImagePanel提供了许多开箱即用的内置效果, 包括TilingScalingRotatingCompositing等。

然而,我无法弄清楚如何做到这一点。目前我的代码片段是:

bufferedImage = ImageIO.read(new File("image.png"));            
image = new ImageIcon(bufferedImage).getImage();
tempImage = image.getScaledInstance(100, 150, Image.SCALE_FAST);
this.deskJXImagePanel.setImage(tempImage);

现在我想以0-360度旋转它。怎么做?

2 个答案:

答案 0 :(得分:3)

不推荐使用JXImagePanel(实际上,从1.6.2开始将包设为私有,因为它仍然在内部使用),所以最好不要使用is,将很快删除。

相反,使用带有ImagePainter的JXPanel和应用于painter的任意transformOp,代码片段如下:

    JXPanel panel = new JXPanel();
    ImagePainter image = new ImagePainter(myImage);
    image.setFilters(
            new AffineTransformOp(AffineTransform.getRotateInstance(-Math.PI * 2 / 8, 100, 100), null) 
            );
    panel.setBackgroundPainter(image);

你可能需要玩一点才能获得你想要达到的确切效果。在问题上,您可能想尝试发布到Swinglabs论坛。

答案 1 :(得分:2)

我不知道有关SwingX's JXImagePanel的更多信息,但对于简单的香草Swing,存在极好的解决方法(通过aephyr或tjacobs或......我讨厌来自old.forums.sun.com的无尽的混乱'Oracle eerrrght)

enter image description here

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.filechooser.*;

public class RotatableImageComponent extends JComponent {

    private static final long serialVersionUID = 1L;
    private Image image;
    private double angle = 0;
    private MyObservable myObservable;

    public RotatableImageComponent() {
        myObservable = new MyObservable();
    }

    public RotatableImageComponent(Image image) {
        this();
        this.image = image;
    }

    public Image getImage() {
        return image;
    }

    public void setImage(Image image) {
        this.image = image;
    }

    public double getAngle() {
        return angle;
    }

    public void setAngle(double angle) {
        if (angle == this.angle) {
            return;
        }
        this.angle = angle;
        double circle = Math.PI * 2;
        while (angle < 0) {
            angle += circle;
        }
        while (angle > circle) {
            angle -= circle;
        }
        if (myObservable != null) {
            myObservable.setChanged();
            myObservable.notifyObservers(this);
        }
        repaint();
    }

    /**
     * In the rotation events sent to the listener(s), the second argument
     * (the value) will be a reference to the RotatableImageComponent. One then
     * should call getAngle() to get the new value.
     * @param o
     */
    public void addRotationListener(Observer o) {
        myObservable.addObserver(o);
    }

    public void removeRotationListener(Observer o) {
        myObservable.deleteObserver(o);
    }

    public void rotateClockwise(double rotation) {
        setAngle(getAngle() + rotation);
    }

    public void rotateCounterClockwise(double rotation) {
        //setAngle(getAngle() - rotation);
        rotateClockwise(-rotation);
    }

    @Override
    public void paintComponent(Graphics g) {
        if (image == null) {
            super.paintComponent(g);
            return;
        }
        Graphics2D g2 = (Graphics2D) g;
        AffineTransform trans = AffineTransform.getTranslateInstance(getWidth() / 2, getHeight() / 2);
        trans.rotate(angle);
        trans.translate(-image.getWidth(null) / 2, -image.getHeight(null) / 2);
        g2.transform(trans);
        g2.drawImage(image, 0, 0, null);
    }

    @Override
    public Dimension getPreferredSize() {
        if (image == null) {
            return super.getPreferredSize();
        }
        int wid = image.getWidth(null);
        int ht = image.getHeight(null);
        int dist = (int) Math.ceil(Math.sqrt(wid * wid + ht * ht));
        return new Dimension(dist, dist);
    }

    public static class TimedRotation {

        private RotatableImageComponent comp;
        private long totalTime, startTime;
        private double toRotate, startRotation;
        private int interval;
        public Timer myTimer;
        private myAction mAction;

        public TimedRotation(RotatableImageComponent comp, double toRotate, long totalTime, int interval) {
            //super(interval, new myAction());
            this.comp = comp;
            this.totalTime = totalTime;
            this.toRotate = toRotate;
            this.startRotation = comp.getAngle();
            this.interval = interval;
        }

        public void start() {
            if (mAction == null) {
                mAction = new myAction();
            }
            if (myTimer == null) {
                myTimer = new Timer(interval, new myAction());
                myTimer.setRepeats(true);
            } else {
                myTimer.setDelay(interval);
            }
            myTimer.start();
            startTime = System.currentTimeMillis();
        }

        public void stop() {
            myTimer.stop();
        }

        private class myAction implements ActionListener {

            @Override
            public void actionPerformed(ActionEvent ae) {
                long now = System.currentTimeMillis();
                if (totalTime <= (now - startTime)) {
                    comp.setAngle(startRotation + toRotate);
                    stop();
                    return;
                }
                double percent = (double) (now - startTime) / totalTime;
                double rotation = toRotate * percent;
                comp.setAngle(startRotation + rotation);
            }
        }
    }

    private class MyObservable extends Observable {

        @Override
        protected void setChanged() {
            super.setChanged();
        }
    }

    public static class RotationKeys extends KeyAdapter {

        private RotatableImageComponent comp;
        private double rotationAmt;

        public RotationKeys(RotatableImageComponent comp, double rotationAmt) {
            this.comp = comp;
            this.rotationAmt = rotationAmt;
        }

        public RotationKeys(RotatableImageComponent comp) {
            this(comp, Math.PI / 90);
        }

        @Override
        public void keyPressed(KeyEvent ke) {
            if (ke.getKeyCode() == KeyEvent.VK_LEFT) {
                comp.rotateCounterClockwise(rotationAmt);
            } else if (ke.getKeyCode() == KeyEvent.VK_RIGHT) {
                comp.rotateClockwise(rotationAmt);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    FileFilter filter = new FileNameExtensionFilter("JPEG file", "jpg", "jpeg");
                    JFileChooser chooser = new JFileChooser();
                    chooser.addChoosableFileFilter(filter);
                    if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
                        File f = chooser.getSelectedFile();
                        BufferedImage im = ImageIO.read(f);
                        final RotatableImageComponent c = new RotatableImageComponent(im);
                        c.addRotationListener(new Observer() {

                            @Override
                            public void update(Observable arg0, Object arg1) {
                                System.out.println("Angle changed: " + ((RotatableImageComponent) arg1).getAngle());
                            }
                        });
                        JPanel controls = new JPanel(new FlowLayout());
                        final JTextField rotation = new JTextField();
                        rotation.setText("30");
                        controls.add(new JLabel("Rotation(degrees)"));
                        controls.add(rotation);
                        final JTextField time = new JTextField();
                        time.setText("1000");
                        time.setColumns(6);
                        rotation.setColumns(7);
                        controls.add(new JLabel("Time(millis)"));
                        controls.add(time);
                        JButton go = new JButton("Go");
                        go.addActionListener(new ActionListener() {

                            @Override
                            public void actionPerformed(ActionEvent ae) {
                                TimedRotation tr = new TimedRotation(c,
                                        Double.parseDouble(rotation.getText()) / 180 * Math.PI,
                                        Integer.parseInt(time.getText()), 50);
                                tr.start();
                            }
                        });
                        controls.add(go);
                        RotationKeys keys = new RotationKeys(c);
                        c.addKeyListener(keys);
                        c.setFocusable(true);
                        JFrame jf1 = new JFrame();
                        jf1.getContentPane().add(c);
                        JFrame jf2 = new JFrame();
                        jf2.getContentPane().add(controls);
                        jf1.pack();
                        jf2.pack();
                        jf1.setLocation(100, 100);
                        jf2.setLocation(400, 100);
                        jf1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                        jf2.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
                        jf1.setVisible(true);
                        jf2.setVisible(true);
                    }
                } catch (Throwable t) {
                    t.printStackTrace();
                }
            }
        });
    }
}