XMLファイルから読み込んで解析したJTableを使用してGUIに追加した旅行のリストがあります。また、新しいオファーがXMLに追加されると直ちにGUIを更新するいくつかの更新機能(間隔およびクリック時に即座に)があります。私の目的は、GUIのオファーをスレッドセーフな方法で追加することです。SwingWorkerのスレッドセーフ - スレッドセーフな方法でJTableを更新
これはSwingworkerを使用してdoInBackground()を実行するクラスであり、安全性についてのより多くの懸念事項です(UpdateData.java)。 (誰かがより深く見てみたいと思っている人は、他のクラスも以下に示します)SwingUtilities.invokeLater()を使ってスレッドセーフにすることはできますか? Swingworkers done()、execute()、およびprocess()をオーバーライドすると、何らかの安全性を達成するのに役立つでしょうか?その場合どのように? (スレッドprogの初心者)(詳細を知りたい人は、他のクラスを以下に示します)。ヘルプ/フィードバックは高く評価されます。
クラス: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;
}
}
ありがとう@VGR !!! btw、データ型として 'ArrayList'を使用しましたが、代わりに 'List'を使用することをお勧めしますか、式を短縮しましたか? – rubikskube