1 绘制动态连线。

我需要在画布的两点间绘制一条可动态展示(连线可以一段段的按时间增长)的连线,于是我打算使用多线程进行绘制,于是我建立了一个自己的线程类:

class MyThread implements Runnable
	{
		private ArrayList<Shape> shapes;

		public MyThread(ArrayList<Shape> shapes)
		{
			this.shapes = shapes;
		}

		@Override
		public void run()
		{
			isShowing = true;//用于锁住这个展示进行,不让出现一次出现两个展示进程
			Graphics2D g2 = (Graphics2D) getGraphics();

			float dash[] = { 4F };
			g2.setStroke(new BasicStroke(4.0F, BasicStroke.CAP_BUTT,
					BasicStroke.JOIN_MITER, 11.0F, dash, 1.0F));
			for (int index = 0; index < shapes.size(); index++)
			{
				try
				{
					Thread.sleep(15);
				}
				catch(InterruptedException e)
				{
					e.printStackTrace();
				}
				for (int pre = 0; pre <= index; pre++)
				{
					if(pre < 2)
						g2.setColor(Color.BLUE);
					else
						g2.setColor(Color.RED);
					g2.draw(shapes.get(pre));
				}
			}
			isShowing = false;
		}
	}
然后在自己的响应函数调用绘图线程:

<span style="white-space:pre">			</span>if(isShowing)//互锁
			{
				showMsg("Last message is not finished please "
						+ "don't click so frequently");
				isShowing = false;
				return;
				
			}
			<span style="color:#ff0000;">this.shapes = showPath(pathData[sequence]);//绘制图形</span>
			repaint();
			isShowPath = true;
			System.out.println("successed!!");


<span style="white-space:pre">	</span>private ArrayList<Shape> showPath(PathPoint pathPoint)//返回值用以保持这个线段在屏幕上
	{
		int step = 30;
		ArrayList<Shape> shapes = getShowPathShapes(pathPoint, step);
		Thread myThread = new Thread(new MyThread(shapes));
		myThread.start();
		return shapes;

	}
由于某种原因(我猜想是因为为重载paintComponent),在外部线程里绘制的连线并不能保持住,在改变窗口大小或另一个窗口遮住的时候(调用系统的repaint的时候)便会消失。于是我在showPath函数返回我画的shapes,并在主线程重载的paintComponent中保持住。

	public void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		g2.drawImage(img, 0, 0, null);
		if(isShowPath)
		{
			maintainShowPath(g2);
		}
	}
<span style="white-space:pre">	</span>private void maintainShowPath(Graphics2D g2)
	{
		Stroke stroke = g2.getStroke();
		float dash[] = { 4F };
		g2.setStroke(new BasicStroke(4.0F, BasicStroke.CAP_BUTT,
				BasicStroke.JOIN_MITER, 11.0F, dash, 1.0F));
		for (int i = 0; i < shapes.size(); i++)
		{
			g2.draw(shapes.get(i));
		}
		g2.setStroke(stroke);
	}


这样绘制的图形就不会消失了。

还存在的问题:由于我是在一个scrollPane中绘制的图形,如果在展示的时候拖动,scrollbar便会产生异常,具体现象是所绘制的线并不会绘制到相应的位置,而是绘制到视图刚开始的位置。这个我还不知道怎么解决。

2 将要动态展示的区域自动显示出来(因为画布较大,我放在了一个scrollPane中,所以,很多位置都是看不到的)

Methods in Other Classes Related to Scrolling
MethodPurpose
void scrollRectToVisible(Rectangle)
(in JComponent)
If the component is in a container that supports scrolling, such as a scroll pane, then calling this method scrolls the scroll pane such that the specified rectangle is visible.
这是Java官方教程中how to use scrollPane中找到的。

其实它的意思是:如果你将一个Panel放入一个scrollPane那么你的Panel的对象调用这个方法就可以实现了。好简单的样子哦。

我添加的代码:

<span style="white-space:pre">	</span>QuadCurve2D.Double q = new QuadCurve2D.Double();//建立以二次曲线的方程
<span style="white-space:pre">	</span>q.setCurve(pathData[sequence].getStartPoint().x,//设置Curve的控制点
<span style="white-space:pre">		</span>pathData[sequence].getStartPoint().y,
<span style="white-space:pre">		</span>pathData[sequence].getCtrPoint().x,
<span style="white-space:pre">		</span>pathData[sequence].getCtrPoint().y,
<span style="white-space:pre">		</span>pathData[sequence].getEndPoint().x,
<span style="white-space:pre">		</span>pathData[sequence].getEndPoint().y);
<span style="white-space:pre">	</span>this.scrollRectToVisible(q.getBounds());//将这个区域显示来(this 指我自己的Panel)

So easy!!!



更多推荐

菜鸟学Java之 Java2D 多线程绘图