How can I change the size of a figure made in Java Graphics2D with a slider?

北城以北 提交于 2020-01-10 06:16:38

问题


I'm trying to make a program with java using Graphics 2D that paints polygons between 3 and 8 sides and that I can resized with a slider but I do not know how to do for change it size with the slider evenly.

Here is a example of my pentagon drawn

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

Now I want to change its size evenly. (I can move my polygon in X and Y axis).

Thanks in advance.


回答1:


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



来源:https://stackoverflow.com/questions/29067700/how-can-i-change-the-size-of-a-figure-made-in-java-graphics2d-with-a-slider

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