繁体   English   中英

如何在随机坐标上绘制一个随机大小的圆圈,使圆圈完全可见?

[英]How to paint a circle with a random size on a random coordinate such that the circle is fully visible?

码:

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将添加到JFrame,其大小使用setSize(FRAME_WIDTH, FRAME_HEIGHT);

但问题是,有时候,圆圈的一半是在JPanel外面的一半和一半:

屏幕截图

我哪里做错了?

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

应该允许您产生不会落在可视区域之外的结果,因为尺寸的最大范围是容器的当前尺寸减去所需的尺寸,请注意,如果可用尺寸小于MAX_SIZE ,您将有问题;)

该示例每秒生成一个新圆圈

随机圆圈

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

    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM