在 JFrame 中生成方波
Posted
技术标签:
【中文标题】在 JFrame 中生成方波【英文标题】:Generate square wave in JFrame 【发布时间】:2016-05-24 14:34:46 【问题描述】:我的方波代码效率低下。我有 2 个按钮、1 个表格和类似正方形出现的坐标系。我希望波浪实时滚动/移动,直到它到达坐标系的末端,而不是仅仅通过选择两个按钮来显示。另外,如果有人有更好的绘制方波的方法,请告诉我。
public void paint(Graphics g)
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawLine(20, 300, 20, 450);
g2d.drawLine(20, 350, 400, 350);
g2d.drawLine(20, 400, 400, 400);
g2d.drawLine(20, 450, 400, 450);
if (this.jButtonSTART.isSelected() & this.jButtonAND.isSelected())
this.draw(g2d);
public void draw(Graphics2D g2d)
boolean up = true;
while (x <= 380)
g2d.setColor(Color.blue);
if (x > 0 && x % 95 == 0)
up = !up;
g2d.drawLine(20 + x, up ? 315 : 350 + y, 20 + x, up ? 350 : 315 + y);
else
if (up)
g2d.drawLine(20 + x, 315 + y, 21 + x, y + 315);
else
g2d.drawLine(20 + x, 350 + y, 21 + x, y + 350);
x++;
x = 0;
【问题讨论】:
【参考方案1】:绘制方波并移动它的简单方法:
-
创建一个比 GUI 更长的 BufferedImage。它的长度应与方波的周期相匹配,并且至少是显示它的 GUI 组件的两倍。
在 JPanel 的paintComponent 方法覆盖中绘制,而不是在paint 方法中。
首先在您的覆盖中调用 super 的 paintComponent 方法。
您将使用
g.drawImage(myImage, imageX, imageY, this)
绘制图像,其中 imageX 和 imageY 是 JPanel 扩展绘图类的私有实例字段。
在 Swing Timer 中,随着 Timer 的每个滴答声(即每次调用其 ActionListener 的 actionPerformed 方法)推进 imageX)。
然后在同一个 actionPerformed 方法中对绘图 JPanel 调用 repaint()
。
完成。
例如,请注意,此代码并没有完全按照您的意图执行,但确实显示了使用 Swing Timer 和 paintComponent 的 Swing 动画示例。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class MoveWave extends JPanel
private static final int PREF_W = 400;
private static final int PREF_H = 200;
private static final int TIMER_DELAY = 40;
public static final int DELTA_X = 2;
public static final int STARTING_MY_IMAGE_X = -PREF_W;
private static final Color COLOR_1 = Color.RED;
private static final Color COLOR_2 = Color.BLUE;
private static final Color BG = Color.BLACK;
private static final int CIRCLE_COUNT = 10;
private BufferedImage myImage = null;
private int myImageX = STARTING_MY_IMAGE_X;
private int myImageY = 0;
public MoveWave()
setBackground(BG);
myImage = new BufferedImage(2 * PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = myImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(new GradientPaint(0, 0, COLOR_1, 20, 20, COLOR_2, true));
for (int i = 0; i < CIRCLE_COUNT; i++)
int x = (i * 2 * PREF_W) / CIRCLE_COUNT;
int y = PREF_H / 4;
int width = (2 * PREF_W) / CIRCLE_COUNT;
int height = PREF_H / 2;
g2.fillOval(x, y, width, height);
g2.dispose();
new Timer(TIMER_DELAY, new TimerListener()).start();
@Override
protected void paintComponent(Graphics g)
super.paintComponent(g);
if (myImage != null)
g.drawImage(myImage, myImageX, myImageY, this);
@Override
public Dimension getPreferredSize()
if (isPreferredSizeSet())
return super.getPreferredSize();
return new Dimension(PREF_W, PREF_H);
private class TimerListener implements ActionListener
@Override
public void actionPerformed(ActionEvent e)
myImageX += DELTA_X;
if (myImageX >= 0)
myImageX = STARTING_MY_IMAGE_X;
repaint();
private static void createAndShowGui()
JFrame frame = new JFrame("MoveWave");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MoveWave());
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
public static void main(String[] args)
SwingUtilities.invokeLater(() -> createAndShowGui());
【讨论】:
你的计时器的 actionPerformed 方法应该在 imageX 达到一个完整波长时重置它。并且您还应该添加一个 ComponentListener,其 componentResized() 方法为组件的新大小重新创建图像。 @FredK: true,或者对于我的示例程序(见上文),我只是固定 GUI 的大小。 @Hovercraft Full of Eels 非常感谢您的帮助!我真的只是一个初学者,所以我很难理解你的步骤。在第二步之后你失去了我。你能再详细一点吗?我假设您希望我创建 paintComponent 方法,因为我没有 @Nest:首先阅读关于 Swing 图形的教程:* Lesson: Performing Custom Painting以上是关于在 JFrame 中生成方波的主要内容,如果未能解决你的问题,请参考以下文章