嗨!
我使用之前的Stackoverflow帖子获得了以下代码。
我想将矩形旋转一定角度,然后让它在sin波中移动。
此代码也会旋转整个sin波。
我明白为什么会这样,但我不知道如何实现我的意图。
请帮助!!!
非常感谢您花时间。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Withrotation {
public static int i = 1;
public static Ticker t;
public static Repainter r;
public static int newx, newy;
public static void main(String[] args) {
final JFrame frame = new JFrame("Wavy!");
final WavyPanel wp = new WavyPanel();
frame.getContentPane().add(wp, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t = new Ticker(wp);
r = new Repainter(wp);
frame.pack();
frame.setVisible(true);
final Timer tickTimer = new Timer();
final Timer paintTimer = new Timer();
paintTimer.schedule(r, 1000, 50);
tickTimer.schedule(t, 1000, 10);
}
private static class WavyPanel extends JPanel {
private final Dimension size = new Dimension(640, 480);
private int amplitude = 50;
private int frequency = 5;
private double x1 = 0;
private double y1 = 500;
private int yBase = 0;
WavyPanel() {
super(true);
}
@Override
protected void paintComponent(final Graphics g) {
final Graphics2D g2 = (Graphics2D) g;
AffineTransform old = g2.getTransform();
g2.rotate(Math.toRadians(-30));
g2.clearRect(0, 0, this.getSize().width, this.getSize().height);
g2.setColor(Color.BLACK);
g2.fillRect((int) x1, (int) y1, 20, 80);
g2.setTransform(old);
}
@Override
public Dimension getPreferredSize() {
return size;
}
@Override
public Dimension getMinimumSize() {
return size;
}
@Override
public Dimension getMaximumSize() {
return size;
}
public void tick() {
x1 = x1 + 1;
final int waveLength = size.width / frequency;
yBase = (++yBase) % waveLength;
final double normalized = (double) yBase / (double) waveLength;
final double radians = normalized * Math.PI * 2;
final double sine = Math.sin(radians);
y1 = (int) (sine * amplitude);
}
}
private static class Ticker extends TimerTask {
private final WavyPanel panel;
Ticker(final WavyPanel panel) {
this.panel = panel;
}
@Override
public void run() {
panel.tick();
}
}
private static class Repainter extends TimerTask {
private final WavyPanel panel;
Repainter(final WavyPanel panel) {
this.panel = panel;
}
@Override
public void run() {
panel.repaint();
}
}
}
答案 0 :(得分:5)
+1 SSCCE
1)不要忘记在被覆盖的super.paintComponent();
方法中调用paintComponent(..)
作为第一个语句。
2)应在EDT上创建Swing UI,并与Swing Timers
一起使用 3)类的Java变量命名约定是每个新单词的大写字母,即WithRotation
。
4)frame.getContentPane.add(..)
无需使用add(..)
,因为所有呼叫都会转发到 contentPane 。
以下是我所做的示例(基本上是您的代码已实现上述修复),它只使用AffineTransform#createTransformedShape()
旋转图形后面的矩形而不是整个图形对象:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.geom.AffineTransform;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class WithRotation {
private JFrame frame;
private WavyPanel wp;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new WithRotation();
}
});
}
public WithRotation() {
initComponents();
}
private void initComponents() {
frame = new JFrame("Wavy!");
wp = new WavyPanel();
frame.add(wp, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
createAndStartTimers();
}
private void createAndStartTimers() {
new Timer(50, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
wp.repaint();
}
}).start();
new Timer(10, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
wp.tick();
}
}).start();
}
class WavyPanel extends JPanel {
private final Dimension size = new Dimension(640, 480);
private int amplitude = 50;
private int frequency = 5;
private double x1 = 0;
private double y1 = 500;
private int yBase = 0;
WavyPanel() {
super(true);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.clearRect(0, 0, this.getSize().width, this.getSize().height);
g2.setColor(Color.BLACK);
Rectangle rect = new Rectangle((int) x1, (int) y1, 20, 80);
AffineTransform transform = new AffineTransform();
transform.rotate(Math.toRadians(-30), rect.getX() + rect.width / 2, rect.getY() + rect.height / 2);
Shape transformed = transform.createTransformedShape(rect);
g2.fill(transformed);
}
@Override
public Dimension getPreferredSize() {
return size;
}
@Override
public Dimension getMinimumSize() {
return size;
}
@Override
public Dimension getMaximumSize() {
return size;
}
public void tick() {
x1 = x1 + 1;
final int waveLength = size.width / frequency;
yBase = (++yBase) % waveLength;
final double normalized = (double) yBase / (double) waveLength;
final double radians = normalized * Math.PI * 2;
final double sine = Math.sin(radians);
y1 = (int) (sine * amplitude);
}
}
}