How to rotate JXImagePanel?

非 Y 不嫁゛ 提交于 2019-12-29 09:29:06

问题


I would to rotate JXImagePanel. It should be possible - this is about JXImagePanel:

  • Swing :: JXImagePanel

While JLabel and JButton allow you to easily add images to your Swing applications, the JXImagePanel makes it trivially easy to add any BufferedImage or Icon to your Swing applications.

If editable, it also provides a way for the user to change the image. In addition, the JXImagePanel provides many built in effects out-of-the-box, including Tiling, Scaling, Rotating, Compositing, and more.

However, I cannot figure out how to do this. Currently my code snippet is:

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

Now I would like to rotate it in 0-360 degrees. How it can be done?


回答1:


JXImagePanel is deprecated (actually, made package private as of 1.6.2, because it's still used internally), so better not use is, will be removed soon.

Instead, use a JXPanel with an ImagePainter and an arbitrary transformOp applied to the painter, in code snippets something like:

    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);

you'll probably have to play a bit to get the exact effects you want to achieve. On problems, you might want to try posting to the Swinglabs forum.




回答2:


I don't know somethimg more about SwingX's JXImagePanel but for plain vanilla Swing there exists excelent workaround (by aephyr or tjacobs or ... I hate this endless-mess from old.forums.sun.com by Sn'Oracle eerrrght)

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();
                }
            }
        });
    }
}


来源:https://stackoverflow.com/questions/6993467/how-to-rotate-jximagepanel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!