0

我有一个paint方法,我已经绘制了一个矩形并将其移动到屏幕上,当矩形离开屏幕以将其移回 JFrame 的开头时,我想要它做什么。我想它会是这样的,if(rectangle.isoffthescreen){ put it back on the screen }但我不知道该怎么做。另外,我想知道你是否可以对 rect 做一些事情JFrame frame = new JFrame();,但显然是针对矩形。如果这令人困惑,我很抱歉。

@MadProgrammer 这是我目前所处的位置

public class main extends JPanel {

public static int place = -350;
public Rectangle rect;
public int xDelta;
   public main() {

       rect = new Rectangle(0, 75, 50, 50);
       xDelta = 4;
       Timer timer = new Timer(40, new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {
               rect.x += xDelta;
               if (rect.x + rect.width > getWidth() - 1) {
                   rect.x = getWidth() - rect.width;
                   xDelta *= -1;
               } else if (rect.x < 0) {
                   rect.x = 0;
                   xDelta *= -1;
               }
               repaint();
           }
       });
       timer.start();

   }

public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g.create();
    Random r = new Random();
    int r1;

    r1 = r.nextInt(5);
    if (r1 == 0) {
        g2d.setColor(Color.WHITE);
    } else if (r1 == 1) {
        g2d.setColor(Color.BLUE);
    } else if (r1 == 2) {
        g2d.setColor(Color.RED);
    } else if (r1 == 3) {
        g2d.setColor(Color.GREEN);
    } else if (r1 == 4) {
        g2d.setColor(Color.PINK);
    } else {
        g2d.setColor(Color.CYAN);
    }

    place += 50;

    rect = new Rectangle(place, 100, 300, 200);
    g2d.draw(rect);
    g2d.fill(rect);
    g2d.dispose();

    try {
        Thread.sleep(400);
    } catch (Exception e) {
    }

    repaint();

}
}

public class frame {

public static JFrame frame;


public static void main(String args[]){
    frame = new JFrame();   
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //frame.setResizable(false);
    frame.setVisible(true);
    frame.setLocationRelativeTo(null);
    main m = new main();
    m.setBackground(Color.BLACK);
    frame.add(m);
}


}

我仍然无法让它工作。

4

1 回答 1

2

首先,您应该避免覆盖paint顶级容器,而是使用扩展自JComponent(如JPanel)的东西并覆盖它的paintComponent.

有很多原因,但在您的情况下,框架包含位于可视区域内的装饰。

基本过程是检查边缘情况......

if (box.x + box.width > getWidth() - 1) {
    // The boxes right edge is beyond the right edge of it's container
} else if (box.x < 0) {
    // The boxes left edge is beyond the left edge of it's container
}

这将检查box' 的右边缘是否超出容器的右边缘以及box' 的左边缘是否超出容器的左边缘。

包括垂直检查也是一个简单的过程。

更新了示例

import java.awt.BorderLayout;
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 javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Move {

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

    public Move() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Rectangle box;
        private int xDelta;

        public TestPane() {

            box = new Rectangle(0, 75, 50, 50);
            xDelta = 4;
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    box.x += xDelta;
                    if (box.x + box.width > getWidth() - 1) {
                        box.x = getWidth() - box.width;
                        xDelta *= -1;
                    } else if (box.x < 0) {
                        box.x = 0;
                        xDelta *= -1;
                    }
                    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();
            g2d.setColor(Color.BLUE);
            g2d.fill(box);
            g2d.dispose();
        }
    }

}

从 OP 的示例代码更新

马上,有很多事情让我担心......

  1. 覆盖paint
  2. 调用方法Thread.sleep_paint
  3. repaintpaint方法内部调用
  4. Rectanglepaint方法中创建一个新的
  5. place对变量的依赖

查看Performing Custom Painting以了解有关在 Swing 中绘画的更多详细信息

您永远不应阻塞或执行长时间运行的事件调度线程处理,这将阻止 EDT 处理(除其他外)绘制请求和新事件。通过调用Thread.sleeppaint方法,您可以阻止 Swing 更新屏幕。

查看Swing 中的并发以获取更多详细信息。

在方法中调用repaint(或任何可能调用repaintpaint方法)肯定会消耗 CPU 周期。

您可能想查看在 AWT 和 Swing 中的绘画,以了解有关 Swing中绘画过程的更多详细信息

Rectangle通过在方法中创建一个新paint方法,您将丢弃所做的任何更改,从而Timer有效地阻止您的矩形有效移动......

place方法不是必需的。动画是随时间变化的错觉,因此使用Timerand xDelta

根据您的代码示例更新

import java.awt.BorderLayout;
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 Move {

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

    public Move() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new Main());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class Main extends JPanel {

        public static int place = -350;
        public Rectangle rect;
        public int xDelta;

        public Main() {

            rect = new Rectangle(0, 75, 50, 50);
            xDelta = 4;
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    rect.x += xDelta;
                    if (rect.x + rect.width > getWidth() - 1) {
                        rect.x = getWidth() - rect.width;
                        xDelta *= -1;
                    } else if (rect.x < 0) {
                        rect.x = 0;
                        xDelta *= -1;
                    }
                    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();
            Random r = new Random();
            int r1;

            r1 = r.nextInt(5);
            if (r1 == 0) {
                g2d.setColor(Color.WHITE);
            } else if (r1 == 1) {
                g2d.setColor(Color.BLUE);
            } else if (r1 == 2) {
                g2d.setColor(Color.RED);
            } else if (r1 == 3) {
                g2d.setColor(Color.GREEN);
            } else if (r1 == 4) {
                g2d.setColor(Color.PINK);
            } else {
                g2d.setColor(Color.CYAN);
            }

//            place += 50;

//            rect = new Rectangle(place, 100, 300, 200);
            g2d.draw(rect);
            g2d.fill(rect);
            g2d.dispose();

        }
    }
}
于 2013-08-07T23:21:57.150 回答