将油漆保留在JPanel边框内

时间:2013-12-27 20:58:49

标签: java swing jpanel border-layout

所以这就是问题所在:到目前为止,我的程序运行正常,但是这段代码无法正常工作:

pane2 = (new JPanel(){

        private static final long serialVersionUID = 1L;

        @Override
        public void paintComponent(Graphics g){

            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            Ellipse2D.Double circle = new Ellipse2D.Double(randomX,
                                                           randomY,
                                                           randomW,
                                                           randomH);
            g2d.fill(circle);
        }
    });

    pane2.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(10,10,10,10), new LineBorder(Color.BLACK)));

那么程序应该做的基本上是重新绘制面板的内容,基本上随机化每次按下“绘制”按钮时每次绘制椭圆的位置。它可以工作,但它不会将椭圆保持在面板的边框内。是否有可能在不添加某种额外的层(如Container或其他东西)以及向容器添加填充的情况下完成该工作,或者这是唯一的方法(它是否可行)?

按钮代码:

bpaint.addActionListener(new ActionListener(){

                @Override
                public void actionPerformed(ActionEvent e) {

                    randomX = Math.random() * pane2.getHeight();
                    randomY = Math.random() * pane2.getWidth();
                    randomW = Math.random() * 100;
                    randomH = Math.random() * 100;
                    pane2.validate();
                    pane2.repaint();
                }

            });

如果某个地方有这个问题的重复,我道歉。如果有,那肯定没有措辞,我会知道它是重复的。

做了也试图添加一个全局填充变量,但由于EmptyBorder(单位)不是基于Ellipse2D(单位)使用的相同大小,添加一个全局填充变量是一个很好的解决方案充其量,我只能估计比率可能是多少。我认为(或者至少希望)有一种更简单的方法可以让它们保持在边界内 - 准确

2 个答案:

答案 0 :(得分:1)

我认为这不是一个大问题。只需更改计算值的方式。

randomW = Math.random() * 100;
randomH = Math.random() * 100;
randomX = Math.random() * (pane2.getHeight() - randomW) + randomW/2;
randomY = Math.random() * (pane2.getWidth() - randomH) + randomH/2;

希望这适合你。

编辑:更改方程式..

答案 1 :(得分:1)

基本上,JComponent#getInsets将返回组件边框插入。

这是您不应该绘制的每个边缘的空间量,例如将它们视为边距...

所以掌握了这些信息,你可以做类似的事情......

// Random size, minimum size of 10, maximum size of 50
randomW = 10 + (Math.random() * 40);
randomH = 10 + (Math.random() * 40);

// Get the components insets
Insets insets = getInsets();
// Calculate the available size by subtract the sum of the margins...
int width = getWidth() - (insets.left + insets.right);
int height = getHeight() - (insets.top + insets.bottom);

// Calculate a postion that is at minimum, the top/left margin
// but less than the available space minus the size of the shape...
randomX = insets.left + (Math.random() * (width - randomW));
randomY = insets.top + (Math.random() * (height - randomH));

道歉,上面的代码来自以下可运行的示例...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class RandomShape extends JPanel {

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

    public RandomShape() {
        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 class TestPane extends JPanel {

        private double randomX;
        private double randomY;
        private double randomW;
        private double randomH;

        public TestPane() {
                setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(10,10,10,10), new LineBorder(Color.BLACK)));
                Timer timer = new Timer(500, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    random();
                }
            });
            timer.start();
        }

        public void random() {

            randomW = 10 + (Math.random() * 40);
            randomH = 10 + (Math.random() * 40);

            Insets insets = getInsets();
            int width = getWidth() - (insets.left + insets.right);
            int height = getHeight() - (insets.top + insets.bottom);

            randomX = insets.left + (Math.random() * (width - randomW));
            randomY = insets.top + (Math.random() * (height - randomH));

            repaint();
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            Ellipse2D.Double circle = new Ellipse2D.Double(randomX,
                            randomY,
                            randomW,
                            randomH);
            g2d.fill(circle);
            g2d.dispose();
        }

    }

}

因此,您需要将概念拼接到您自己的代码中;)