I\'m using a second JTable in the Viewport of a JScrollPane to build a RowHeader for a main table. DragAndDrop on the main table is disabled. On the rowheader table DnD is enabl
Alright. Confession time. This is some gnarly, blunt-instrument code right here. I apologize for not being able to produce a more elegant or clean solution. I am a level 1 tourist in the deep dark dungeons of swing.
This custom code falls into the quick-and-dirty category. It will not work with columns, I'm not sure about all the edge cases, and I don't know the rules about stealing another components graphical context in the middle of the draw routine. Bottom line: this is an example, not a full solution.
Because you are using a separate table for dragging and dropping (your rowTable), there is no nice way for that table to draw to the mainTable. It should be noted that there may be a slick and shiny path using PropertyChangeListeners or something to fire an event to the mainTable, but I didn't manage it. Here is a custom extension of the BasicTableUI:
public class ExtendedDropLineTableUI extends BasicTableUI {
private JTable drawTable;
private Integer oldRow;
//We give this UI instance a reference to a separate table for drawing
public ExtendedDropLineTableUI(JTable drawTable) {
this.drawTable = drawTable;
}
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
paintExtendedDropLine();
}
private void paintExtendedDropLine() {
JTable.DropLocation loc = table.getDropLocation();
if (loc == null) {
drawTable.repaint();
return;
}
//get the correct line color. no color? no line!
Color color = UIManager.getColor("Table.dropLineColor");
if (color == null) {
return;
}
//try to repaint the draw table only if the row changes
if (oldRow != null && oldRow != loc.getRow()) {
drawTable.repaint();
}
oldRow = loc.getRow();
//get location of cell rectangle
int row = loc.getRow();
int col = loc.getColumn();
if (col >= table.getColumnCount()) {
col--;
}
Rectangle rect = table.getCellRect(row, col, true);
//adjust rectangle to fit between the cells
if (rect.y == 0) {
rect.y = -1;
} else {
rect.y -= 2;
}
//what's a line but a really thin rectangle?
rect.height = 3;
//extend the rectangle to the width of the drawing table
rect.width = drawTable.getWidth();
//draw the rectangle
Graphics g = drawTable.getGraphics();
g.setColor(color);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
}
}
You will need to give this UI to your rowTable so it can draw to the mainTable, like this:
rowTable.setUI(new ExtendedDropLineTableUI(mainTable));
I leaned heavily on actual source code to hijack the drawing of the drop lines, because the methods concerning that stuff are all private.
EDIT: I forgot to mention as an aside that I'm worried you may be trying to re-arrange the entire row in the mainTable by dragging the cell in the rowTable. This solution does not account for that either, it just draws the line. For that you really will need a more elegant solution, or a check which keeps the rows in the mainTable ordered in sync with the rowTable.