【发布时间】:2017-04-12 17:09:54
【问题描述】:
我试图使用带有 Graphics2D 绘制形状的 JPanel 绘制方法制作图表。但是,我的线没有连接,它们的斜率为 0。我的期望是像信号波一样绘制线。这是我的代码:
package action;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.geom.Line2D;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Starter extends JFrame {
double Xoffset = 30, Yoffset = 20, Xold = 40, Ycurr = 40, Xcurr = Xold,
Ytarget = Ycurr, Xgap = 10, Ygap = 60;
double sh = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
double sw = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int panelOffSet = 20;
double[] value_old = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
double[] value_curr = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};// new
// double[17];
int counter = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Starter mainThread = new Starter();
}
public Starter() {
super("EEG Recorder");
// //set the frame to center of screen
setLayout(null);
this.getContentPane().setBackground(new Color(32, 32, 32));
setSize((int) sw, (int) sh);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// add the painting panel
EEGRecorder plotter = new EEGRecorder();
add(plotter);
this.setVisible(true);
while (true) {
plotter.run();
}
}
class EEGRecorder extends JPanel implements Runnable {
public EEGRecorder() {
setLayout(null);
setBackground(new Color(32, 32, 32));
setBounds(0, panelOffSet, (int) sw, (int) (sh - panelOffSet));
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
this.updateUI();
repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
// System.out.println("hello");
}
@Override
public void paint(Graphics g) {
Graphics2D gg = (Graphics2D) g;
for (int i = 1; i < 17; i++) {
Random rn = new Random();
Ytarget = rn.nextDouble() * 30;
value_curr[i] = Ytarget;
// System.out.println(value_curr[i]);
if (Xcurr + Xgap - 1 > sw) {
gg.clearRect((int) Xoffset, (int) Yoffset, (int) (sw - Xoffset - 20), (int) (sh - panelOffSet));
gg.setColor(new Color(32, 32, 32));
gg.fillRect(0, 0, (int) (sw), (int) (sh - panelOffSet));
Xold = Xoffset;
Xcurr = Xold + Xgap;
} else {
gg.setColor(Color.yellow);
gg.drawString("ch" + i, 4, (int) (Yoffset + (i - 1) * Ygap));
if (counter == 0) {
value_old[i] = 0;// value_curr[i];
Xcurr = Xold + Xgap;
}
gg.setColor(Color.BLUE);
gg.draw(new Line2D.Double(Xold, (i - 1) * Ygap - value_old[i], Xcurr,
(i - 1) * Ygap - value_curr[i]));
double Yold=(i - 1) * Ygap - value_old[i];
double Ynew=(i - 1) * Ygap - value_curr[i];
System.out.println(Xold+","+Yold+","+ Xcurr+","+Ynew);
}
}
value_old = value_curr;
// Ycurr = Ytarget;
Xold = Xcurr;
Xcurr += Xgap;
counter++;
}
}
}
【问题讨论】:
-
我仍在尝试找出这段代码中的问题,有人知道吗?
-
while (true) {在这种情况下非常危险;this.updateUI();与您尝试做的事情无关,看起来您只是随机调用“听起来”不错的方法 - 我建议阅读updateUI上的文档,基本上,永远不要再调用它 -
您还破坏了记录在案的油漆链,这将产生无穷无尽的问题 - 我强烈建议您阅读 Painting in AWT and Swing 和 Performing Custom Painting
-
另外,绘制方法不应该更新状态,它们应该只绘制当前状态。您应该尽可能减少逻辑,以便在其他地方做出许多决定 - 为什么?可以出于多种原因随时调用 Paint,其中许多原因是您无法控制的
-
绘画也是破坏性的。预计每次调用paint时,您将重新绘制整个状态,而不仅仅是更新它。这让您有两个选择。您要么设计一个模型来维护组件完全绘制自身所需的信息,要么绘制到后备缓冲区。