0

四角形を描画して画面上で移動する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);
}


}

私はまだそれを機能させることができません。

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. メソッドrepaint内から呼び出すpaint
  4. メソッドRectangleでの新規作成paint
  5. place変数への依存

Swing でのペイントの詳細については、カスタム ペイントの実行を参照してください。

イベント ディスパッチ スレッドの長時間実行処理をブロックしたり、実行したりしないでください。これにより、EDT が (特に) 描画要求と新しいイベントを処理できなくなります。メソッドを呼び出すことThread.sleepで、paintSwing が画面を更新するのを防ぎます。

詳細については、Swing での同時実行を確認してください。

メソッド内での呼び出しrepaint(または を呼び出す可能性のあるメソッド) は、確実に CPU サイクルを消費します。repaintpaint

Swingでのペイント プロセスの詳細については、Painting in AWT and Swingを参照してください。

メソッドで新しいRectangleを作成することにより、が行った変更を破棄し、四角形が効果的に移動するのを効果的に停止します...paintTimer

placeメソッドは必須ではありません。アニメーションは時間の経過に伴う変化の錯覚であるため、 と を使用しTimerます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 に答える