2016-04-02 22 views
0

Bir XML dosyasından okudum ve ayrıştırdığım ve JTable'ı kullanarak GUI'm için eklediğim seyahat teklifleri listemize sahibim. Ayrıca, XML'e yeni teklifler eklendiğinde, GUI'yi güncelleyen bazı güncelleme işlevlerine (aralıklı ve anında tıklama) da sahibim. Amacım, GUI'deki teklifleri iş parçacığı güvenli bir şekilde eklemektir.Threadsafety in SwingWorker - Threadsafe içinde JTable Güncelleniyor

Bu, Swingworker kullanarak doInBackground() işlemini gerçekleştirdiğim sınıf (UpdateData.java) ve güvenlik konusunda daha fazla endişe kaynağıdır. (Daha derin bir bakış almak isteyen varsa diğer sınıflar da aşağıda gösterilmiştir) Can SwingUtilities.invokeLater(), iş parçacığı güvenli hale getirmek için kullanılabilir mi? Swingworkers done(), execute() ve process() 'i geçersiz kılmak, bir şekilde güvenliğin sağlanmasına yardımcı olur mu? Bu durumda nasıl? (thread prog'da newbie) (Daha derin bir bakış almak isteyen varsa diğer sınıflar aşağıda verilmiştir). Bazı Yardım/Geri Bildirim son derece takdir edilecektir.

Sınıf: 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; 
    } 

} 

Sınıf: 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 

} 

Sınıf: 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]; 
    } 

} 

Sınıf: 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; 
    } 
} 

Sınıf: 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; 
    } 

} 

cevap

1

Tüm Bileşenlerinin değişiklikler ve bunların modelleri değil de, AWT olay gönderme dizisindeki yapılması gerekir arka plan iş parçacığı. DoInBackground yönteminizin ikinci ve üçüncü satırları, is guaranteed to be executed in the AWT event thread olan done yöntemine taşınmalıdır.

Ayrıca, SwingWorker'ın değer türünün arka planda elde ettiğiniz veriler olması normaldir.

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(); 
     } 
    } 
} 
+0

Teşekkür ederiz @VGR !!! btw, 'ArrayList'i veri türü olarak kullandım, yerine' Liste'yi kullanmayı mı tavsiye ediyorsunuz yoksa sadece ifadeyi kısaltdınız mı? – rubikskube