I have JTable with some rows. I want when move one row with mouse(drag and drop) that row to move together with mouse and table rows to be reorder when mouse move(like moving JTable's columns).
This jsfiddle is exactly what i want but i have to do it in java swing(or gif image below. Example is from here but I can't understand it).
My TransferHandler :
public class TableRowTransferHandler extends TransferHandler {
private final DataFlavor localObjectFlavor = new ActivationDataFlavor(Integer.class, "application/x-java-Integer;class=java.lang.Integer", "Integer Row Index");
private JTable table = null;
private static final Logger logger = Logger.getLogger(TableRowTransferHandler.class.getName());
public TableRowTransferHandler(JTable table) {
this.table = table;
}
#Override
protected Transferable createTransferable(JComponent c) {
assert (c == table);
return new DataHandler(table.getSelectedRow(), localObjectFlavor.getMimeType());
}
#Override
public boolean canImport(TransferHandler.TransferSupport info) {
boolean b = info.getComponent() == table && info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
table.setCursor(b ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop);
return b;
}
#Override
public int getSourceActions(JComponent c) {
return TransferHandler.COPY_OR_MOVE;
}
#Override
public boolean importData(TransferHandler.TransferSupport info) {
JTable target = (JTable) info.getComponent();
JTable.DropLocation dl = (JTable.DropLocation) info.getDropLocation();
int index = dl.getRow();
int max = table.getModel().getRowCount();
if (index < 0 || index > max) {
index = max;
}
target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
try {
Integer rowFrom = (Integer) info.getTransferable().getTransferData(localObjectFlavor);
if (rowFrom != -1 && rowFrom != index) {
((Reorderable) table.getModel()).reorder(rowFrom, index);
if (index > rowFrom) {
index--;
}
target.getSelectionModel().addSelectionInterval(index, index);
return true;
}
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
logger.log(Level.SEVERE, null, e);
}
return false;
}
#Override
protected void exportDone(JComponent c, Transferable t, int act) {
if ((act == TransferHandler.MOVE) || (act == TransferHandler.NONE)) {
table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
}
That is a simple settings that i use to JTable:
childrenTable.setDragEnabled(true);
childrenTable.setDropMode(DropMode.INSERT);
childrenTable.setTransferHandler(new TableRowTransferHandler(childrenTable));
childrenTable.setRowSelectionAllowed(true);
childrenTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
At the moment when you move row with mouse between rows only have one bold line(Like this in red ellipse below in image). If it is impossible to do rows to move like this, i want this bold line to appear to whole row (not only in one cell).
Read the section from the Swing tutorial on Drag and Drop for the basics.
Here is some old code I found somewhere on the web with a custom TransferHandler to support a JTable:
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.IOException;
public class DnD_Demo extends JFrame {
public DnD_Demo() {
setTitle("DnD Demo (Version 3)");
JTextArea tips = new JTextArea("1. Select a row in Table A. " +
"Press the row again and drag. \n " +
"As you drag the cursor icon over Table B, the row that is currently under the cursor highlights " +
"- the new data will be inserted after the selected row. \n " +
"Drop the row onto Table B. Note that the row has been removed from Table A, " +
"and now appears in Table B. \n" +
"2. Select two rows from Table A and drop onto Table B. " +
"Now there are two new rows in Table B. ");
tips.setEditable(false);
tips.setBackground(new Color(255,255,204));
tips.setBorder(new LineBorder(Color.orange,5));
getContentPane().add(tips,BorderLayout.NORTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(2,1));
panel.add(createTable("Table A"));
panel.add(createTable("Table B"));
getContentPane().add(panel,BorderLayout.CENTER);
pack();
}
private JPanel createTable(String tableId) {
DefaultTableModel model = new DefaultTableModel();
model.addColumn("Column 0");
model.addColumn("Column 1");
model.addColumn("Column 2");
model.addColumn("Column 3");
model.addRow(new String[]{tableId+" 00", tableId+" 01", tableId+" 02", tableId+" 03"});
model.addRow(new String[]{tableId+" 10", tableId+" 11", tableId+" 12", tableId+" 13"});
model.addRow(new String[]{tableId+" 20", tableId+" 21", tableId+" 22", tableId+" 23"});
model.addRow(new String[]{tableId+" 30", tableId+" 31", tableId+" 32", tableId+" 33"});
JTable table = new JTable(model);
table.getTableHeader().setReorderingAllowed(false);
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setPreferredSize(new Dimension(400,100));
table.setDragEnabled(true);
table.setTransferHandler(new TableTransferHandler());
JPanel panel = new JPanel();
panel.add(scrollPane);
panel.setBorder(BorderFactory.createTitledBorder(tableId));
return panel;
}
public static void main(String[] args) {
new DnD_Demo().setVisible(true);
}
abstract class StringTransferHandler extends TransferHandler {
protected abstract String exportString(JComponent c);
protected abstract void importString(JComponent c, String str);
protected abstract void cleanup(JComponent c, boolean remove);
protected Transferable createTransferable(JComponent c) {
return new StringSelection(exportString(c));
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
public boolean importData(JComponent c, Transferable t) {
if (canImport(c, t.getTransferDataFlavors())) {
try {
String str = (String)t.getTransferData(DataFlavor.stringFlavor);
importString(c, str);
return true;
} catch (UnsupportedFlavorException ufe) {
} catch (IOException ioe) {
}
}
return false;
}
protected void exportDone(JComponent c, Transferable data, int action) {
cleanup(c, action == MOVE);
}
public boolean canImport(JComponent c, DataFlavor[] flavors) {
for (int i = 0; i < flavors.length; i++) {
if (DataFlavor.stringFlavor.equals(flavors[i])) {
return true;
}
}
return false;
}
}
class TableTransferHandler extends StringTransferHandler {
public JTable target;
public int[] rows = null;
public int addIndex = -1; //Location where items were added
public int addCount = 0; //Number of items added.
protected String exportString(JComponent c) {
JTable table = (JTable)c;
rows = table.getSelectedRows();
int colCount = table.getColumnCount();
StringBuffer buff = new StringBuffer();
for (int i = 0; i < rows.length; i++) {
for (int j = 0; j < colCount; j++) {
Object val = table.getValueAt(rows[i], j);
buff.append(val == null ? "" : val.toString());
if (j != colCount - 1) {
buff.append(",");
}
}
if (i != rows.length - 1) {
buff.append("\n");
}
}
return buff.toString();
}
protected void importString(JComponent c, String str) {
target = (JTable)c;
DefaultTableModel model = (DefaultTableModel)target.getModel();
int index = target.getSelectedRow();
//Prevent the user from dropping data back on itself.
//For example, if the user is moving rows #4,#5,#6 and #7 and
//attempts to insert the rows after row #5, this would
//be problematic when removing the original rows.
//So this is not allowed.
if (rows != null && index >= rows[0] - 1 &&
index <= rows[rows.length - 1]) {
rows = null;
return;
}
int max = model.getRowCount();
if (index < 0) {
index = max;
} else {
index++;
if (index > max) {
index = max;
}
}
addIndex = index;
String[] values = str.split("\n");
addCount = values.length;
int colCount = target.getColumnCount();
for (int i = 0; i < values.length ; i++) {
model.insertRow(index++, values[i].split(","));
}
//If we are moving items around in the same table, we
//need to adjust the rows accordingly, since those
//after the insertion point have moved.
if (rows!= null && addCount > 0) {
for (int i = 0; i < rows.length; i++) {
if (rows[i] > addIndex) {
rows[i] += addCount;
}
}
}
}
protected void cleanup(JComponent c, boolean remove) {
JTable source = (JTable)c;
if (remove && rows != null) {
DefaultTableModel model =
(DefaultTableModel)source.getModel();
for (int i = rows.length - 1; i >= 0; i--) {
model.removeRow(rows[i]);
}
}
rows = null;
addCount = 0;
addIndex = -1;
}
}
}
I think that ListTransferHandler.java for item swapping of JList in the Swing tutorial will be also helpful.
Here is an example that I modified ListTransferHandler for JTable:
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.*;
import java.util.List;
import javax.activation.*;
import javax.swing.*;
import javax.swing.table.*;
public final class TableRowsDnDTest {
private final TransferHandler handler = new TableRowTransferHandler();
private final String[] columnNames = {"String", "Integer", "Boolean"};
private final Object[][] data = {
{"AAA", 12, true}, {"aaa", 1, false},
{"BBB", 13, true}, {"bbb", 2, false},
{"CCC", 15, true}, {"ccc", 3, false},
{"DDD", 17, true}, {"ddd", 4, false},
{"EEE", 18, true}, {"eee", 5, false},
{"FFF", 19, true}, {"fff", 6, false},
{"GGG", 92, true}, {"ggg", 0, false}
};
private final TableModel model = new DefaultTableModel(data, columnNames) {
#Override public Class<?> getColumnClass(int column) {
switch (column) {
case 0:
return String.class;
case 1:
return Number.class;
case 2:
return Boolean.class;
default:
return super.getColumnClass(column);
}
}
};
private final JTable table = new JTable(model);
public JComponent makeUI() {
table.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
table.setTransferHandler(handler);
table.setDropMode(DropMode.INSERT_ROWS);
table.setDragEnabled(true);
table.setFillsViewportHeight(true);
//table.setAutoCreateRowSorter(true); //XXX
//Disable row Cut, Copy, Paste
ActionMap map = table.getActionMap();
Action dummy = new AbstractAction() {
#Override public void actionPerformed(ActionEvent e) { /* Dummy action */ }
};
map.put(TransferHandler.getCutAction().getValue(Action.NAME), dummy);
map.put(TransferHandler.getCopyAction().getValue(Action.NAME), dummy);
map.put(TransferHandler.getPasteAction().getValue(Action.NAME), dummy);
JPanel p = new JPanel(new BorderLayout());
p.add(new JScrollPane(table));
p.setBorder(BorderFactory.createTitledBorder("Drag & Drop JTable"));
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TableRowsDnDTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
//Demo - BasicDnD (Drag and Drop and Data Transfer) https://docs.oracle.com/javase/tutorial/uiswing/dnd/basicdemo.html
//Demo - DropDemo (Drag and Drop and Data Transfer) https://docs.oracle.com/javase/tutorial/uiswing/dnd/dropmodedemo.html
//#see https://docs.oracle.com/javase/tutorial/uiswing/examples/dnd/DropDemoProject/src/dnd/ListTransferHandler.java
//#see https://github.com/aterai/java-swing-tips/blob/master/DnDReorderTable/src/java/example/TableRowsDnDTest.java
class TableRowTransferHandler extends TransferHandler {
private final DataFlavor localObjectFlavor;
private int[] indices;
private int addIndex = -1; //Location where items were added
private int addCount; //Number of items added.
protected TableRowTransferHandler() {
super();
localObjectFlavor = new ActivationDataFlavor(Object[].class, DataFlavor.javaJVMLocalObjectMimeType, "Array of items");
}
#Override protected Transferable createTransferable(JComponent c) {
JTable table = (JTable) c;
DefaultTableModel model = (DefaultTableModel) table.getModel();
List<Object> list = new ArrayList<>();
indices = table.getSelectedRows();
for (int i : indices) {
list.add(model.getDataVector().get(i));
}
Object[] transferedObjects = list.toArray();
return new DataHandler(transferedObjects, localObjectFlavor.getMimeType());
}
#Override public boolean canImport(TransferHandler.TransferSupport info) {
JTable table = (JTable) info.getComponent();
boolean isDropable = info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
table.setCursor(isDropable ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop);
return isDropable;
}
#Override public int getSourceActions(JComponent c) {
return TransferHandler.MOVE;
}
#Override public boolean importData(TransferHandler.TransferSupport info) {
if (!canImport(info)) {
return false;
}
TransferHandler.DropLocation tdl = info.getDropLocation();
if (!(tdl instanceof JTable.DropLocation)) {
return false;
}
JTable.DropLocation dl = (JTable.DropLocation) tdl;
JTable target = (JTable) info.getComponent();
DefaultTableModel model = (DefaultTableModel) target.getModel();
int index = dl.getRow();
int max = model.getRowCount();
if (index < 0 || index > max) {
index = max;
}
addIndex = index;
target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
try {
Object[] values = (Object[]) info.getTransferable().getTransferData(localObjectFlavor);
addCount = values.length;
for (int i = 0; i < values.length; i++) {
int idx = index++;
model.insertRow(idx, (Vector) values[i]);
target.getSelectionModel().addSelectionInterval(idx, idx);
}
return true;
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
return false;
}
#Override protected void exportDone(JComponent c, Transferable data, int action) {
cleanup(c, action == TransferHandler.MOVE);
}
//If the remove argument is true, the drop has been
//successful and it's time to remove the selected items
//from the list. If the remove argument is false, it
//was a Copy operation and the original list is left
//intact.
protected void cleanup(JComponent c, boolean remove) {
if (remove && indices != null) {
c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
DefaultTableModel model = (DefaultTableModel)((JTable) c).getModel();
//If we are moving items around in the same list, we
//need to adjust the indices accordingly, since those
//after the insertion point have moved.
if (addCount > 0) {
for (int i = 0; i < indices.length; i++) {
if (indices[i] >= addIndex) {
indices[i] += addCount;
}
}
}
for (int i = indices.length - 1; i >= 0; i--) {
model.removeRow(indices[i]);
}
}
indices = null;
addCount = 0;
addIndex = -1;
}
}
I add items to a model that is linked to a table. When I select an item in this table, things happen depending on what item it is. For now I just have a System.out telling me the items name.
If I have two items called 'A' and 'B', when I select either their respective name is written to the console as expected, however, if I sort them by name, so that 'B' is placed in the row over 'A', the sorting never happened internally but only visually. So if I now select 'A', the console prints out 'B', and vice versa.
The sorter is declared in the mainclass, itemList is a JTable itemList.setAutoCreateRowSorter(true);
Apparently I must have failed to include some default method that's needed for this sorterfunctionality. "default methods" is declared towards the end in the code-snippet, from and after the method 'getColumnName'.
class ItemModel extends AbstractTableModel
{
ArrayList<MCItem> items = new ArrayList<MCItem>();
private int currentMaxRows = 0;
private String[] columnNames = {"Item", "Total Units", "In Sorter"};
private Class[] types = {String.class, Integer.class, Integer.class};
private Object[][] data = new Object[currentMaxRows][getColumnCount()];
public ArrayList<MCItem> getItems()
{
return items;
}
public void readdItems(Main m, ArrayList<MCItem> tempItems)
{
for(MCItem mci : tempItems)
{
mci.setMain(m);
addRow(mci);
}
}
public void emptyMe()
{
currentMaxRows = 0;
items.clear();
data = new Object[currentMaxRows][getColumnCount()];
fireTableDataChanged();
}
public boolean isDuplicate(String s)
{
for(MCItem ci : items)
if(ci.getName().equalsIgnoreCase(s))
return true;
return false;
}
public void updateItem(String id)
{
try
{
int foundRow = -1;
for(int i = 0;i < currentMaxRows;i++)
if(getValueAt(i, 0).toString().equalsIgnoreCase(id))
{
foundRow = i;
break;
}
for(MCItem ii : items)
if(ii.getName().equalsIgnoreCase(id))
{
setItem(foundRow, ii);
fireTableDataChanged();
return;
}
}
catch(NullPointerException e){}
}
public void addRow(MCItem item)
{
//check if we need to expand the dataArray
if(currentMaxRows == items.size())
{
if(currentMaxRows == 0)
data = new Object[++currentMaxRows][getColumnCount()];
else
{
Object[][] tempArr = data;
data = new Object[++currentMaxRows][getColumnCount()];
for(int x = 0; x < tempArr.length; x++)
for(int y = 0; y < getColumnCount(); y++)
data[x][y] = tempArr[x][y];
}
}
setItem(items.size(), item);
items.add(item);
fireTableDataChanged();
}
public void changeItem(int row, String name)
{
String originalName = (String) data[row][0];
data[row][0] = name;
for(MCItem ii : items)
if(ii.getName().toString().equalsIgnoreCase(originalName))
{
ii.setName(name);
return;
}
fireTableDataChanged();
}
public void removeItem(String id)
{
for(MCItem ii : items)
if(ii.getName().toString().equalsIgnoreCase(id))
{
items.remove(ii);
redoList();
return;
}
fireTableDataChanged();
}
private void redoList()
{
ArrayList<MCItem> tempArr = (ArrayList<MCItem>) items.clone();
emptyMe();
for(MCItem ii : tempArr)
addRow(ii);
}
private void setItem(int row, MCItem item)
{
int counter = 0;
data[row][counter++] = item.getName();
data[row][counter++] = item.getCount();
data[row][counter++] = item.getSorterCount();
fireTableDataChanged();
}
MCItem getMCItem(String name)
{
for(MCItem i : items)
if(i.getName().equals(name))
return i;
return null;
}
public String getColumnName(int col)
{
return columnNames[col].toString();
}
public int getRowCount()
{
return data.length;
}
public int getColumnCount()
{
return columnNames.length;
}
public Object getValueAt(int row, int col)
{
return data[row][col];
}
public Class getColumnClass(int columnIndex)
{
return this.types[columnIndex];
}
public boolean isCellEditable(int row, int col)
{
return false;
}
public void setValueAt(Object value, int row, int col)
{
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
* Answer *
The issue was never the tablemodel, but the JTable itself. When I want to present information based on the item selected, I called
currentMCItem = model.getMCItem(model.getValueAt(itemList.getSelectedRow(), 0).toString());
which returned the index in the JTable correctly, however when sorting all the indexes gets messed up and it's only the view that changes, so I had to redo that line to
currentMCItem = model.getMCItem(model.getValueAt(itemList.convertRowIndexToModel(itemList.getSelectedRow()), 0).toString());
So, the key is to call JTable.convertRowIndexToModel(SELECTED INDEX IN TABLE) in order to get the correct index, and use that as if it was the selectedRow.
You have a set of convert methods in JTable that you need to use. For example, convertColumnIndexToModel takes a view index and gives you back a corresponding column index in the model. Convert them and then get the values.
I want to implement a native drag and drop of widgets of a FlexTable without using any third party library in GWT.Im looking for something similar to this
http://tech.pro/tutorial/688/javascript-tutorial-drag-drop-lists
this is in javascript i want to achieve the similar kind of functionality with GWT
I have looked into the answer provided by #BruceLowe over here
Making a drag and drop FlexTable in GWT 2.5
but its is missing a few classes namely DragVerticalHandler and DraggableWidget classes so the code is not working. Does anyone know how to achieve this
After a little Prototyping I was able to make a drag gable flextable.I created a class which extended the flex table.Here is the code
public class DragFlexTable extends FlexTable implements
MouseDownHandler,MouseUpHandler,MouseMoveHandler,
MouseOutHandler
{
private int row,column,draggedrow,draggedcolumn;
private Element td;
private Widget w;
private boolean emptycellclicked;
DragFlexTable()
{
sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONMOUSEDOWN | Event.ONMOUSEMOVE);
this.addMouseDownHandler(this);
this.addMouseMoveHandler(this);
this.addMouseUpHandler(this);
this.addMouseOutHandler(this);
}
#Override
public void onBrowserEvent(Event event)
{
super.onBrowserEvent(event);
td = getEventTargetCell(event);
if (td == null)
{
return;
}
Element tr = DOM.getParent((com.google.gwt.user.client.Element) td);
Element body = DOM.getParent((com.google.gwt.user.client.Element) tr);
row = DOM.getChildIndex((com.google.gwt.user.client.Element) body, (com.google.gwt.user.client.Element) tr);//(body, tr);
column = DOM.getChildIndex((com.google.gwt.user.client.Element) tr, (com.google.gwt.user.client.Element) td);
}
boolean mousedown;
#Override
public void onMouseDown(MouseDownEvent event)
{
if (event.getNativeButton() == NativeEvent.BUTTON_LEFT)
{
//to ensure empty cell is not clciked
if (!td.hasChildNodes())
{
emptycellclicked = true;
}
event.preventDefault();
start(event);
mousedown = true;
}
}
#Override
public void onMouseMove(MouseMoveEvent event)
{
if (mousedown)
{
drag(event);
}
}
#Override
public void onMouseUp(MouseUpEvent event)
{
if (event.getNativeButton() == NativeEvent.BUTTON_LEFT)
{
if (!emptycellclicked)
{
end(event);
}
emptycellclicked = false;
mousedown = false;
}
}
#Override
public void onMouseOut(MouseOutEvent event)
{
this.getCellFormatter().getElement(row, column).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(row, column).getStyle().clearBorderColor();
this.getCellFormatter().getElement(row, column).getStyle().clearBorderWidth();
w.getElement().getStyle().setOpacity(1);
mousedown = false;
}
private void start(MouseDownEvent event)
{
w = this.getWidget(row, column);
w.getElement().getStyle().setOpacity(0.5);
}
private void drag(MouseMoveEvent event)
{
if (draggedrow != row || draggedcolumn != column)
{
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderColor();
this.getCellFormatter().getElement(draggedrow, draggedcolumn).getStyle().clearBorderWidth();
this.draggedrow = row;
this.draggedcolumn = column;
this.getCellFormatter().getElement(row, column).getStyle().setBorderStyle(BorderStyle.DASHED);
this.getCellFormatter().getElement(row, column).getStyle().setBorderColor("black");
this.getCellFormatter().getElement(row, column).getStyle().setBorderWidth(2, Unit.PX);
}
}
private void end(MouseUpEvent event)
{
insertDraggedWidget(row, column);
}
private void insertDraggedWidget(int r,int c)
{
this.getCellFormatter().getElement(r, c).getStyle().clearBorderStyle();
this.getCellFormatter().getElement(r, c).getStyle().clearBorderColor();
this.getCellFormatter().getElement(r, c).getStyle().clearBorderWidth();
w.getElement().getStyle().setOpacity(1);
if (this.getWidget(r, c) != null)
{
//pushing down the widgets already in the column
// int widgetheight = (this.getWidget(r, c).getOffsetHeight() / 2) + this.getWidget(r, c).getAbsoluteTop();
// int rw;
//placing the widget above the dropped widget
for (int i = this.getRowCount() - 1; i >= r; i--)
{
if (this.isCellPresent(i, c))
{
this.setWidget(i + 1, c, this.getWidget(i, c));
}
}
}
this.setWidget(r, c, w);
//removes unneccesary blank rows
cleanupRows();
//pushing up the column in the stack
// for (int i = oldrow;i<this.getRowCount()-1 ;i++)
// {
//
// this.setWidget(i ,oldcolumn, this.getWidget(i+1, oldcolumn));
//
// }
}
private void cleanupRows()
{
ArrayList<Integer> rowsfilled = new ArrayList<Integer>();
for (int i = 0; i <= this.getRowCount() - 1; i++)
{
for (int j = 0; j <= this.getCellCount(i) - 1; j++)
{
if (this.getWidget(i, j) != null)
{
rowsfilled.add(i);
break;
}
}
}
//replace the empty rows
for (int i = 0; i < rowsfilled.size(); i++)
{
int currentFilledRow = rowsfilled.get(i);
if (i != currentFilledRow)
{
for (int j = 0; j < this.getCellCount(currentFilledRow); j++)
{
this.setWidget(i, j, this.getWidget(currentFilledRow, j));
}
}
}
for (int i = rowsfilled.size(); i < this.getRowCount(); i++)
{
this.removeRow(i);
}
}
public HandlerRegistration addMouseUpHandler(MouseUpHandler handler)
{
return addDomHandler(handler, MouseUpEvent.getType());
}
public HandlerRegistration addMouseDownHandler(MouseDownHandler handler)
{
return addDomHandler(handler, MouseDownEvent.getType());
}
public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler)
{
return addDomHandler(handler, MouseMoveEvent.getType());
}
public HandlerRegistration addMouseOutHandler(MouseOutHandler handler)
{
return addDomHandler(handler, MouseOutEvent.getType());
}
}
and the on module load for the above custom widget is
public void onModuleLoad()
{
Label a = new Label("asad");
Label b = new Label("ad");
Label c = new Label("qwad");
Label w = new Label("zxd");
a.setPixelSize(200, 200);
a.getElement().getStyle().setBorderStyle(BorderStyle.SOLID);
a.getElement().getStyle().setBorderWidth(1, Unit.PX);
b.setPixelSize(200, 200);
c.setPixelSize(200, 200);
w.setPixelSize(200, 200);
a.getElement().getStyle().setBackgroundColor("red");
b.getElement().getStyle().setBackgroundColor("yellowgreen");
c.getElement().getStyle().setBackgroundColor("lightblue");
w.getElement().getStyle().setBackgroundColor("grey");
DragFlexTable d = new DragFlexTable();
d.setWidget(0, 0, a);
d.setWidget(0, 1, b);
d.setWidget(1, 0, c);
d.setWidget(1, 1, w);
d.setCellPadding(20);
RootPanel.get().add(d);
}
I am trying to implement a method named mostFrequent in a bag that finds the most frequent object in a bag For example, if B = {Bob, Joe, Bob, Ned, Bob, Bob}, then the method
returns Bob. Hint: The method is O(n^2).
public E MostFrequent (Bag<E> B){
// implementation here
}
The adt of the bag is the following:
package edu.uprm.ece.icom4035.bag;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class StaticBag implements Bag {
private int currentSize;
private Object elements[];
private class BagIterator implements Iterator {
private int currentPosition;
public BagIterator(){
this.currentPosition = 0;
}
#Override
public boolean hasNext() {
return this.currentPosition < currentSize;
}
#Override
public Object next() {
if (hasNext()){
return elements[this.currentPosition++];
}
else {
throw new NoSuchElementException();
}
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
public StaticBag(int maxSize){
if (maxSize < 1){
throw new IllegalArgumentException("Max size must be at least 1.");
}
this.currentSize = 0;
this.elements = new Object[maxSize];
}
#Override
public void add(Object obj) {
if (obj == null){
throw new IllegalArgumentException("Value cannot be null.");
}
else if (this.size() == this.elements.length){
throw new IllegalStateException("Bag is full.");
}
else {
this.elements[this.currentSize++] = obj;
}
}
#Override
public boolean erase(Object obj) {
int target = -1;
for (int i=0; i < this.size(); ++i){
if (this.elements[i].equals(obj)){
target = i;
break;
}
}
if (target == -1){
return false;
}
else {
this.elements[target] = this.elements[this.currentSize-1];
this.elements[this.currentSize-1] = null;
this.currentSize--;
return true;
}
}
#Override
public int eraseAll(Object obj) {
int copies = 0;
while(this.erase(obj)){
copies++;
}
return copies;
}
#Override
public int count(Object obj) {
int counter = 0;
for (int i=0; i < this.size(); ++i){
if (elements[i].equals(obj)){
counter++;
}
}
return counter;
}
#Override
public void clear() {
for (int i=0; i < this.size(); ++i){
this.elements[i] = null;
}
this.currentSize = 0;
}
#Override
public boolean isEmpty() {
return this.size() == 0;
}
#Override
public int size() {
return this.currentSize;
}
#Override
public boolean isMember(Object obj) {
return this.count(obj) > 0;
}
#Override
public Iterator iterator() {
return new BagIterator();
}
}
the method must be implemented in the most efficient way and if possible using the methods already given in the bag adt
What I've been trying is the following:
public E MostFrequent(Bag<E> B){
for(E e : B){
int counter = B.count(e)
}
}
but I don't seem to think of a way to return the object with more frequencies inside the loop