如何使用SwingWorker?
朋友们,我正在开发一个java应用程序。 这是性能监测。 因为我在一个类中获取值并在另一个类中绘制图形。 我想使用swingworker来执行这两个类。
ResultSet rs; Connection conn = null; conn = (Connection)getMySqlConnection(); Statement st = conn.createStatement(); rs = st.executeQuery("SHOW GLOBAL STATUS"); while(rs.next()) { Map_MySql.put(rs.getString(1), rs.getString(2)); } conn.close();
上面的类用于收集服务器状态并将其存储在哈希映射中。 这个类称为“MySQLClass”。
System.out.println("Graph Occur"); XYDataset Dataset; TimeSeries Series = new TimeSeries("Random Data"); Second sec = new Second(); ChartPanel CPanel; if(Operation_Combo.getSelectedItem().toString() == "MySQL") { if(MySQLClass.Map_MySql.get(""+MainWindow.SelectedNode+"") == null) { Value = 0; } else { Value = Integer.parseInt(MySQLClass.Map_MySql.get(""+MainWindow.SelectedNode+"")); } System.out.println(Value); } if(Operation_Combo.getSelectedItem().toString() == "SQL Server") { if(SqlServerClass.Map_SQLServer.get(""+MainWindow.SelectedNode+"") == null) { Value = 0; } else { Value = Integer.parseInt(SqlServerClass.Map_SQLServer.get(""+MainWindow.SelectedNode+"")); } System.out.println(Value); } String CounterName = MainWindow.SelectedNode.toString(); Series.add(sec, Value); Dataset = new TimeSeriesCollection(Series); Chart = ChartFactory.createTimeSeriesChart(CounterName, "Time", "Range", Dataset, true, false, false); XYPlot Plot = (XYPlot)Chart.getPlot(); Plot.setBackgroundPaint(Color.LIGHT_GRAY); Plot.setDomainGridlinePaint(Color.WHITE); Plot.setRangeGridlinePaint(Color.RED); CPanel = new ChartPanel(Chart); Panel1.revalidate(); Panel1.add(CPanel); System.out.println("Chart Added"); Panel1.validate(); Panel1.repaint(); Thread.sleep((int)MainWindow.Interval_Combo.getSelectedItem() * 1000); System.out.println("Sleep="+((int)MainWindow.Interval_Combo.getSelectedItem() * 1000)); System.gc();
以上是在一个名为“Graph”的类中绘制Graph的代码。 如何使用swing worker来交替执行此操作并在每次迭代中绘制图形。 如果你知道请帮助我。
SwingWorker
使用起来要简单得多。
基本上,您需要就要实现的目标做出一些基本决定。
- 是否要在进程运行时定期返回更新或
- 您想要返回流程的结果……还是两者都有?
- 您想提供进展更新吗?
根据您的要求,将改变您声明SwingWorker的方式。
例如…
public class HardWorker extends SwingWorker {
其中ReturnValueType
是将由worker生成的最终结果, PeriodicalType
是可以发送回UI线程的对象类型,如果您想要执行定期更新(这些是您可以自己指定的值)。
如果您不在意,可以为这些值中的任何一个指定Void
或Object
执行时, SwingWorker
将调用doInBackground
,此方法将在其自己的线程中调用,允许在Event Dispatching Thread之外执行长时间运行的任务。
如果要在doInBackground
方法完成之前将值发送回UI,可以调用publish(instanceOfPeriodicalType)
。 传递给此方法的值最终将传递给process
方法。
因为可以将多个项发送到publish
方法,所以process
方法提供了List
参数。 调用时,此方法将在EDT的上下文中执行,允许您更新UI。
一旦doInBackground
完成,它将return
ReturnValueType
类型的返回值(如果你不关心,则return
null
)。
如果你对这个结果感兴趣,你应该使用SwingWorker#get
doInBackground
,但是你应该注意这个方法将阻塞直到doInBackground
返回,这意味着你不应该在EDT中调用这个方法,直到你知道doInBackground
方法已经返回。 您可以使用isDone
或isCancelled
方法检查worker的状态,或者……
您可以使用PropertyChangeListener
并监视state
属性或覆盖SwingWorker
的done
方法。
如果要提供进度更新,则在doInBackground
方法中,可以调用setProgress
来更新worker的进度。 这将触发名为progress
的PropertyChangeEvent
,您可以通过使用PropertyChangeListener
进行监视。 对该听众的召唤将在EDT的背景下进行。
看一眼:
- SwingWorker的
- 工人线程和SwingWorker
更多细节。
通常,为了使用SwingWorker
,您要做的是将您的设计分为两组。 可以在后台完成的所有事情以及在EDT中需要完成的所有事情。
您可以开始构建工作人员的基本概念。
基本范例……
这假设很多。 基本上,它假设已经设置了UI,这将用于挑选新结果并将它们传递回特定系列。
基本上,根据需要,工人将被隐瞒,并且系列传递给它…
GraphWorker worker = new GraphWorker(series); worker.execute();
然后,该工作将执行查询并将结果传递回process
方法
public class GraphWorker extends SwingWorker { private TimeSeries series; private Second sec; public GraphWorker(TimeSeries series) { this.series = series; sec = new Second(); } @Override protected Void doInBackground() throws Exception { ResultSet rs; Connection conn = null; try { conn = (Connection) getMySqlConnection(); Statement st = conn.createStatement(); rs = st.executeQuery("SHOW GLOBAL STATUS"); while (rs.next()) { publish(new String[]{rs.getString(1), rs.getString(2)}); } } finally { conn.close(); } return null; } @Override protected void process(List chunks) { for (String[] value : chunks) { try { int iValue = Integer.parseInt(value[1]); series.add(sec, Value); } catch (NumberFormatException exp) { exp.printStackTrace(); } } } }
首先,我只是从MySQL.execute()调用doInBackground()函数; 用这个。 然后在doInBackground()函数中,我只收集那些计数器值并使用publish(); function,以确定价值。 在这里我只是通过标志来表示数据已成功收集。 发布(GraphLock);
在调用Publish()之后; 方法, 进程(List chunks)方法被调用。 在那我只是检查条件并调用Graph类来生成图形。
if(GraphLock==true) SwingUtilities.invokeLater(new Graph());
它工作正常……