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

前端 未结 1 1904
时光说笑
时光说笑 2020-12-22 11:49

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 cha

相关标签:
1条回答
  • 2020-12-22 12:50

    You could...

    Use a AffineTransformation to scale the Graphics context

    Scale

    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

    Scaled Shape

    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

    0 讨论(0)
提交回复
热议问题