我在管理两个JTable和相关数据时遇到了一些问题。
我做了这个GUI:
我解释一下用法: 在第一个jTable中,我列出了车辆(卡车,汽车......)和相关信息。 在第二个jTable中,我有一个我希望“可用”(即sw代理启动)的车辆列表,按下绿色箭头。因此,是第一个列表的子列表:第一个表中选择的行将复制到第二个列表中。
第一个问题: 在第一列中,我有一个车辆类型的解释图像(您可以在示例中看到一辆卡车)。 在第三和第五列中,我有不同的jComboBox。请参阅TIPO VEICOLO的jComboBox(即Kind):如果我选择不同的车辆,则第一列中的Image必须更改! (如果我选择从卡车改为卡车,相关的图标必须更改)。 此外,我可能不希望在软件的其他地方处理此图标。我解释一下:我想用
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);
}
}
答案 0 :(得分:2)
&#34;我想知道一种在jTable中使用Icon的方法,但是DON&T要想像处理信息的一部分一样处理图标。我希望jTable能够自己实现这种车辆并改变连续性的图标&#34;
你真的很难用这个来做这件事:
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
为同一行的图像列设置新图标即可。
答案 1 :(得分: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...
//...
}
现在,我已经这样做了。 new是扩展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);
}
// ...
}
您可以在此处查看结果:
我仍然需要定义一些东西,但它应该是正确的方法。