I want to make a table in a view part which will be dynamically updated (row count, column count, column name). The model is a collection of string array. Can I do that?
The easiest way to do that would be to use a TableViewer instance, specify its content provider and then, you can call its refresh() method every time a change has been made to its content.
#itun. Simplest way to show columns dynamically is to create all columns and set the width of unnecessary columns to zero.
There is another way (which I am using) to create dynamic columns is as follow.
Create Extension Point for columns (column name,orientation,data provider)
Create Extension of by using step 1.
Implementation of creating columns in View.
String[] id = preferences.getString(PREFS_COLUMNS).split(";");
for (int i = 0; i < id.length; i++) {
String name = "";
int style = SWT.LEFT;
Image image = null;
ILabelProvider provider = registry.createLabelProvider(id[i]);
if (provider != null) {
name = registry.getName(id[i]);
style = registry.getOrientation(id[i]);
if (provider instanceof ITableLabelProvider) {
name = ((ITableLabelProvider) provider).getColumnText(null, i);
image = ((ITableLabelProvider) provider).getColumnImage(null, i);
}
} else {
LogFactory.getLog(getClass()).warn("Missing column [" + id[i] + "]");
}
if (index < table.getColumnCount()) {
tableColumn = table.getColumn(index);
if (tableColumn.getData("labelProvider") != null)
((ILabelProvider) tableColumn.getData("labelProvider")).dispose();
} else {
tableColumn = new TableColumn(table, style);
tableColumn.addControlListener(columnControlListener);
tableColumn.addSelectionListener(columnSelectionListener);
tableColumn.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (e.widget.getData("labelProvider") != null)
((ILabelProvider) e.widget.getData("labelProvider")).dispose();
}
});
}
tableColumn.setText(name);
tableColumn.setAlignment(style);
tableColumn.setImage(image);
tableColumn.setMoveable(true);
tableColumn.setData("labelProvider", provider);
tableColumn.setData("columnId", id[i]);
index++;
}
Related
I have the following code, that allows me to remove a row from the right Jtable with a click. It works fine for all the rows, except when there is only one row remaining. BTW, sorry for most names being in portuguese, its my native language. Here are the images showing before and after i click the final row in the table. It updates the total, but the row remains. For every other case, it works perfectly.
Screenshot:
private void jtbSelecionadosMouseClicked(java.awt.event.MouseEvent evt)
{
int x = jtbSelecionados.rowAtPoint(evt.getPoint());
if (x >= 0)
{
String nomeProduto = (String)jtbSelecionados.getModel().getValueAt(x, 0);
for (int i = 0; i < itensVenda.size();i++)
{
if (itensVenda.get(i).getNomeProduto().equals(nomeProduto))
{
if(itensVenda.get(i).getQtd() > 1)
{
valorTotal -= (itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd());
double precototal = itensVenda.get(i).getPreco();
double unit = precototal / itensVenda.get(i).getQtd();
System.out.println("Unidade: "+unit+"\nTotal: "+precototal);
itensVenda.get(i).setPreco(itensVenda.get(i).getPreco() - (itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd()));
itensVenda.get(i).setQtd(itensVenda.get(i).getQtd() - 1);
recarregarTabela();
}
else if(itensVenda.get(i).getQtd() <= 1)
{
valorTotal -= itensVenda.get(i).getPreco() / itensVenda.get(i).getQtd();
itensVenda.remove(i);
recarregarTabela();
}
}
}
}
function that resets the table with new information:
private void recarregarTabela()
{
if (itensVenda.size() == 0)
{
dtm.getDataVector().removeAllElements();
dtm.setRowCount(0);
lblTotal.setText("Total: R$" + String.valueOf(valorTotal));
}
else
{
dtm.getDataVector().removeAllElements();
dtm.setRowCount(0);
for (Item item : itensVenda)
{
Object[] vetor = new Object[3];
vetor[0] = item.getNomeProduto();
vetor[1] = item.getQtd();
vetor[2] = String.format("%.2f", item.getPreco());
System.out.println(item.getPreco());
dtm.addRow(vetor);
}
lblTotal.setText("Total: R$" + String.valueOf(valorTotal));
}
}
You dont have to rebuild whole model everytime a single row is deleted. As you already have index of clicked or selected row you can just remove it from model using removeRow(index) method. I suspect that dtm is a DefaultTableModel so just call dtm.removeRow(index) everytime you need to remove row from table
I am looking to get the value of the selected row in an AbstractTableModel and I am noticing some things. It is correctly reporting what sell (row) I am on, when it is selected, but as soon as I click my button to remove, the selected row value goes to 0. Resulting in the 0 row always being removed. I want to get the value int selectedRow and use it to remove it from the table and my ArrayLists.
ListSelectionModel rsm = table.getSelectionModel();
ListSelectionModel csm = table.getColumnModel().getSelectionModel();
csm.addListSelectionListener(new SelectionDebugger(columnCounter,csm));
columnCounter = new JLabel("(Selected Column Indices Go Here)");
columnCounter.setBounds(133, 62, 214, 14);
csm.addListSelectionListener(new SelectionDebugger(columnCounter,csm));
contentPane1.add(columnCounter);
rowCounter = new JLabel("(Selected Column Indices Go Here)");
rowCounter.setBounds(133, 36, 214, 14);
rsm.addListSelectionListener(new SelectionDebugger(rowCounter, rsm));
contentPane1.add(rowCounter);
SelectionDebugger:
public class SelectionDebugger implements ListSelectionListener {
JLabel debugger;
ListSelectionModel model;
public SelectionDebugger(JLabel target, ListSelectionModel lsm) {
debugger = target;
model = lsm;
}
public void valueChanged(ListSelectionEvent lse) {
if (!lse.getValueIsAdjusting()) {
// skip all the intermediate events . . .
StringBuffer buf = new StringBuffer();
int[] selection = getSelectedIndices(model.getMinSelectionIndex(),
model.getMaxSelectionIndex());
if (selection.length == 0) {
buf.append("none");
//selectedRow = buf.toString();
}
else {
for (int i = 0; i < selection.length -1; i++) {
buf.append(selection[i]);
buf.append(", ");
}
buf.append(selection[selection.length - 1]);
}
debugger.setText(buf.toString());
System.out.println("CampaignConfiguration: Selected Row: " + selection[selection.length - 1]);
// Set the selected row for removal;
selectedRow = selection[selection.length - 1];
}
}
// This method returns an array of selected indices. It's guaranteed to
// return a nonnull value.
protected int[] getSelectedIndices(int start, int stop) {
if ((start == -1) || (stop == -1)) {
// no selection, so return an empty array
return new int[0];
}
int guesses[] = new int[stop - start + 1];
int index = 0;
// manually walk through these . . .
for (int i = start; i <= stop; i++) {
if (model.isSelectedIndex(i)) {
guesses[index++] = i;
}
}
// ok, pare down the guess array to the real thing
int realthing[] = new int[index];
System.arraycopy(guesses, 0, realthing, 0, index);
return realthing;
}
}
}
The TableModel has nothing to do with selection. The View(JTable) is responsible for the selection.
I want to get the value int selectedRow and use it to remove it from the table and my ArrayLists.
You should NOT have separate ArrayLists. The data should only be contained in the TableModel.
If you want to delete a row from the table (and the TableModel) then you can use the getSelectedIndex() method of the table in your ActionListener added to the "Delete" button. Something like:
int row = table.getSelectedIndex();
if (row != -1)
{
int modelRow = table.convertRowIndexToModel( row );
tableModel.removeRow( modelRow );
}
If you are not using the DefaultTableModel, then your custom TableModel will need to implement the "removeRow(...)" method.
I need to know how to check if there is data in a JTable something like
if(jTextField1.getText().isEmpty()):
then (if jTable1.isEmpty())
...
how I do that?
JTables are not simple components like the jtextfield, like other swing components they have an underlying Data Model, check this example from the javadoc:
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 10; }
public int getRowCount() { return 10;}
public Object getValueAt(int row, int col) { return new Integer(row*col); }
};
JTable table = new JTable(dataModel);
Like in every UI object that follows the MVC pattern, you don't use the graphical component to understand the values it has, you use the data model. In you case, save a reference to the Data Model of the JTable you created and call getRowCount to know how much data you have previously loaded.
Also, check the official docs here.
I validate if the jtable is empty with
this code.
private int calculate() {
Vector<Integer> myvector = new Vector();
TableModel mode = new DefaultTableModel();
mode = jTable2.getModel();
int n = mode.getRowCount();
for (int i = 0; i < n; i++) {
if (mode.getValueAt(i, 3) != null) {
myvector.add((Integer) mode.getValueAt(i, 3));
}
}
return myvector.size();
}
//then I validate with a button
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
int numofvalidrows;
numofvalidrows = calculate();
if (numofvalidrows == 0) //if the size of the vector is 0 then the jtable is empty
{
System.out.println("You need to add people to the jtable, because the table is empty");
} else {
// I get the values of the jtable with
for (int i = 0; i < n; i++) {
if (model.getValueAt(i, 3) != null) { //whith this "if" I print only data, not print null of the empty cells in jtable
System.out.print(model.getValueAt(i, 3))
}
}
}
}
i want to add a cloumn to a jtable when a radio button is being clicked. but when i click it twice two columns are being added to the table. here's my code
dtm = (DefaultTableModel) viewTable.getModel();
dtm.setRowCount(0);
TableColumnModel model=viewTable.getColumnModel();
boolean found=false;
for (int i = 0; i < viewTable.getColumnCount(); i++) {
if (model.getColumn(i).getIdentifier().equals("customer Id")) {
found=true;
break;
}
if (found==false) {
dtm.addColumn("customer Id");
}
don't know how to fix it..
This code would help you. Call the below method on actionPerformed of the check box and if it is true. Validating it based on the column header.
private static void addColumn( final JTable table, final String newColumnHeader )
{
final JTableHeader header = table.getTableHeader();
final int columnCount = header.getColumnModel().getColumnCount();
boolean addColumn = true;
for( int index = 0; index < columnCount; index ++ )
{
final Object headerValue = header.getColumnModel().getColumn(index).getHeaderValue();
if( newColumnHeader.equals( headerValue ) )
{
JOptionPane.showMessageDialog(null, "Column already exists" );
addColumn = false;
break;
}
}
if( addColumn )
{
final TableColumn newCol = new TableColumn();
newCol.setHeaderValue(newColumnHeader);
table.getColumnModel().addColumn(newCol);
}
}
It is good to disable the checkbox if it is already clicked ;) if you do not want a huge code.
This is a clumsy solution but it will work.
You can create a new boolean variable in your class and this variable represents if a column was set or not.
Like:
class MyClass{
boolean isColumnAdded
public MyClass(){
isColumnAdded = false;
}
private void radioButtonActionPerformed(java.awt.event.ActionEvent evt){
if(!isColumnAdded){
//add column
isColumnAdded = true;
}
}
}
To start with, JRadioButton has a selected property. You should be checking this state to determine if the column needs to be removed or added...
Assume that each column name is unique, you could use something like...
TableColumnModel model = viewTable.getColumnModel();
int index = -1;
try {
index = model.getColumnIndex("customer Id");
} catch (IllegalArgumentException e) {
// I know, sucks...
}
if (index < 0) {
// Add new column, if JRadioButton.isSelected
} else {
// Remove old column...
// JRadioButton.isSelected is false...
}
To find and add/remove the column.
Have a look at How to Use Buttons, Check Boxes, and Radio Buttons for some more details
I want to add some columns to a table (Swing JTable). Some of them will have a default size (e.g. 250), others will be hidden (so their size will be 0). I use this code:
model = new DefaultTableModel();
table = new JTable(model);
setAutoResizeMode(AUTO_RESIZE_OFF);
for (int i = 1; i < COLUMN_NAMES.length; i++) {
model.addColumn(COLUMN_NAMES[i]);
if (show[i]) show(index);
else hide(index);
}
........
private void hide(int index) {
TableColumn column = getColumnModel().getColumn(index);
column.setMinWidth(0);
column.setMaxWidth(0);
column.setWidth(0);
column.setPreferredWidth(0);
doLayout();
}
private void show(int index) {
final int width = 250;
column.setMinWidth(15);
column.setMaxWidth(width);
column.setWidth(width);
column.setPreferredWidth(width);
doLayout();
}
the problem is when the table is displayed, all the columns are showed (none is hidden) and their size is not 250 but they have all the same size.
How can I get the wanted effect?
I think you have named your methods incorrectly, when you want to hide a column you will set
column.setMinWidth(0);
column.setMaxWidth(0);
column.setPreferredWidth(0);
but in your code you are doing this when you want to show a column which is exactly opposite.
Also there is no need to call this "setWidth" method on a TableColumn, read TableColumn#setWidth(int).
JTable#removeColumn remove Column only from JTable view, more in this example
instead of re-inventing the wheel you might consider to use JXTable (in the SwingX project) which supports hidden columns, comlete with a ui-control to allow users hiding/showing them dynamically - and a bunch of other useful thingies :).
try this something like this for example:
myTableModel = new DefaultTableModel();
myTableModel.setColumnIdentifiers(new Object[]{"ID", "Name"});
JTable myTable = new JTable(myTableModel);
// remember to save the references
TableColumn myTableColumn0 = guiLoteryNumbersTable.getColumnModel().getColumn(0);
TableColumn myTableColumn1 = guiLoteryNumbersTable.getColumnModel().getColumn(1);
//...
// remove temporary the column ("hide")
myTable.getColumnModel().removeColumn(myTableColumn1);
// then you restore that column when you need it ("show")
myTable.getColumnModel().addColumn(myTableColumn1);
That's the best way I know to hide a column.
HashMap<String,TableColumn> hashMap_columns = new HashMap<String,TableColumn>();
DefaultTableColumnModel defaultTableColumnModel = (DefaultTableColumnModel)jtable.getColumnModel();
Enumeration<TableColumn> enumeration = defaultTableColumnModel.getColumns();
while (enumeration.hasMoreElements())
{
TableColumn tableColumn = enumeration.nextElement();
hashMap_columns.put((String)tableColumn.getIdentifier(),tableColumn);
}
public void setColumnVisible(String identifier, boolean setVisible)
{
TableColumn tableColumn = hashMap_columns.get(identifier);
if (setVisible)
{
// using a sorted map removes the need to check column index/position
SortedMap<Integer,TableColumn> sortedMap = new TreeMap<Integer,TableColumn>();
// retreive all visible columns
Enumeration<TableColumn> enumeration = defaultTableColumnModel.getColumns();
while (enumeration.hasMoreElements())
{
TableColumn column = enumeration.nextElement();
sortedMap.put(column.getModelIndex(),column);
}
// add the column of interest to the sorted map
sortedMap.put(tableColumn.getModelIndex(),tableColumn);
// remove all visible columns
for (TableColumn column: sortedMap.values())
{
defaultTableColumnModel.removeColumn(column);
}
// add all previously visible columns as well as the column of interest
for (TableColumn column: sortedMap.values())
{
defaultTableColumnModel.addColumn(column);
}
}
else
{
defaultTableColumnModel.removeColumn(tableColumn);
}
}
public class TableColumnHider {
private final JTable table;
private final TableColumnModel tcm;
private final Map hiddenColumns;
public TableColumnHider(JTable table) {
this.table = table;
tcm = table.getColumnModel();
hiddenColumns = new HashMap();
}
public void hide(String columnName, String keySig) {
int index = tcm.getColumnIndex(columnName);
TableColumn column = tcm.getColumn(index);
hiddenColumns.put(columnName, column);
hiddenColumns.put(keySig + columnName, new Integer(index));
tcm.removeColumn(column);
}
public void show(String columnName, String keySig) {
Object o = hiddenColumns.remove(columnName);
if (o == null) {
return;
}
tcm.addColumn((TableColumn) o);
o = hiddenColumns.remove(keySig + columnName);
if (o == null) {
return;
}
int column = ((Integer) o).intValue();
int lastColumn = tcm.getColumnCount() - 1;
if (column < lastColumn) {
tcm.moveColumn(lastColumn, column);
}
}
}