`

TWaver报表工具使用的GUI线程安全问题

阅读更多
  一个RCP实现的客户端,服务端传输数据过来客户端就主推到了UI界面,用的是观察者设计模式,在View视图中实现了update方法,这样引来了一个UI线程错误,很偶然会出现数组越界问题,就是没保证UI的变更,没在一条线程的单例下完成。

   原先报错的做法是
@Override
	public void update(Observable o, final Object arg) {
		// TODO Auto-generated method stub
				DB_ConStatus dbConn = (DB_ConStatus)arg;
				String node = dbConn.getNode();
				String svrName = dbConn.getSvrName();
				LineChart lineChart = (LineChart)uiMap.get(node+svrName+"lineChart");
				if(lineChart==null)return;
				List<LineItem> items =lineChart.getItems();
				LineItem red = items.get(0);
				LineItem green = items.get(1);
				double max = dbConn.getAll_conn()+20;
				lineChart.setUpperLimit(max);//最大上线数
				lineChart.setYScaleValueGap(max/10==0?1:Math.floor(max/10));
				red.addValue(dbConn.getAll_conn());//最大连接数
				red.setName("最大连接数("+dbConn.getAll_conn()+")");
				green.addValue(dbConn.getUsed_conn());//当前连接数
				green.setName("当前连接数("+dbConn.getUsed_conn()+")");
				String date = dbConn.getSet_date();
				String xText = date.substring(8,10)+":"+date.substring(10,12)+":"+date.substring(12,14);
				lineChart.addXScaleText(xText);//当前时间
				if (lineChart.valueCount() > 15) {
					lineChart.removeHead(1);
				}		
		
	}


这样就很容易出现一个错误,数组越界,一个关乎LineChart使用GUI画图时候的错误,贴下错误。

Exception in thread "AWT-EventQueue-1" java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at twaver.chart.LineChart.A(Unknown Source)
at twaver.chart.LineChart.paintContent(Unknown Source)
at twaver.chart.AbstractScaleChart.paintChart(Unknown Source)
at twaver.chart.A.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(JComponent.java:1027)
at javax.swing.JComponent.paintChildren(JComponent.java:864)
at javax.swing.JComponent.paint(JComponent.java:1036)
at twaver.chart.AbstractChart.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5122)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:277)
at javax.swing.RepaintManager.paint(RepaintManager.java:1217)
at javax.swing.JComponent._paintImmediately(JComponent.java:5070)
at javax.swing.JComponent.paintImmediately(JComponent.java:4880)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:803)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:714)
at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:694)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:128)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)


解决方案是使操作UI的操作给Swing自己去管理,加个SwingUtilities.invokeLater();或SwingUtilities.invokeAndWait();
@Override
	public void update(Observable o, final Object arg) {
		// TODO Auto-generated method stub
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				DB_ConStatus dbConn = (DB_ConStatus)arg;
				String node = dbConn.getNode();
				String svrName = dbConn.getSvrName();
				LineChart lineChart = (LineChart)uiMap.get(node+svrName+"lineChart");
				if(lineChart==null)return;
				List<LineItem> items =lineChart.getItems();
				LineItem red = items.get(0);
				LineItem green = items.get(1);
				double max = dbConn.getAll_conn()+20;
				lineChart.setUpperLimit(max);//最大上线数
				lineChart.setYScaleValueGap(max/10==0?1:Math.floor(max/10));
				red.addValue(dbConn.getAll_conn());//最大连接数
				red.setName("最大连接数("+dbConn.getAll_conn()+")");
				green.addValue(dbConn.getUsed_conn());//当前连接数
				green.setName("当前连接数("+dbConn.getUsed_conn()+")");
				String date = dbConn.getSet_date();
				String xText = date.substring(8,10)+":"+date.substring(10,12)+":"+date.substring(12,14);
				lineChart.addXScaleText(xText);//当前时间
				if (lineChart.valueCount() > 15) {
					lineChart.removeHead(1);
				}
			}
		});



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics