2014-10-01 2 views
0

두 개의 JTable 및 관련 데이터를 관리하는 데 몇 가지 문제가 있습니다. 나는 차량의 목록 (트럭, 자동차 ...) 및 상대 정보를 가지고있는 첫 번째의 JTable에서 : enter image description hereJTable, TableModel 및 기타의 복잡한 사용

내가 사용 설명 :

나는이 GUI를 확인했다. 두 번째 jTable에는 녹색 화살표를 눌러서 "사용 가능"(즉, 에이전트가 시작됨)하려는 차량 목록이 있습니다. 첫 번째 목록의 하위 목록은 첫 번째 테이블에서 선택한 행이 두 번째 목록에 복사됩니다.

첫 번째 문제 : 첫 번째 열에는 차량 종류 (이 예에서는 트럭을 볼 수 있음)에 대한 설명 이미지가 있습니다. 세 번째와 다섯 번째 열에는 다른 jComboBox가 있습니다. TIPO VEICOLO의 jComboBox (즉 Kind)를 참조하십시오 : 다른 차량을 선택하면 첫 번째 열의 이미지가 변경되어야합니다! (트럭에서 자동차로 변경하려면 상대 아이콘이 변경되어야 함). 또한 소프트웨어의 다른 위치에서이 아이콘을 처리하지 않을 수도 있습니다. 나는 설명 : 내가 사용하려는

Object[] vehicle = {"aaa", "kind1", "marca", "disponibile", "ptt" } 

Object[] vehicle = {"/image/truck.png" ,"aaa", "kind1", "marca", "disponibile", "ptt" } 

두 번째 문제

결코 : 나는 JTable의 다른 기능을 추가하고자하는 미래에 : 치수, 차량의 색상, 라이센스를 ... 알 수 없습니다 트럭의 기능은 자동차의 기능과 다릅니다. 헤더의 모든 기능을 유지하는 방법을 원하지만 모든 종류의 차량에 따라 일부 셀을 활성화/비활성화 할 수 있습니다.

참고 : jTables의 헤더가 필요하지 않습니다 같은

package it.transfersimulation; 

import it.transfersimulation.Vehicle.Stato; 
import it.transfersimulation.Vehicle.TipoVeicolo; 

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.Toolkit; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
import java.awt.ComponentOrientation; 

import javax.swing.DefaultCellEditor; 
import javax.swing.DefaultComboBoxModel; 
import javax.swing.ImageIcon; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.BoxLayout; 
import javax.swing.JTable; 
import javax.swing.event.TableModelEvent; 
import javax.swing.event.TableModelListener; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableColumn; 
import javax.swing.JButton; 

import java.awt.FlowLayout; 

import javax.swing.SwingConstants; 


@SuppressWarnings("serial") 
public class ShipperAgentGUI extends JFrame implements ActionListener { 

// Variabili di classe 
private JPanel masterPanel; 
private JButton btnPM_plus; 
private JButton btnPM_meno; 
private JButton btnMD_plus; 
private JButton btnMD_meno; 
private JTable availablesTable; 
private JTable parkTable; 

private Object[] parkModelHeader = { "" , "TARGA", "TIPO VEICOLO", "MARCA", "STATO", "PTT" }; 
private Object[] availablesModelHeader = { "", "TARGA", "TIPO VEICOLO", "MARCA", "STATO", "PTT" }; 

private DefaultTableModel parkModel = new DefaultTableModel(null, parkModelHeader){ 
    public Class<?> getColumnClass(int columnIndex) { 
     return getValueAt(0, columnIndex).getClass(); 
    }; 
};// per aggiungere jCheckBox, jComboBox e ImageIcon 

private DefaultTableModel availablesModel = new DefaultTableModel(null, availablesModelHeader){ 
    public Class<?> getColumnClass(int columnIndex) { 
     return getValueAt(0, columnIndex).getClass(); 
    }; 
};// per aggiungere jCheckBox, jComboBox e ImageIcon 

// My third-part software: a JADE agent: 
protected ShipperAgent shipperAgent; 

private Coordinator parkCoordinator; 
private Coordinator availablesCoordinator; 


//////////////////////////////////////////////////// 
// COSTRUTTORE 

ShipperAgentGUI(ShipperAgent agent) { 

    // Valorizza l'agente corrispondente 
    shipperAgent = agent; 


    /////////////////////////////////////////////////////////////////////// 
    // Graphics: 
    // 

    setTitle("Shipper Agent: "+agent.getLocalName()); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    try { 
     UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); 
     //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
    } catch (ClassNotFoundException | InstantiationException 
      | IllegalAccessException | UnsupportedLookAndFeelException e) { 
     e.printStackTrace(); 
    } 

    // MasterPanel 
    masterPanel = new JPanel(); 
    masterPanel.setLayout(new BoxLayout(masterPanel, BoxLayout.Y_AXIS)); 
    masterPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); 


    // Park Panel 
    JPanel parkPanel = new JPanel(); 
    parkPanel.setLayout(new BoxLayout(parkPanel, BoxLayout.Y_AXIS)); 
    masterPanel.add(parkPanel); 

    JPanel pnlHeaderParkPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); 
    JLabel parkLabel = new JLabel("Parco auto:"); 
    pnlHeaderParkPanel.add(parkLabel); 
    parkPanel.add(pnlHeaderParkPanel); 

    JPanel pnlTableParkPanel = new JPanel(); 
    pnlTableParkPanel.setLayout(new BoxLayout(pnlTableParkPanel, BoxLayout.X_AXIS)); 
    parkPanel.add(pnlTableParkPanel); 

    // Park Table 
    parkTable = new JTable(); 
    parkTable.setModel(parkModel); 
    parkTable.setPreferredScrollableViewportSize(new Dimension(500,100)); 
    parkTable.setFillsViewportHeight(true); 
    JScrollPane parkScrollPane = new JScrollPane(parkTable); 
    pnlTableParkPanel.add(parkScrollPane); 

    JPanel pnlBtnParkPanel = new JPanel(); 
    pnlTableParkPanel.add(pnlBtnParkPanel); 
    pnlBtnParkPanel.setLayout(new BoxLayout(pnlBtnParkPanel, BoxLayout.Y_AXIS)); 

    // JButtons: add/remove vehicle in Park Table 
    btnPM_plus = new JButton(); 
    btnPM_plus.setToolTipText("Aggiungi mezzo"); 
    btnPM_plus.setIcon(new ImageIcon(ShipperAgentGUI.class.getResource("/images/lorry-add.png"))); 
    btnPM_plus.setActionCommand("+parco"); 
    btnPM_plus.addActionListener(this); 
    pnlBtnParkPanel.add(btnPM_plus); 

    btnPM_meno = new JButton(); 
    btnPM_meno.setToolTipText("Rimuovi mezzo"); 
    btnPM_meno.setIcon(new ImageIcon(ShipperAgentGUI.class.getResource("/images/lorry-delete.png"))); 
    btnPM_meno.setActionCommand("-parco"); 
    btnPM_meno.addActionListener(this); 
    pnlBtnParkPanel.add(btnPM_meno); 


    // Arrow Panel 
    JPanel arrowPanel = new JPanel(); 
    masterPanel.add(arrowPanel); 

    // JButtons: available or not vehicle 
    btnMD_plus = new JButton(); 
    btnMD_plus.setToolTipText("Rendi disponibile il mezzo selezionato"); 
    btnMD_plus.setIcon(new ImageIcon(ShipperAgentGUI.class.getResource("/images/arrow-green-down.png"))); 
    arrowPanel.add(btnMD_plus); 
    btnMD_plus.setActionCommand("+disponibili"); 
    btnMD_plus.addActionListener(this); 

    btnMD_meno = new JButton(); 
    btnMD_meno.setToolTipText("Rendi indisponibile il mezzo selezionato"); 
    btnMD_meno.setIcon(new ImageIcon(ShipperAgentGUI.class.getResource("/images/arrow-red-up.png"))); 
    arrowPanel.add(btnMD_meno); 
    btnMD_meno.setActionCommand("-disponibili"); 
    btnMD_meno.addActionListener(this); 


    // Availables Panel 
    JPanel availablesPanel = new JPanel(); 
    masterPanel.add(availablesPanel); 
    availablesPanel.setLayout(new BoxLayout(availablesPanel, BoxLayout.Y_AXIS)); 

    JPanel pnlHeaderAvailablesPanel = new JPanel(); 
    FlowLayout fl_pnlHeaderAvailablesPanel = (FlowLayout) pnlHeaderAvailablesPanel.getLayout(); 
    fl_pnlHeaderAvailablesPanel.setAlignment(FlowLayout.LEFT); 
    availablesPanel.add(pnlHeaderAvailablesPanel); 
    JLabel label_1 = new JLabel("Disponibili:"); 
    pnlHeaderAvailablesPanel.add(label_1); 
    label_1.setHorizontalAlignment(SwingConstants.LEFT); 

    // Available Table 
    availablesTable = new JTable(); 
    availablesTable.setModel(availablesModel); 
    availablesTable.setPreferredScrollableViewportSize(new Dimension(500, 100)); 
    availablesTable.setFillsViewportHeight(true); 
    JScrollPane availablesScrollPane = new JScrollPane(availablesTable); 
    availablesPanel.add(availablesScrollPane); 
    getContentPane().add(masterPanel, BorderLayout.CENTER); 

    // Search Panel 
    JPanel searchPanel = new JPanel(); 
    masterPanel.add(searchPanel); 
    JButton btnSearch = new JButton("Search"); 
    searchPanel.add(btnSearch); 

    // End of graphics init 
    /////////////////////////////////// 


    ////////////////////////////////////// 
    // Editor delle colonne delle tabelle 
    // TODO 
    JComboBox<TipoVeicolo> tipoVeicoloComboBox = new JComboBox<TipoVeicolo>(); 
    tipoVeicoloComboBox.setModel(new DefaultComboBoxModel<TipoVeicolo>(TipoVeicolo.values())); 
    JComboBox<Stato> statoComboBox = new JComboBox<Stato>(); 
    statoComboBox.setModel(new DefaultComboBoxModel<Stato>(Stato.values())); 

    TableColumn tipoVeicoloColumn = parkTable.getColumnModel().getColumn(2); 
    TableColumn statoColumn = parkTable.getColumnModel().getColumn(4); 

    tipoVeicoloColumn.setCellEditor(new DefaultCellEditor(tipoVeicoloComboBox)); 
    statoColumn.setCellEditor(new DefaultCellEditor(statoComboBox)); 


    ///////////////////////////////////////////////////////////////////// 
    // Coordinators (ispirati al Mediator pattern) 

    parkCoordinator = new Coordinator(shipperAgent, parkModel) { 
     @Override 
     public void notifyAndAddRow(final Object[] rowData) { 
      shipperAgent.newTruck((String) rowData[0]); 

      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        tableModel.addRow(rowData); 
       } 
      }); 
     } 

     @Override 
     public void notifyAndDeleteRow(final int rowIndex) { 
      final String truck = (String)this.tableModel.getValueAt(rowIndex, 0); 
      int flag=search(availablesCoordinator.tableModel, truck); 
      if (flag!=-1) 
       removeVehicle(availablesCoordinator, flag); 
      shipperAgent.removeTruck(truck); 

      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        tableModel.removeRow(rowIndex); 
       } 
      }); 
     } 
    }; 


    availablesCoordinator = new Coordinator(shipperAgent, availablesModel) { 
     @Override 
     public void notifyAndAddRow(final Object[] rowData) { 
      shipperAgent.activateTruck((String) rowData[0]); 

      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        tableModel.addRow(rowData); 
       } 
      }); 
     } 

     @Override 
     public void notifyAndDeleteRow(final int rowIndex) { 
      String truck = (String)this.tableModel.getValueAt(rowIndex, 1); 
      shipperAgent.deactivateTruck(truck); 

      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        tableModel.removeRow(rowIndex); 
       } 
      }); 
     } 
    }; 


    ///////////////////////////////////////////////////// 
    // Listeners: 

    parkModel.addTableModelListener(parcoListener); 
    availablesModel.addTableModelListener(mezziDisponibiliListener); 


    ///////////////////////////////////////////////////// 
    // Contatto con l'agente - Riempimento dati 
    // TODO 
    Object[] veicoli = shipperAgent.getVehicles(); 
    for (int i=0; i<veicoli.length;i++){ 
     Object[] info = (Object[]) veicoli[i]; 
     Object[] veicolo = new Object[info.length+1]; 

     veicolo[0] = new ImageIcon(ShipperAgentGUI.class.getResource("/images/lorry-icon.png")); 

     for (int j=1;j<info.length+1;j++){ 
      veicolo[j]=info[j-1]; 
     } 

     parkModel.addRow(veicolo); 

     if (veicolo[4] == Stato.DISPONIBILE) 
      availablesModel.addRow(veicolo); 
    } 

    //////////////////////////// 
    // Show GUI 
    showGui(); 
} 


public void showGui() { 
    pack(); 
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
    int centerX = (int) screenSize.getWidth()/2; 
    int centerY = (int) screenSize.getHeight()/2; 
    setLocation(centerX - getWidth()/2, centerY - getHeight()/2); 
    super.setVisible(true); 
} 


////////////////////////////////////////////// 
// actionPerformed 

@Override 
public void actionPerformed(ActionEvent e) { 
    switch (e.getActionCommand()) { 
    case "+parco": { 
     new VehicleInsertJDialog(this, parkCoordinator); 
    } break; 

    case "-parco": { 
     int selectedRow = parkTable.getSelectedRow(); 
     if (selectedRow != -1) 
      removeVehicle(parkCoordinator, selectedRow); 
    } break; 

    case "+disponibili": { 
     int selectedRow = parkTable.getSelectedRow(); 
     if (selectedRow != -1){ 
      //TODO controlla la consistenza 
      addVehicle(availablesCoordinator, 
        String.valueOf(parkModel.getValueAt(selectedRow, 0)), 
        String.valueOf(parkModel.getValueAt(selectedRow, 1)), 
        String.valueOf(parkModel.getValueAt(selectedRow, 2)), 
        String.valueOf(parkModel.getValueAt(selectedRow, 3)), 
        String.valueOf(parkModel.getValueAt(selectedRow, 4)) 
        ); 

     } 
    } break; 

    case "-disponibili": { 
     int selectedRow = availablesTable.getSelectedRow(); 
     if (selectedRow != -1) 
      removeVehicle(availablesCoordinator, selectedRow); 
    } break; 

    default: 
     System.out.println("Imprevisto in actionPerformed()"); 
     break; 
    } 
} 



// ///////////////////////////////////// 
// Add/Remove vehicles methods 

public void addVehicle(Coordinator coordinator, 
     String targa, String tipo, String marca, String stato, String peso) { 
    coordinator.notifyAndAddRow(new Object[]{targa, tipo, marca, stato, peso}); 
} 

public void removeVehicle(Coordinator coordinator, int index) { 
    coordinator.notifyAndDeleteRow(index); 
} 


// ////////////////////////////////////////// 
// LISTENER: 

TableModelListener parcoListener = new TableModelListener() { 
    public void tableChanged(TableModelEvent e) { 
     switch (e.getType()) { 
     case (TableModelEvent.INSERT): 
      System.out.println("un inserimento in corso!"); break; 
     case (TableModelEvent.DELETE): 
      System.out.println("una cancellazione in corso!"); break; 
     case (TableModelEvent.UPDATE): 
      System.out.println("un aggiornamento in corso!"); break; 
     } 
    } 
}; 

TableModelListener mezziDisponibiliListener = new TableModelListener() { 
    public void tableChanged(TableModelEvent e) { 
     switch (e.getType()) { 
     case (TableModelEvent.INSERT): 
      System.out.println("un inserimento in corso!"); break; 
     case (TableModelEvent.DELETE): 
      System.out.println("una cancellazione in corso!"); break; 
     case (TableModelEvent.UPDATE): 
      System.out.println("un aggiornamento in corso!"); break; 
     } 
    } 
}; 



private int search(DefaultTableModel tableModel, String targa) { 
    int flag = -1; 
    for (int i=0; i<tableModel.getRowCount(); i++) 
     if (tableModel.getValueAt(i, 0).equals(targa)) 
      flag=i; 
    return flag; 
} 






/////////////////////////////////////// 
// INNER CLASS 
/////////////////////////////////////// 

protected abstract class Coordinator { 

    /* 
    * protected class members so subclasses can access these directly 
    */ 

    protected ShipperAgent shipperAgent; 
    protected DefaultTableModel tableModel; 

    public Coordinator(ShipperAgent sa, DefaultTableModel tm) { 
     shipperAgent = sa; 
     tableModel = tm; 
    } 

    public abstract void notifyAndAddRow(Object[] rowData); 

    public abstract void notifyAndDeleteRow(int rowIndex); 
} 

} 
+1

첫 번째 질문에서 특정 질문을 발견 할 수 없습니다. 두 번째 문제 –

+0

불명확하면 죄송합니다. 첫 번째 질문에 대해서는 jTable에서 Icon을 사용하는 방법을 알고 싶지만 정보의 일부처럼 아이콘을 처리하고 싶지는 않습니다. 나는 jTable이 그 자체로 차량의 종류를 깨닫고 주행성의 아이콘을 바꾸기를 원합니다. 내가 어디에서 할 수 있니? – Gioce90

답변

2

첫 번째 구현이 내 실망에 좋지 않다는 것을 알고 있습니다. 벡터, 객체, 문자열 만 사용할 수 있기 때문에 먼저 DefaultTableModel을 사용하는 것이 큰 한계입니다. 제 경우에는 jtable을 사용하여 차량 세트를 조작하고 싶습니다. 그래서, 첫 번째 것들 :

Vehicle.java 이제

public class Vehicle { 

    enum TipoVeicolo { 
     AUTO, FURGONE, 
     AUTOCARRO, 
     AUTOARTICOLATO 
    }; 

    private String targa; 
    private TipoVeicolo tipoVeicolo; 
    private String marca; 
    private Stato stato 
    private float ptt; 
    //... others... 

    // constructor 
    public Vehicle(String targa, TipoVeicolo tipoVeicolo, String marca, Stato stato, float ptt) { 
     this.targa=targa; 
     this.tipoVeicolo=tipoVeicolo; 
     // ... bla bla 
    } 

    // GET and SET methods... 
    //... 
} 

, 나는 이미 이런 짓을했다. 새로운는 AbstractTableModel가 (그리고하지의 DefaultTableModel)를 확장하는 클래스

VehicleTableModel.java이 후

public class VehicleTableModel extends AbstractTableModel { 

    // private objects 
    private ArrayList<Vehicle> vehicles; 
    private COLUMNS[] header; 

    // possible column names: 
    public enum COLUMNS { 
     IMAGE_COLUMN, 
     TARGA_COLUMN, 
     CAR_TYPE_COLUMN, 
     //... 
    }; // if I want I can add others... 



    /////////////////////////////////////////////////////// 
    // Constructor: 

    public VehicleTableModel(COLUMNS[] headerTable) { 
     this.vehicles = new ArrayList<Vehicle>() 
     this.header = headerTable; 
    } 


    /////////////////////////////////////////////////////// 
    // obligatory override methods (from AbstractTableModel): 

    @Override 
    public int getColumnCount() { 
     return header.length; 
    } 

    @Override 
    public int getRowCount() { 
     return vehicles.size(); 
    } 

    // this works! :D 
    @Override 
    public Object getValueAt(int row, int col) { 
     Object value = "?"; 
     Vehicle v = vehicles.get(row); 
     if (v!=null) { 
      COLUMNS column = header[col]; 
      switch (column) { 
       case IMAGE_COLUMN: 
        int i = findColumn(COLUMNS.CAR_TYPE_COLUMN); // find the right column index 
        Object tipo = getValueAt(row, i); 
        value = (ImageIcon)findImageByColumnCarType(tipo); // find the right icon for the type of vehicle. 
        break; 
       case TARGA_COLUMN: 
        value = v.getTarga(); 
        break; 
       case CAR_TYPE_COLUMN: 
        value = v.getTipoVeicolo(); 
        break; 
       //... 
      } 
     } 
     return value; 
    } 



    /////////////////////////////////////////////////////// 
    // My methods: 

    public void addRow(Vehicle vehicle) { 
     if (!vehicles.contains(vehicle)){ 
      vehicles.add(vehicle); 
      fireTableRowsInserted(0, getRowCount()); // I'm not so sure of this.. 
    } 

    /* I'm not so sure of this.. 
    public boolean removeRow(Vehicle vehicle) { 
     boolean flag = vehicles.remove(vehicle); 
     fireTableRowsDeleted(0, getRowCount()); // or fireTableDataChanged(); ? 
     return flag; 
    }*/ 

    public void removeRow(int row) { 
     vehicles.remove(row); 
     fireTableRowsDeleted(row, row); 
    } 


    public Vehicle getVehicleAt(int row) { 
     return vehicles.get(row); 
    } 

    // found the corresponding column index 
    public int findColumn(COLUMNS columnName) { 
     for (int i=0; i<getColumnCount(); i++) 
      if (columnName.equals(header[i])) 
       return i; 
     return -1; 
    } 

    // found the right image 
    protected static ImageIcon findImageByColumnCarType(Object value) { 
     ImageIcon i = null; 
     if (value.equals(TipoVeicolo.AUTO)) 
      i = new ImageIcon(VehicleTableModel.class.getResource("/images/Car-icon_32.png")); 
     else if (value.equals(TipoVeicolo.AUTOARTICOLATO)) 
      i = new ImageIcon(VehicleTableModel.class.getResource("/images/City-Truck-blue-icon_32.png")); 
     //... 
     return i; 
    } 

    // knows if exist a value (of a column) in all rows 
    private boolean controllIfExist(Object value, int col) { 
     boolean bool = false; 
     for (int i=0; i<getRowCount();i++){ 
      if (value.equals(getValueAt(i, col))){ 
       bool=true; 
       break; 
      } 
     } 
     return bool; 
    } 



    /////////////////////////////////////////////////////// 
    // other methods (from AbstractTableModel) to ovveride: 

    // this works! :D 
    @Override 
    public Class<?> getColumnClass(int col) { 
     Class<?> c; 
     COLUMNS column = header[col]; 
     if (column.equals(COLUMNS.IMAGE_COLUMN)) 
      c = ImageIcon.class; 
     else if (column.equals(COLUMNS.CAR_TYPE_COLUMN)) 
      c = JComboBox.class; 
     // else if blabla.... 
     else c = super.getColumnClass(col); 
     return c; 
    } 

    // this works! :D 
    @Override 
    public String getColumnName(int col) { 
     COLUMNS column = header[col]; 
     if (column.equals(COLUMNS.IMAGE_COLUMN)) 
      return " "; 
     else if (column.equals(COLUMNS.TARGA_COLUMN)) 
      return "Targa"; 
     else if (column.equals(COLUMNS.CAR_TYPE_COLUMN)) 
      return "Tipo veicolo"; 
     // else if blabla... 
     return super.getColumnName(col); 
    }; 


    @Override 
    public boolean isCellEditable(int row, int col) { 
     return true; 
    } 


    @Override 
    public void setValueAt(Object value, int row, int col) { 
     Vehicle v = vehicles.get(row); 
     boolean flag = false; 
     if (v!=null) { 
      COLUMNS column = header[col]; 
      switch (column) { 
       case TARGA_COLUMN: 
        if (!v.getTarga().equals(value)){ 
         if (!controllIfExist(value, col)){ 
          v.setTarga((String) value); 
          flag = true; 
         } 
        } 
        break; 
       case CAR_TYPE_COLUMN: 
        if (!v.getTipoVeicolo().equals(value)){ 
         v.setTipoVeicolo((TipoVeicolo) value); 
         flag = true; 
        } 
        break; 
       // other cases bla bla... 
      } 

      if (flag) // update only if have found modify 
       fireTableRowsUpdated(0, getRowCount()); // or fireTableRowsUpdated(row, row); ? 
     } 
    } 

} 

, 상품을 위해, 나는 VehicleTable이 (JTable의 확장)를 만들 수 있습니다. 그것은

public class VehicleTable extends JTable { 

public VehicleTable(VehicleTableModel vehicleModel) { 
    super(vehicleModel); 
    this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
    this.setColumnSelectionAllowed(false); 
    this.setCellSelectionEnabled(false); 
    this.setRowSelectionAllowed(true); 
    this.setShowHorizontalLines(true); 
    this.setRowHeight(25); 
    this.setPreferredScrollableViewportSize(new Dimension(700,150)); 
    this.setFillsViewportHeight(true); 

    //////////////////////////////////// 
    // Now I set the columns features: 
    int flag=-1; 
    TableColumn column; 

    // Icon Column: 
    flag = vehicleModel.findColumn(COLUMNS.IMAGE_COLUMN); 
    if (flag!=-1){ 
     column = this.getColumnModel().getColumn(flag); 
     column.setMinWidth(80); 
     column.setMaxWidth(80); 
    } 

    // Targa Column: 
    flag = vehicleModel.findColumn(COLUMNS.TARGA_COLUMN); 
    if (flag!=-1){ 
     column = this.getColumnModel().getColumn(flag); 
     column.setMinWidth(100); 
     column.setMaxWidth(100); 
    } 

    // Tipo veicolo Column 
    flag = vehicleModel.findColumn(COLUMNS.CAR_TYPE_COLUMN); 
    if (flag!=-1){ 
     column = this.getColumnModel().getColumn(flag); 
     column.setCellEditor(new DefaultCellEditor(
       new JComboBox<TipoVeicolo>(TipoVeicolo.values()))); 
     column.setMinWidth(150); 
     column.setMaxWidth(150); 
    } 

    //others... 
} 

마지막으로

VehicleTable.java을 쓸모없는 것처럼 보이지만, (예를 들어, JComboBox에와 셀) ... 당신은 특별한 세포에 적합한 설정을 볼 수 있습니다 내 목적에 적합한 수, 우리 이것을 사용할 수 있습니다.

enter image description here

나는 아직도 정의 할 필요가 내 GUI

ShipperAgentGUI.java의 예를 들어 당신은 여기에 결과를 볼 수 있습니다

public class ShipperAgentGUI extends JFrame implements ActionListener { 

    // ... bla bla 

    private COLUMNS[] parkModelHeader = {COLUMNS.IMAGE_COLUMN, COLUMNS.TARGA_COLUMN, 
     COLUMNS.CAR_TYPE_COLUMN, COLUMNS.MARCA_COLUMN, COLUMNS.STATE_COLUMN, COLUMNS.PTT_COLUMN }; 
    private VehicleTableModel parkModel = new VehicleTableModel(parkModelHeader); 
    private VehicleTable parkTable; 
    private Coordinator parkCoordinator; // long story 

    protected ShipperAgent shipperAgent; // my agent, my third-part software 

    // ... bla bla 

    // Constructor: 
    ShipperAgentGUI(ShipperAgent agent) { 

     //... bla bla 

     // Park Table: 
     parkTable = new VehicleTable(parkModel); 
     JScrollPane parkScrollPane = new JScrollPane(parkTable); 
     pnlTableParkPanel.add(parkScrollPane); 

     //... bla bla 

     // Coordinators (Mediator pattern's ispired) 
     // Long story. Is for coordinating with my agent and others tables in my GUI 
     parkCoordinator = new Coordinator(shipperAgent, parkModel) { 

      @Override 
      public void notifyAndAddRow(final Vehicle vehicle) { 
       shipperAgent.newTruck(vehicle.getTarga()); // comunicate with the agent 

       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         parkModel.addRow(vehicle); 
        } 
       }); 
      } 

      @Override 
      public void notifyAndDeleteRow(final int rowIndex) { 
       final Vehicle v = this.tableModel.getVehicleAt(rowIndex); 
       // bla bla 
       shipperAgent.removeTruck(v.getTarga()); // comunicate with the agent 

       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         //parkModel.removeRow(v); 
         parkModel.removeRow(rowIndex); 
        } 
       }); 
      } 
@Override 
public void notifyRowUpdated() { 
    parkModel.addTableModelListener(new TableModelListener() { 
     public void tableChanged(TableModelEvent e) { 
      switch (e.getType()) { 
       case (TableModelEvent.DELETE): 
        parkTable.repaint(); 
        break; 
       case (TableModelEvent.UPDATE): 
        int row = e.getLastRow(); 
        int col = parkModel.getIndexColumn(COLUMNS.STATE_COLUMN); 
        if (parkModel.getValueAt(row, col).equals(Stato.DISPONIBILE)) 
         addVehicle(availablesCoordinator, parkModel.getVehicleAt(row)); 
        else 
         //removeVehicle(availablesCoordinator, row); error! 
         availablesModel.removeRow(parkModel.getVehicleAt(row)); 
        repaint(); 
        break; 
      } 
     } 
    }); 
} 
     }; 


     ArrayList<Vehicle> veicoli = shipperAgent.getVehicles(); // from agent 
     Iterator<Vehicle> I = veicoli.iterator(); 
     while (I.hasNext()){ 
      addVehicle(parkCoordinator, I.next()); 
     } 

     //... bla bla 

    } // end of constructor 

    // ... others methods... 

    private void addVehicle(Coordinator coordinator, Vehicle v) { 
     coordinator.notifyAndAddRow(v); 
    } 

    public void removeVehicle(Coordinator coordinator, int index) { 
     coordinator.notifyAndDeleteRow(index); 
    } 

    // ... 

} 

(. 추출 나는 하나 개의 테이블에 초점) 두 가지가 있지만 올바른 방법이어야합니다.

+1

+1하지만'Map'으로 이미지를 캐쉬합니다. 'getValueAt'는 꽤 자주 호출됩니다. 그래서 끊임없이 정보 검색을하는 것은 자원 낭비입니다. –

+0

@peeskillet 예, 제가 알아서하겠습니다. 가까운 미래에 제가 할 일이 있습니다. 고맙습니다 – Gioce90

2

"나는 사용 방법을 JTable의에서 아이콘을 알고 싶지만의 일부처럼 아이콘을 처리하지 않으려는 .

: 정보는 내가 JTable가 그 자체로 차량의 종류를 실현하고 당신이 함께 일을하려고 정말 힘든 시간을 보내려고 conseguency의 아이콘 "

를 변경하려면

이미지 열 값으로 다른 것을 사용하는 것이 좋습니다. null 값을 가질 수 있음을 기억하십시오.

중요한 것부터 먼저,이 :

Object[] vehicle = {"/image/truck.png" ,"aaa", "kind1", 
        "marca", "disponibile", "ptt" }; 

ImageIcon.class이 될 것입니다, 당신은 기본 렌더러는 이미지로 열을 렌더링, getColumnClass() 오버라이드 (override) 한 이후이

Object[] vehicle = {new ImageIcon(...) ,"aaa", "kind1", 
        "marca", "disponibile", "ptt" } 

가 될 수 감지 됨. How to use Tables: Editors and Renderers을 참조하십시오.

주된 질문은 차량의 종류에 따라 이미지를 동적으로 바꿀 수있는 방법입니다. 테이블 모델의 setValueAt을 무시할 수 있습니다.

DefaultTableModel model = new DefaultTableModel(...) { 
    private static final int CAR_TYPE_COLUMN = 2; 
    private static final int IMAGE_COLUMN = 0; 

    @Override 
    public void setValueAt(Object value, int row, int col) { 
     if (col == CAR_TYPE_COLUMN) { 
      ImageIcon icon = findImageByColumnCarType(value); 
      super.setValueAt(icon, row, IMAGE_COLUMN); 
     } 
     super.setValueAt(value, row, col); 
    } 

    public Class<?> getColumnClass(int columnIndex) { 
     return getValueAt(0, columnIndex).getClass(); 
    } 
}; 

findImageByColumnCarType 같은 뭔가가 value에 따라 ImageIcon을 찾을 수있는 몇 가지 방법입니다. setValueAt은 귀하의 경우에는 콤보 박스에 의해 편집자에 의해 호출됩니다. 따라서 값을 설정할 때 콤보 상자의 값은 setValueAt으로 전달되며이를 사용하여 findImageByColumnCarType 메서드를 호출하여 ImageIcon을 가져올 수 있습니다. Map 또는 아이콘과 해당 값을 저장하는 데 사용할 수 있습니다. 당신은 어떤 이미지를

이없는 자동차 유형에 대한 방법을 반환 null을 가질 수 있습니다 당신은 일단 ImageIcon 당신이 단지 같은 행의 이미지 열에 대한 새로운 아이콘을 설정 super.setValueAt를 호출의 문제, 싶다.

+0

은 좋은 답변입니다. 하지만 ** setValueAt ** 구현에 ** 문제가 있습니다 ** ** TableModelListener **에 대한 업데이트가 두 번 있습니다. 불가능 하나 줄일 수 있습니까? – Gioce90

+0

** 반드시'setValueAt'를 써야합니다. 두 개의 테이블 + 두 개의 테이블 모델 == 두 개의'setValueAt' –

+0

'DefaultTableModel'을 확장하는 클래스를 만들고 싶다면 그 클래스의 두 인스턴스를 사용할 수 있습니다. 이렇게하면 한 번만 할 필요가 없습니다. 두 개의 _anonymous_ 클래스를 사용하고 있으므로 두 번 수행해야합니다. –