如何查看Graphics2D中的某些内容是否在帧外

时间:2013-08-07 23:08:55

标签: java swing graphics jframe graphics2d

我有一个paint方法,我绘制了一个矩形并将其移动到屏幕上以及我想要它做什么我当矩形离开屏幕时将其移回JFrame的开头。我认为它会像if(rectangle.isoffthescreen){ put it back on the screen },但我不知道该怎么做。另外,我想知道你是否可以像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);
}


}

我仍然无法让它发挥作用。

1 个答案:

答案 0 :(得分: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方法
  3. 中呼叫paint
  4. repaint方法
  5. 中拨打paint
  6. Rectangle方法
  7. 中创建新的paint
  8. 依赖place变量
  9. 查看Performing Custom Painting,了解有关在Swing中绘画的更多详情

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

    查看Concurrency in Swing了解详情。

    repaint方法中调用repaint(或任何可能调用paint的方法)是消耗CPU周期的可靠方法。

    您可以查看Painting in AWT and Swing以获取有关Swing

    中绘画过程的更多详细信息

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

    不需要place方法。动画是随时间变化的幻觉,因此使用了TimerxDelta

    根据您的代码示例更新

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