【问题标题】:How to paint a circle with a random size on a random coordinate such that the circle is fully visible?如何在随机坐标上绘制一个随机大小的圆,使圆完全可见?
【发布时间】:2015-07-03 05:43:17
【问题描述】:

代码:

Random rand = new Random();
JPanel mainPanel;

int randomSize = 0; 
int randomPositionX = 0;
int randomPositionY = 0;

final static int FRAME_HEIGHT = 500;
final static int FRAME_WIDTH  = 500;

final static int TITLE_BAR    = 30 ;

final static int MAX_SIZE     = 100;
final static int MIN_SIZE     = 10 ;

/* All the below code is put into a method */

mainPanel = new JPanel(){   
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.RED);
        g.fillOval(randomPositionY, randomPositionX, randomSize, randomSize);
    }
};

do{
    randomSize = rand.nextInt(MAX_SIZE) + 1;
}while(randomSize < MIN_SIZE);

do{
    randomPositionX = rand.nextInt(FRAME_WIDTH);
    randomPositionY = rand.nextInt(FRAME_HEIGHT);
}while((randomPositionX + randomSize > FRAME_WIDTH) || (randomPositionY + randomSize > FRAME_HEIGHT - TITLE_BAR));

repaint();

我想要的是具有随机大小的圆,使其最小大小为 10,最大大小为 100。圆还应该以随机坐标绘制,以使圆完全在 JPanel mainPanel 中可见

请注意,mainPanel 将添加到使用 setSize(FRAME_WIDTH, FRAME_HEIGHT); 设置大小的 JFrame。

但问题是,有时,圆圈的一部分在JPanel的外面一半在里面:

我哪里做错了?

【问题讨论】:

    标签: java swing random paintcomponent


    【解决方案1】:
    1. 当框架包含可变的高标题栏和框架插图时,您在计算圆的位置时尝试使用框架大小
    2. 您正在尝试使用不相关的框架大小,这是您应该使用的组件大小,因为它位于您要绘制的 mainPanel 的坐标上下文中

    那么,我该如何解决这些问题?

    丢弃所有帧“填充”/“偏移”。 mainPanel 有它自己的坐标上下文(它的左上角将是0x0),它将在它的父坐标上下文中,所以你不需要关心框架或它的插图。

    简化您的计算,例如...

    int randomSize = MIN_SIZE + (rand.nextInt(MAX_SIZE) + 1);
    
    int randomPositionX = rand.nextInt(getWidth() - randomSize);
    int randomPositionY = rand.nextInt(getHeight() - randomSize);
    

    应该允许您生成不会超出可视区域的结果,因为尺寸的最大范围是容器的当前尺寸减去所需尺寸,请注意,如果可用尺寸小于 @ 987654326@,你会有问题;)

    示例每秒生成一个新圆圈

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    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();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public static class TestPane extends JPanel {
    
            public final static int MAX_SIZE = 100;
            public final static int MIN_SIZE = 10;
            private Rectangle bounds;
            private Random rand;
    
            public TestPane() {
                rand = new Random();
                Timer timer = new Timer(1000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
    
                        int randomSize = MIN_SIZE + (rand.nextInt(MAX_SIZE) + 1);
    
                        int randomPositionX = rand.nextInt(getWidth() - randomSize);
                        int randomPositionY = rand.nextInt(getHeight() - randomSize);
    
                        bounds = new Rectangle(randomPositionX, randomPositionY, randomSize, randomSize);
                        repaint();
                    }
                });
                timer.start();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                if (bounds != null) {
                    g2d.setColor(Color.RED);
                    g2d.fillOval(bounds.x, bounds.y, bounds.width, bounds.height);
                }
                g2d.dispose();
            }
    
        }
    
    }
    

    【讨论】:

    • 那么,我该如何解决这些问题?
    • @CoolGuy 丢弃所有框架引用并关注组件的实际大小
    猜你喜欢
    • 1970-01-01
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多