我想用这段代码画一条线但是在图片视图上我看不到图片。如果我只拨打paintComponent()
,则效果非常好。我可以看到两行,但如果我拨打startDrawing()
,我会收到以下错误。起初,我试过没有new Canvas()
和setImageView()
,但没有任何事可做。
logcat的:
07-21 04:41:43.489: W/System.err(1770): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-21 04:41:43.529: W/System.err(1770): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
07-21 04:41:43.529: W/System.err(1770): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:857)
07-21 04:41:43.529: W/System.err(1770): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4320)
07-21 04:41:43.549: W/System.err(1770): at android.view.View.invalidate(View.java:10935)
07-21 04:41:43.569: W/System.err(1770): at android.view.View.invalidate(View.java:10890)
07-21 04:41:43.569: W/System.err(1770): at android.widget.ImageView.setImageDrawable(ImageView.java:426)
07-21 04:41:43.569: W/System.err(1770): at android.widget.ImageView.setImageBitmap(ImageView.java:439)
07-21 04:41:43.569: W/System.err(1770): at graphing.GraphPanel.run(GraphPanel.java:577)
07-21 04:41:43.569: W/System.err(1770): at java.lang.Thread.run(Thread.java:841)*
有代码:
public class GraphPanel implements Runnable {
private static final long serialVersionUID = -8880798842884968375L;
private double minX = -10;
private double maxX = 10;
private double minY = -10;
private double maxY = 10;
private double xInterval;
private double yInterval;
private int xAxis = 0;
private int yAxis = 0;
private int panelHeight = 0;
private int panelWidth = 0;
private boolean firstResize = true;
private static Vector<Equation> equations = new Vector<Equation>();
private static Vector<Path> polylines = new Vector<Path>();
private Vector<Thread> threads = new Vector<Thread>();
private boolean stopThreads = false;
private boolean painting = false;
private int currentEq = 0;
private static HashMap<String, PointF> points = new HashMap<String, PointF>();
SurfaceView view;
private Canvas g2;
private Paint p;
ImageView imageview;
Bitmap bitmap;
public GraphPanel(ImageView imageview, int width, int height) {
bitmap = Bitmap.createBitmap( width,height, Bitmap.Config.ARGB_8888);
p=new Paint();
p.setColor(Color.GREEN);
// TODO Auto-generated constructor stub
this.imageview=imageview;
}
private void init() {
// TODO Auto-generated method stub
}
public void paintComponent() {
painting = true;
g2 = new Canvas(bitmap);
imageview.setImageBitmap(bitmap);
p.setColor(Color.GREEN);
yAxis = UnitToPixelX(0);
xAxis = UnitToPixelY(0);
// GraphSettings.setDrawGrid(true);
// Draw Grid
if (GraphSettings.isDrawGrid()) {
//g2.setColor(Color.GRAY);
xInterval = Math.pow(10, String.valueOf((int) (maxX - minX) / 4).length() - 1);
yInterval = Math.pow(10, String.valueOf((int) (maxY - minY) / 4).length() - 1);
xInterval = yInterval = Math.min(xInterval, yInterval);
for (double i = 0 + xInterval; i <= maxX; i += xInterval) {
g2.drawLine(UnitToPixelX(i), 0, UnitToPixelX(i), g2.getHeight(),p);
}
for (double i = 0 - xInterval; i >= minX; i -= xInterval) {
g2.drawLine(UnitToPixelX(i), 0, UnitToPixelX(i), g2.getHeight(),p);
}
for (double i = 0 + yInterval; i <= maxY; i += yInterval) {
g2.drawLine(0, UnitToPixelY(i), g2.getWidth(), UnitToPixelY(i),p);
}
for (double i = 0 - yInterval; i >= minY; i -= yInterval) {
g2.drawLine(0, UnitToPixelY(i), g2.getWidth(), UnitToPixelY(i),p);
}
}
// Draw crossheir
g2.drawLine(g2.getWidth() / 2 - 5, g2.getHeight() / 2, g2.getWidth() / 2 + 5, g2.getHeight() / 2,p);
g2.drawLine(g2.getWidth() / 2, g2.getHeight() / 2 - 5, g2.getWidth() / 2, g2.getHeight() / 2 + 5,p);
// Draw x and y axis
g2.drawLine(0, xAxis, g2.getWidth(), xAxis,p);
g2.drawLine(yAxis, 0, yAxis, g2.getHeight(),p);
painting=false;
}
private synchronized void increasePolylineNumber(int eqNumber) {
while (polylines.size() < eqNumber + 1) {
polylines.add(new Path());
}
}
public void startDrawing() {
stopThreads = true;
for (Thread t : threads) {
t.stop(); //TODO: Terbile design. This should be changed later. But it works for testing.
}
threads.clear();
polylines.clear();
stopThreads = false;
// .draw(g2);
// repaint();
for (int i=0; i<equations.size(); i++) {
threads.add(new Thread(this));
threads.lastElement().start();
}
}
@Override
public void run() {
try {
g2=new Canvas(bitmap);
imageview.setImageBitmap(bitmap);
// imageview.setI
int eqNumber = this.getNextEQ();
Equation eq = equations.get(eqNumber);
increasePolylineNumber(eqNumber);
Path polyline = new Path();/*(GeneralPath.WIND_EVEN_ODD, this.getWidth());*/
boolean firstPoint = true;
double interval, intervalFormula, slope;
Double eqVal;
Double eqPrev = 0.0;
String expr = eq.getExpression();
// Set values for loop.
try {
eqPrev = Equation.evaluate(expr, minX, false);
} catch (Exception exc) {
equations.clear();
//JOptionPane.showMessageDialog(this, "Invalid Argument.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
int unittopixelxmin=UnitToPixelX(minX),
unittopixelxeqprev= UnitToPixelY(eqPrev);
polyline.moveTo(unittopixelxmin,unittopixelxeqprev);
// Printer.print("\neqNumber:" + eqNumber);
// Printer.print("Size:" + polylines.size());
polylines.set(eqNumber, polyline);
interval = intervalFormula = (maxX - minX) / (bitmap.getWidth());
int xtest=0,ytest=0;
// Start loop.
int loop = 0;
for (double x = minX;; x += interval) {
if (stopThreads) {
break;
}
// eqVal and pixValX are used a lot. Solve only once.
eqVal = Equation.evaluate(expr, x, false);
int pixValX = UnitToPixelX(x);
if (eqVal.isNaN() || eqVal.isInfinite()) {
firstPoint = true;
} else if (firstPoint) {
polyline.moveTo(pixValX, UnitToPixelY(eqVal));
polylines.set(eqNumber, polyline);
xtest=pixValX;
ytest=UnitToPixelY(eqVal);
firstPoint = false;
} else {
polyline.lineTo(pixValX, UnitToPixelY(eqVal));
polylines.set(eqNumber, polyline);
xtest=pixValX;
ytest=UnitToPixelY(eqVal);
}
// Set interval.
slope = Math.abs((eqVal - eqPrev) / (x - (x - interval)));
if (slope > GraphSettings.getMinCalcPerPixel()) {
if (slope > GraphSettings.getMaxCalcPerPixel()) {
slope = GraphSettings.getMaxCalcPerPixel();
}
interval = intervalFormula / slope;
} else {
interval = intervalFormula;
}
eqPrev = eqVal;
if ((loop++ % 10 == 0 || x >= maxX) && !painting) {
p.setColor(Color.RED);
g2.drawLine(0,0,120,120, p);
// repaint();
//g2.drawPath(polyline, p);
// view.draw(g2);
}
if (x >= maxX) {
break;
}
}
p.setColor(Color.RED);
g2.drawLine(0,0,120,120, p);
p.setColor(Color.RED);
g2.drawLine(unittopixelxmin,unittopixelxeqprev, xtest, ytest, p);
System.out.print(polylines);
System.out.print(polyline);
// imageview.setImageBitmap(bitmap);
/* for(Path path:polylines){
Log.e(path.toString(), path.toString()) ;
g2.drawPath(path, p);
}*/
} catch (Exception e) {
//JOptionPane.showMessageDialog(this, e, "Error", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}