我们有一个在Windows和OSX上都使用的大型Java应用程序。 我们在两个JTable之间进行自定义拖放。
在Windows上,这非常有效。在目标JTable上拖动时会显示自定义光标。
在Mac上,永远不会显示自定义光标。而是在开始拖动时显示灰色矩形(仅限边框)。此矩形是表列的宽度和表的高度。我们的日志记录显示正在调用dragOver()和dropActionChanged()方法,我们正在设置自定义光标。它永远不会被显示出来。
如果我禁用自定义光标代码,则会显示相同的框 - 但它的中间也有圆圈/斜线图标。
我想摆脱怪异的盒子,并显示自定义光标。
摘自代码:
private class FileTransferHandler extends TransferHandler {
private static final long serialVersionUID = 1L;
private final Logger log = LogManager.getLogger();
private final CursorDragSourceListener dragSourceListener = new CursorDragSourceListener();
// Left out the Drop handling code that was here
@Override
public int getSourceActions( final JComponent c) {
log.debug("FileTransferHandler.getSourceAction: ");
return COPY | MOVE;
}
@Override
protected Transferable createTransferable( final JComponent c) {
log.debug("FileTransferHandler.createTransferable:");
List<iFilePage> pages = new ArrayList<iFilePage>();
// Left out the code that builds the pages list
DragSource.getDefaultDragSource().addDragSourceListener(dragSourceListener);
dragSourceListener.setCursorChoice(pages.size() == 1);
return new FilePageTransferable(pages);
}
@Override
protected void exportDone( final JComponent c,
final Transferable t,
final int action) {
log.debug("FileTransferHandler.exportDone: {}", action, t);
tblFixed.getSelectionModel().clearSelection();
DragSource.getDefaultDragSource().removeDragSourceListener(dragSourceListener);
return;
}
}
private static class CursorDragSourceListener implements DragSourceListener {
private Cursor singlePage = null;
private Cursor multiPage = null;
private Cursor badSinglePage = null;
private Cursor useCursor = null;
private boolean useSingle = false;
public CursorDragSourceListener() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
URL url;
String name;
Image img;
url = FileUtils.getResourceURL("/images/page.png");
name = "DragPage";
img = toolkit.createImage(url);
singlePage = toolkit.createCustomCursor(img, new Point(16, 16), name);
url = FileUtils.getResourceURL("/images/badpage_stack.png");
name = "DragBadPage";
img = toolkit.createImage(url);
badSinglePage = toolkit.createCustomCursor(img, new Point(16, 16), name);
url = FileUtils.getResourceURL("/images/page_stack.png");
name = "DragPageStack";
img = toolkit.createImage(url);
multiPage = toolkit.createCustomCursor(img, new Point(16, 16), name);
return;
}
public void setCursorChoice( final boolean single) {
log.debug("CursorDragSourceListener.setCursorChoice: {}", single);
useSingle = single;
if (useSingle) {
useCursor = singlePage;
} else {
useCursor = multiPage;
}
return;
}
@Override
public void dropActionChanged( final DragSourceDragEvent dsde) {
log.debug("CursorDragSourceListener.dropActionChanged: {}", dsde.getDropAction(), useSingle);
if (dsde.getDropAction() == 2) {
if (!useSingle) {
useCursor = badSinglePage;
} else {
useCursor = singlePage;
}
} else {
if (useSingle) {
useCursor = singlePage;
} else {
useCursor = multiPage;
}
}
dsde.getDragSourceContext().setCursor(useCursor);
return;
}
@Override
public void dragOver( final DragSourceDragEvent dsde) {
try {
Object x = dsde.getDragSourceContext().getTransferable()
.getTransferData(DataFlavor.javaFileListFlavor);
log.trace("CursorDragSourceListener.dragOver: {}", (x != null) ? x.getClass().getSimpleName() : "null");
if (x instanceof ArrayList) {
dsde.getDragSourceContext().setCursor(useCursor);
}
} catch (Exception e) {
log.error("CursorDragSourceListener.dragOver:", e);
}
}
@Override
public void dragExit( final DragSourceEvent dse) {
}
@Override
public void dragEnter( final DragSourceDragEvent dsde) {
}
@Override
public void dragDropEnd( final DragSourceDropEvent dsde) {
}
}
答案 0 :(得分:0)
经过多次检查和分析后,我们的自定义选择模型在OSX上引发了这个问题。 我们有一个选择模型,允许您选择多个单独的单元格,而不仅仅是整行。 因此getMinSelectionindex()和getMaxSelectionIndex()方法返回虚拟数据,因为我们从未使用它们。
在MS Win上运行正常,但显然JTable的OSX拖放使用了这些调用。
修改我们的代码以返回合理的值后,选择框不再像表那样高。
自定义光标大多数时间都会出现,但仍无条件地随机消失。