如何旋转JXImagePanel?

发布于 2024-11-28 12:08:19 字数 880 浏览 2 评论 0原文

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

虽然 JLabelJButton 允许您轻松地将图像添加到 Swing 应用程序中, JXImagePanel 使得向 Swing 应用程序添加任何 BufferedImageIcon 变得非常简单。

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

但是,我不知道该怎么做。目前我的代码片段是:

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度。怎样才能做到呢?

I would to rotate JXImagePanel. It should be possible - this is about 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦冥 2024-12-05 12:08:19

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

相反,使用带有 ImagePainter 的 JXPanel 和应用于画家的任意 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 论坛上发帖。

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.

゛时过境迁 2024-12-05 12:08:19

我不知道更多关于 SwingX 的 JXImagePanel 的事情,但是对于普通的 Swing 来说,存在优秀的解决方法(由 aephyr 或 tjacobs 或......我讨厌来自 old.forums.sun.com 的这种无休止的混乱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();
                }
            }
        });
    }
}

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)

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();
                }
            }
        });
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文