2014-10-01 2 views
0

У меня есть некоторые проблемы с управлением двумя JTable и относительными данными.Сложное использование JTable, TableModel и других

Я был сделать это графический интерфейс: enter image description here

я объясняю использование: В первом JTable У меня есть список транспортных средств (грузовые, легковые автомобили ...) и относительная информация. Во втором jTable у меня есть список транспортных средств, которые я хочу сделать «доступными» (т. Е. Запускается агент), нажатием зеленой стрелки. Итак, это подписок в первом списке: строка, выбранная в первой таблице, копируется во второй.

Первая проблема: В первом столбце у меня есть объяснительное изображение транспортного средства (в примере вы можете увидеть грузовик). В третьей и пятой колонке у меня разные jComboBox. См. JComboBox TIPO VEICOLO (т. Е. Вид): если я выбираю другое транспортное средство, изображение в первом столбце должно измениться! (если я решила перейти из Truck to Car, относительная Icon должна измениться). Кроме того, возможно, я не хочу обращаться с этим значком в других местах программного обеспечения. Я объясняю: я хочу использовать

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

и никогда не

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

Второй проблемы: В будущем я хочу добавить другие функции в JTable: размеры, автомобиль цвета, лицензию ... я знаю что функции для грузовика отличаются от особенностей автомобиля. Я хочу, чтобы сохранить все функции в заголовке, но в каждой строке (в зависимости от типа транспортного средства) активировать/отключить некоторые ячейки.

Обратите внимание: Заголовки JTable: не обязательно же

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

Я не могу определить конкретный вопрос в первой _or_ второй проблеме –

+0

извините, если неясно. В первом вопросе я хочу знать способ использования значка в jTable, но НЕ хочу, чтобы этот значок был как часть информации. Я хочу, чтобы jTable сам реализовал вид транспортного средства и изменил икону консенсуса. Где я могу это сделать? – Gioce90

ответ

2

Я понял, что моя первая реализация не очень хороша для моей привязанности. Во-первых, использование DefaultTableModel - отличное ограничение, потому что вы можете использовать только Vector, Object, String ... В моем случае я хочу манипулировать 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). Может ли это выглядеть бесполезным, но подходит для моей цели ... Вы можете увидеть правильные настройки для специальных клеток (клетки с JComboBox, например)

VehicleTable.java

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... 
} 

Наконец, мы может использовать это. Например, в моем 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); 
    } 

    // ... 

} 

Вы можете увидеть результаты здесь:

enter image description here

мне еще нужно определить несколько вещей, но это должен быть правильный путь.

+1

+1 Но я просто буду кэшировать изображения в «карте». 'getValueAt' вызывается довольно часто. Поэтому постоянное выполнение IO - это пустая трата ресурсов. –

+0

@peeskillet да, я беру вашу точку зрения ... в ближайшем будущем я это сделаю. спасибо – Gioce90

2

«Я хочу знать путь для использования иконки в JTable, но не хочу обращаться значок, как часть из . Я хочу, чтобы информация о том, что JTable реализует сам по себе вид автомобиля и изменить значок conseguency»

Вы собираетесь иметь очень трудное время, пытаясь сделать это с этим:

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

Лучше использовать другой, со значением для столбцов изображения. Помните, что вы можете иметь нулевые значения.

Перво-наперво, это:

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

Может быть это

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

Поскольку вы переопределены getColumnClass(), визуализатор по умолчанию будет оказывать столбец как образ, как ImageIcon.class будет обнаружено. См. 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 некоторый метод, чтобы найти ImageIcon на основе value. setValueAt будет вызываться редактором, в вашем случае - поле со списком. Поэтому, когда значение будет установлено, значение поля со списком будет передано в setValueAt, и вы можете использовать его для вызова метода findImageByColumnCarType, чтобы получить ImageIcon. У вас может быть Map или что-то, что вы используете для хранения значков и соответствующих значений. Вы можете иметь метод возврата null для типа автомобиля, который не имеет образа

После того, как у вас есть ImageIcon вы хотите, это просто вопрос вызова super.setValueAt установить новую иконку для столбца изображения для той же строки.

+0

- хороший ответ. Но у меня есть проблема ... с этой реализацией ** setValueAt ** у нас есть TWO раз UPDATE для ** TableModelListener **. Невозможно уменьшить на одном? – Gioce90

+0

** ДОЛЖЕН ** выполняться с 'setValueAt'. Две таблицы + две табличные модели == two 'setValueAt' –

+0

Если вы хотите создать класс, который расширяет' DefaultTableModel', то вы можете просто использовать два экземпляра этого класса. Таким образом, вам нужно только сделать это один раз. Вы используете два класса _anonymous_, поэтому вам нужно сделать это дважды. –

Смежные вопросы