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のサンプルコードからの更新
急に色々と気になる…。
- オーバーライド
paint
- メソッド
Thread.sleep
の呼び出しpaint
- メソッド
repaint
内から呼び出すpaint
- メソッド
Rectangle
での新規作成paint
place
変数への依存
Swing でのペイントの詳細については、カスタム ペイントの実行を参照してください。
イベント ディスパッチ スレッドの長時間実行処理をブロックしたり、実行したりしないでください。これにより、EDT が (特に) 描画要求と新しいイベントを処理できなくなります。メソッドを呼び出すことThread.sleep
で、paint
Swing が画面を更新するのを防ぎます。
詳細については、Swing での同時実行を確認してください。
メソッド内での呼び出しrepaint
(または を呼び出す可能性のあるメソッド) は、確実に CPU サイクルを消費します。repaint
paint
Swingでのペイント プロセスの詳細については、Painting in AWT and Swingを参照してください。
メソッドで新しいRectangle
を作成することにより、が行った変更を破棄し、四角形が効果的に移動するのを効果的に停止します...paint
Timer
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();
}
}
}