在非常基本的术语中,我有一个面板逐个像素地绘制一条线,并且正在实时更新。除此之外,我想要另一个面板,它围绕当前像素绘制一个框,但稍后会自行清除。两者都是实时的
我目前的情况是包含JPAnel的OverlayLayout
。底部面板具有使用从Graphics2D
获取的JPanel
对象绘制的线条。顶部面板后面的框也是使用从其JPanel
获取的Graphics2D对象绘制的。
这个系统中的问题很多。由于我只是单独绘制Graphics2D
对象并且没有覆盖JPanel的paint()
,所以当面板需要重新绘制时,所有线条都会丢失,我想我会反对Swing的线程模型只有一个线程更新屏幕。我还没有让顶部面板正常工作,它只是不断清理屏幕,不会让底部面板画一条线。
处理这种情况的最佳方法是什么?我对图像处理和Swing中图像的低级显示几乎没有经验,我只知道基础知识。我听说过BufferedImage
,但不知道该图片放在哪里,如果稍后更改它会更新,这样做的效率,以及它缓冲的事实吓跑了我。我不知道该用什么
有人能指出我需要用什么来实现这个目标的正确方向吗?
答案 0 :(得分:4)
您可以使用合适的Shape
累积积分,例如GeneralPath
,如LissajousPanel
所示。使用javax.swing.Timer
进行定期更新,并使用周围的矩形突出显示最近添加的点。
答案 1 :(得分:3)
我建议
例如:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class BufferedImageEg extends JPanel {
private static final int BI_WIDTH = 700;
private static final int BI_HEIGHT = 500;
private static final Color BACKGROUND = new Color(255, 255, 240);
private static final int THIS_PT_WIDTH = 12;
private static final int THIS_PT_HEIGHT = THIS_PT_WIDTH;
private static final float THIS_PT_STROKE_WIDTH = 2f;
private static final Color THIS_PT_BORDER_COLOR = Color.red;
private static final Color THIS_PT_FILL_COLOR = new Color(250, 250, 0, 125);
private static final int TIMER_DELAY = 30;
private static final int X_MIN = 0;
private static final int X_MAX = 100;
private static final double X_STEP = 0.1;
private static final double X_SCALE = (double) BI_WIDTH
/ ((double) X_MAX - X_MIN);
private static final double Y_SCALE = 8;
private static final float LINE_WIDTH = 4;
private static final Color LINE_COLOR = Color.blue;
private Point lastPoint = null;
private Point thisPoint = null;
private BufferedImage bImage = new BufferedImage(BI_WIDTH, BI_HEIGHT,
BufferedImage.TYPE_INT_RGB);
private double xValue = X_MIN;
public BufferedImageEg() {
Graphics biG = bImage.getGraphics();
biG.setColor(BACKGROUND);
biG.fillRect(0, 0, BI_WIDTH, BI_HEIGHT);
setBackground(BACKGROUND);
new Timer(TIMER_DELAY, new ActionListener() {
public void actionPerformed(ActionEvent e) {
timerActionPerformed(e);
}
}).start();
}
private void timerActionPerformed(ActionEvent e) {
if (xValue <= X_MAX) {
lastPoint = thisPoint;
double tempX = xValue;
double yValue = function(xValue);
tempX *= X_SCALE;
yValue *= Y_SCALE;
yValue = BI_HEIGHT / 2.0 - yValue;
thisPoint = new Point((int) tempX, (int) yValue);
if (lastPoint != null) {
drawInBufferedImage();
}
xValue += X_STEP;
} else {
((Timer) e.getSource()).stop();
thisPoint = null;
}
repaint();
}
private void drawInBufferedImage() {
Graphics2D g2 = bImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(LINE_WIDTH, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND));
g2.setColor(LINE_COLOR);
int x1 = lastPoint.x;
int y1 = lastPoint.y;
int x2 = thisPoint.x;
int y2 = thisPoint.y;
g2.drawLine(x1, y1, x2, y2);
g2.dispose();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(BI_WIDTH, BI_HEIGHT);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bImage, 0, 0, null);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (thisPoint != null) {
drawThisPoint(g2);
}
}
private void drawThisPoint(Graphics2D g2) {
int x = thisPoint.x - THIS_PT_WIDTH / 2;
int y = thisPoint.y - THIS_PT_HEIGHT / 2;
Graphics2D g2b = (Graphics2D) g2.create();
g2b.setStroke(new BasicStroke(THIS_PT_STROKE_WIDTH));
g2b.setColor(THIS_PT_FILL_COLOR);
g2b.fillOval(x, y, THIS_PT_WIDTH, THIS_PT_HEIGHT);
g2b.setColor(THIS_PT_BORDER_COLOR);
g2b.drawOval(x, y, THIS_PT_WIDTH, THIS_PT_HEIGHT);
g2b.dispose();
}
private double function(double x) {
return 24 * Math.sin(x / 12.0) * Math.sin(x);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("BufferedImage Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new BufferedImageEg());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}