我有一个旅行优惠清单,我从XML文件中读取并解析,并使用JTable将它们添加到我的GUI中。我还有一些更新功能(间隔和即时点击),只要新的商品被添加到XML,就会更新GUI。我的目标是以线程安全的方式在GUI中添加商品。
这是类(UpdateData.java),我使用Swingworker执行doInBackground(),更关注安全性。 (如果有人有兴趣深入了解,其他类也会在下面显示)可以使用SwingUtilities.invokeLater()来使其线程安全吗?重写Swingworkers done(),execute()和process()会以某种方式帮助实现安全吗?在那种情况下怎么样? (新手在线程编程)(如果有人有兴趣深入了解,下面给出其他课程)。一些帮助/反馈将受到高度赞赏。
类: UpdateData.java
public class UpdateData extends SwingWorker<Integer, Integer> {
private ArrayList<RawTravelData> listOfOffer;
private TravelData offerData;
private XMLReader parseData;
//the controller
private ControlUpdate updtController;
//constructor
public UpdateData(TravelData o, ControlUpdate offerController) {
updtController = offerController;
parseData = new XMLReader();
offerData = o;
}
@Override
protected Integer doInBackground() throws Exception {
listOfOffer = parseData.fetchData();
offerData.setData(listOfOffer);
updtController.setOfferArray(listOfOffer);
return null;
}
}
类: RawTravelData.java
public class RawTravelData {
private String destination = "";
private String travelDate = "";
private int currPrice;
//empty constructor
public RawTravelData() {
}
//setters ad getters for destination, travel date and currprise
}
分类: TravelData.java
public class TravelData extends AbstractTableModel {
//the table header strings
private String[] colNames = { "Destination", "Date", "Price", "Details" };
private static final long serialVersionUID = 1L;
//arraylist of the offer data
private ArrayList<RawTravelData> offerList;
//constructor
public TravelData(ArrayList<RawTravelData> rtd) {
offerList = rtd;
}
//second constructor to create empty list
public TravelData() {
offerList = new ArrayList<RawTravelData>();
}
//add the list
public void setData(ArrayList<RawTravelData> o) {
offerList = o;
this.fireTableDataChanged();
}
//get the offer list
public ArrayList<RawTravelData> getOfferList() {
return offerList;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return String.class;
case 1:
return Integer.class;
case 2:
return String.class;
case 3:
return String.class;
default:
break;
}
return String.class;
}
@Override
public int getColumnCount() {
return colNames.length;
}
@Override
public int getRowCount() {
return offerList.size();
}
@Override
public Object getValueAt(int arg0, int arg1) {
switch (arg1) {
case 0:
return offerList.get(arg0).getDestination();
case 1:
return offerList.get(arg0).getPrice();
case 2:
return offerList.get(arg0).getTravelDate();
case 3:
return "Details";
default:
break;
}
return "null";
}
@Override
public String getColumnName(int col) {
return colNames[col];
}
}
类: XMLReader.java
public class XMLReader {
//Method to fetch and read all the data from the XML file
public ArrayList<RawTravelData> fetchData() {
//parse data and return as arraylist of offers
return arrayOfOffer;
}
}
类: ControlUpdate.java
//This class is responsible for controlling the updating of the offer data in the background
public class ControlUpdate {
private TablePanel tablePane;
private ArrayList<RawTravelData> offerArray;
//..
//Constructor
public ControlUpdate(TablePanel tablePane) {
settingsVal = new SaveSettings();
this.tablePane = tablePane;
tablePane.getOfferTable().addMouseListener(
new TableSortListener(tablePane.getOfferTable(), this));
runUpdateTask();
setUpdateInterval(settingsVal.readSettings());
}
//run the updates
private void runUpdateTask() {
//used Timer and ScheduledThreadPool
}
//get the table panel
public TablePanel getTablePanel() {
return tablePane;
}
//setting the list to a new offer list for the updater
public void setOfferArray(ArrayList<RawTravelData> rtd) {
offerArray = rtd;
}
}
答案 0 :(得分:1)
组件及其模型的所有修改都需要在AWT事件派发线程中执行,而不是在后台线程中执行。 doInBackground方法的第二行和第三行应移至done
方法,is guaranteed to be executed in the AWT event thread。
通常情况下,SwingWorker的值类型是您在后台获取的数据。
public class UpdateData
extends SwingWorker<List<RawTravelData>, Integer> {
// ...
@Override
protected List<RawTravelData> doInBackground() throws Exception {
return parseData.fetchData();
}
@Override
protected void done() {
try {
List<RawTravelData> listOfOffer = get();
offerData.setData(listOfOffer);
updtController.setOfferArray(listOfOffer);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
// Someone wants us to exit cleanly.
e.printStackTrace();
}
}
}