复杂使用JTable,TableModel等 [英] Complex use of JTable, TableModel and others

查看:130
本文介绍了复杂使用JTable,TableModel等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

管理两个JTable和相关数据时遇到了一些问题。

I have some problems with the manage of two JTable, and relative data.

我做了这个GUI:

I had make this GUI:

我解释一下使用:
在第一个jTable我列出了车辆(卡车,汽车......)和相关信息。
在第二个jTable中,我有一个我想要的车辆列表可用(即sw代理启动),按下绿色箭头。所以,是第一个列表的子列表:第一个表中选择的行被复制到第二个列表中。

I explain the use: In the first jTable I have a list of vehicles (trucks, cars...) and relative info. In the second jTable I have a list of vehicles that I want make "available" (i.e. a sw agent starts), with the press of the green arrow. So, is a sublist of the first list: the row selected in the first table are copied in the second.

第一个问题:
在第一列中我有这种车辆的解释图像(你可以在示例中看到一辆卡车)。
在第三和第五列中,我有不同的jComboBox。参见TIPO VEICOLO的jComboBox(即Kind):如果我选择不同的车辆,第一列中的图像必须改变! (如果我选择从卡车改为卡车,相关的图标必须更改)。
此外,我可能不希望在软件的其他地方处理此图标。我解释:我想要使用

First problem: In the first column I have a explicative image of the kind of vehicle (you can see a truck in the example). In the third and fifth column I have different jComboBoxs. See the jComboBox of TIPO VEICOLO (i.e. Kind): if I choose a different vehicle the Image in the first column must change! (if I choose to change from Truck to Car, the relative Icon must change). Moreover, possibily, I don't want handle this icon in other places in the software. I explain: I want use

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

从不

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

第二个问题:
将来我想在jTable中添加其他功能:尺寸,车辆颜色,许可证...
我知道卡车的功能与汽车的功能不同。我想要一种方法来保持标题中的所有功能,但是在每一行(根据车辆类型)激活/禁用一些单元格。

Second problem: In the future I want add other features in the jTable: dimensions, vehicle's color, licence... I know that the features for a truck are different from features for a car. I want a way for keep all features in the header, but in every row (according the kind of vehicle) to activate/disable some cells.

请注意:标题jTables不一定相同

Please note: The headers of jTables are not necessarily the same

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);
}

}


推荐答案

我明白我的第一次实施不利于我的紧急情况。
首先,使用DefaultTableModel是一个很大的限制,因为你只能使用Vector,Object,String ...
在我的情况下,我希望通过jtable操作一组Vehicle。所以,第一件事:

I have understand that my first implementation isn't good for my exigence. First things first, the using of DefaultTableModel is a great limitation, because you can use only Vector, Object, String... In my case, I want manipulate by jtable a set of Vehicles. So, the first things:

Vehicle.java

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

现在,我已经这样做了。 new是扩展AbstractTableModel(而不是DefaultTableModel)的类

Now, I had already done this. The new is the class that extends AbstractTableModel (and not DefaultTableModel)

VehicleTableModel.java

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的单元格)

After this, for commodity, I create a VehicleTable (extends JTable). Can it look like useless, but is right for my objective... You can see the right settings for the special cells (cell with JComboBox, for example)

VehicleTable。 java

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中

Finally, we can use this. For example in my GUI

ShipperAgentGUI.java(一个摘录。我专注于一个表)

ShipperAgentGUI.java (an extract. I focus on ONE table)

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);
    }

    // ...

}

You can see the results here:

You can see the results here:

I still need to define a couple of things, but it should be the right way.

I still need to define a couple of things, but it should be the right way.

这篇关于复杂使用JTable,TableModel等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆