/*
* Customized JTable with helpers to coordinate common operations.
*/
/*
Copywrite 2013-2016 Will Winder
This file is part of Universal Gcode Sender (UGS).
UGS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
UGS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with UGS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.willwinder.universalgcodesender.uielements.components;
import com.willwinder.universalgcodesender.i18n.Localization;
import com.willwinder.universalgcodesender.types.GcodeCommand;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
/**
*
* @author wwinder
*/
public class GcodeTable extends JTable {
private static final Logger logger = Logger.getLogger(GcodeTable.class.getName());
//GcodeTableModel model = null;
private DefaultTableModel model = null;
private int maxLines = -1;
private boolean autoWindowScroll = false;
private int offset = 0;
private boolean first = true;
final private static int COL_INDEX_COMMAND = 0;
final private static int COL_INDEX_ORIG_COMMAND = 1;
final private static int COL_INDEX_SENT = 2;
final private static int COL_INDEX_DONE = 3;
final private static int COL_INDEX_RESPONSE = 4;
private static String[] columnNames = {
Localization.getString("gcodeTable.command"),
Localization.getString("gcodeTable.originalCommand"),
Localization.getString("gcodeTable.sent"),
Localization.getString("gcodeTable.done"),
Localization.getString("gcodeTable.response")
};
private static Class[] columnTypes = {
String.class,
String.class,
Boolean.class,
Boolean.class,
String.class
};
public GcodeTable() {
//model = new GcodeTableModel(null, columnNames, columnTypes);
model = new DefaultTableModel(null, columnNames) {
@Override
public Class<?> getColumnClass(int idx) {
return columnTypes[idx];
}
};
this.setModel(model);
getTableHeader().setReorderingAllowed(false);
}
@Override
public void setBounds(int x, int y, int width, int height)
{
super.setBounds(x, y, width, height);
// This is totally bogus, but they look alright when I throw in a max
// width for the boolean columns.
setPreferredColumnWidths(new double[] {0.25, 0.3, 0.2, 0.2, 0.2} );
getColumnModel().getColumn(COL_INDEX_SENT).setResizable(false);
getColumnModel().getColumn(COL_INDEX_SENT).setMaxWidth(50);
getColumnModel().getColumn(COL_INDEX_DONE).setResizable(false);
getColumnModel().getColumn(COL_INDEX_DONE).setMaxWidth(50);
}
public void setAutoWindowScroll(boolean autoWindowScroll) {
this.autoWindowScroll = autoWindowScroll;
}
/**
* Delete all rows from the table.
*/
public void clear() {
while (model.getRowCount()>0){
model.removeRow(0);
}
//model.dropData();
this.offset = 0;
this.first = true;
}
/**
* Update table with a GcodeCommand.
*/
public void addRow(final GcodeCommand command) {
if (first) {
offset = command.getCommandNumber() * -1;
first = false;
}
model.addRow(new Object[]{
command.getCommandString(),
command.getOriginalCommandString(),
command.isSent(),
command.isDone(),
command.getResponse()});
scrollTable(this.getRowCount());
}
/**
* Update table with a GcodeCommand.
*/
public void updateRow(final GcodeCommand command) {
String commandString = command.getCommandString();
int row = command.getCommandNumber() + offset;
// Check for modified command string
String val = (String)model.getValueAt(row, COL_INDEX_COMMAND);
if (!command.isComment() && commandString != model.getValueAt(row, COL_INDEX_COMMAND)) {
String message = String.format(
"Row mismatch [%s] does not match row %d [%s].]\n",
commandString,
row,
model.getValueAt(row, COL_INDEX_COMMAND));
logger.log(Level.WARNING, message) ;
}
model.setValueAt(command.isSent(), row, COL_INDEX_SENT);
model.setValueAt(command.isDone(), row, COL_INDEX_DONE);
model.setValueAt(command.getResponse(), row, COL_INDEX_RESPONSE);
scrollTable(row);
}
/**
* Helper function to scroll table to specific row number.
*/
private void scrollTable(int toRow) {
// Scroll if selected.
if (this.autoWindowScroll) {
if (isVisible()) {
scrollToVisible(toRow);
}
}
}
/**
* Helper function to set preferred widths as a percentage.
* http://stackoverflow.com/questions/1046005/jtable-column-resize-isnt-working
*/
private void setPreferredColumnWidths(double[] percentages) {
Dimension tableDim = getPreferredSize();
double total = 0;
for (int i = 0; i < getColumnModel().getColumnCount(); i++) {
total += percentages[i];
}
for (int i = 0; i < getColumnModel().getColumnCount(); i++) {
TableColumn column = getColumnModel().getColumn(i);
column.setPreferredWidth(
(int)(tableDim.width * (percentages[i] / total)));
}
}
/**
* Helper function to scroll table to specific row.
*/
private void scrollToVisible(int rowIndex) {
getSelectionModel().setSelectionInterval(rowIndex, rowIndex);
scrollRectToVisible(new Rectangle(getCellRect(rowIndex, 0, true)));
}
public void setOffset() {
setOffset(this.getRowCount());
}
public void setOffset(int offset) {
this.offset = offset;
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
}