如何使用滑块更改用Java Graphics2D制作的图形的大小? [英] How can I change the size of a figure made in Java Graphics2D with a slider?

查看:122
本文介绍了如何使用滑块更改用Java Graphics2D制作的图形的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用使用Graphics 2D的Java编写一个程序,该程序可以绘制3到8面之间的多边形,并且可以使用滑块调整大小,但是我不知道如何用滑块均匀地更改其大小. /p>

这是我绘制的五边形的一个例子

if (sides == 5){
        g.drawLine(110+x,135-y, 10+x,205-y);
        g.drawLine(10+x,205-y, 48+x, 320-y);
        g.drawLine(48+x,320-y, 170+x,320-y);
        g.drawLine(170+x,320-y, 205+x,205-y);
        g.drawLine(205+x,205-y, 110+x,135-y);
    }

现在,我要均匀地更改其大小. (我可以在X和Y轴上移动多边形.)

提前谢谢.

解决方案

您可以...

使用 AffineTransformation 缩放Graphics上下文

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane tp = new TestPane();

                JSlider slider = new JSlider(10, 200);
                slider.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        tp.setScale(slider.getValue());
                    }
                });
                slider.setValue(100);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(tp);
                frame.add(slider, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int scale = 100;

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(250, 350);
        }

        public void setScale(int value) {
            if (value != scale) {
                int old = scale;
                this.scale = value;
                firePropertyChange("scale", old, scale);
                repaint();
            }
        }

        public int getScale() {
            return scale;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            double scaleValue = getScale() / 100d;
            System.out.println(scaleValue);
            AffineTransform at = AffineTransform.getScaleInstance(scaleValue, scaleValue);
            g2d.setTransform(at);

            int x = 10;
            int y = 10;

            g2d.drawLine(110 + x, 135 - y, 10 + x, 205 - y);
            g2d.drawLine(10 + x, 205 - y, 48 + x, 320 - y);
            g2d.drawLine(48 + x, 320 - y, 170 + x, 320 - y);
            g2d.drawLine(170 + x, 320 - y, 205 + x, 205 - y);
            g2d.drawLine(205 + x, 205 - y, 110 + x, 135 - y);
            g2d.dispose();
        }

    }

}

这将同时缩放大小和位置,这可能是不希望的...

您可以...

请改用2D图形形状API.这将允许您独立定义形状,并根据需要简单地对其进行绘制.这样做的好处是您可以更好地控制变换,在不改变位置的情况下变换比例尺

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane tp = new TestPane();

                JSlider slider = new JSlider(10, 200);
                slider.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        tp.setScale(slider.getValue());
                    }
                });
                slider.setValue(100);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(tp);
                frame.add(slider, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int scale = 100;
        private PentegonShape pentegonShape;

        public TestPane() {
            pentegonShape = new PentegonShape(100, 100);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(250, 350);
        }

        public void setScale(int value) {
            if (value != scale) {
                int old = scale;
                this.scale = value;
                firePropertyChange("scale", old, scale);
                repaint();
            }
        }

        public int getScale() {
            return scale;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int x = 10;
            int y = 10;

            double scaleValue = getScale() / 100d;
            Shape shape = AffineTransform.getScaleInstance(scaleValue, scaleValue).createTransformedShape(pentegonShape);
            g2d.setTransform(AffineTransform.getTranslateInstance(x, y));
            g2d.draw(shape);
            g2d.dispose();
        }

    }

    public class PentegonShape extends Path2D.Double {

        public PentegonShape(double width, double height) {
            moveTo(width / 2, 0);
            lineTo(width, height / 3d);
            lineTo((width / 5d) * 4, height);
            lineTo((width / 5d), height);
            lineTo(0, height / 3d);
            closePath();
        }

    }

}

看看 2D图形 解决方案

You could...

Use a AffineTransformation to scale the Graphics context

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane tp = new TestPane();

                JSlider slider = new JSlider(10, 200);
                slider.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        tp.setScale(slider.getValue());
                    }
                });
                slider.setValue(100);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(tp);
                frame.add(slider, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int scale = 100;

        public TestPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(250, 350);
        }

        public void setScale(int value) {
            if (value != scale) {
                int old = scale;
                this.scale = value;
                firePropertyChange("scale", old, scale);
                repaint();
            }
        }

        public int getScale() {
            return scale;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            double scaleValue = getScale() / 100d;
            System.out.println(scaleValue);
            AffineTransform at = AffineTransform.getScaleInstance(scaleValue, scaleValue);
            g2d.setTransform(at);

            int x = 10;
            int y = 10;

            g2d.drawLine(110 + x, 135 - y, 10 + x, 205 - y);
            g2d.drawLine(10 + x, 205 - y, 48 + x, 320 - y);
            g2d.drawLine(48 + x, 320 - y, 170 + x, 320 - y);
            g2d.drawLine(170 + x, 320 - y, 205 + x, 205 - y);
            g2d.drawLine(205 + x, 205 - y, 110 + x, 135 - y);
            g2d.dispose();
        }

    }

}

This is going to scale both the size and position though, which may not be desirable...

You could...

Use the 2D Graphics shape API instead. This will allow you to define a shape, independently and simply paint it as you need. The benefit of this is you can control the transformation better, transforming the scale without transforming the position

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane tp = new TestPane();

                JSlider slider = new JSlider(10, 200);
                slider.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        tp.setScale(slider.getValue());
                    }
                });
                slider.setValue(100);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(tp);
                frame.add(slider, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int scale = 100;
        private PentegonShape pentegonShape;

        public TestPane() {
            pentegonShape = new PentegonShape(100, 100);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(250, 350);
        }

        public void setScale(int value) {
            if (value != scale) {
                int old = scale;
                this.scale = value;
                firePropertyChange("scale", old, scale);
                repaint();
            }
        }

        public int getScale() {
            return scale;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            int x = 10;
            int y = 10;

            double scaleValue = getScale() / 100d;
            Shape shape = AffineTransform.getScaleInstance(scaleValue, scaleValue).createTransformedShape(pentegonShape);
            g2d.setTransform(AffineTransform.getTranslateInstance(x, y));
            g2d.draw(shape);
            g2d.dispose();
        }

    }

    public class PentegonShape extends Path2D.Double {

        public PentegonShape(double width, double height) {
            moveTo(width / 2, 0);
            lineTo(width, height / 3d);
            lineTo((width / 5d) * 4, height);
            lineTo((width / 5d), height);
            lineTo(0, height / 3d);
            closePath();
        }

    }

}

Have a look at 2D Graphics and Working with Geometry in particular

这篇关于如何使用滑块更改用Java Graphics2D制作的图形的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆