我在一个由2列组成的JTable中显示了一些结果。
档案 - 结果
我实现了一个显示副本条目的JPopupMenu,我尝试复制单元格的值,我右键单击。
filelistTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(SwingUtilities.isRightMouseButton(e))
{
TablePopupMenu popup = new TablePopupMenu(filelistTable, e.getPoint());
filelistTable.setComponentPopupMenu(popup);
}
}
});
-
public TablePopupMenu(JTable table, Point p) {
this.table = table;
this.p = p;
JMenuItem mntmKopieren = new JMenuItem("Kopieren");
mntmKopieren.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
copyCellToClipboard();
}
});
add(mntmKopieren);
}
public void copyCellToClipboard()
{
int r = table.rowAtPoint(p);
int c = table.columnAtPoint(p);
System.out.println(table.getValueAt(table.convertRowIndexToView(r),
table.convertRowIndexToView(c)));
StringSelection entry = new StringSelection(table.getValueAt(table.convertRowIndexToView(r),
table.convertRowIndexToView(c)).toString());
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents( entry, this );
}
无论如何,这仅适用于少量测试。 我做错了什么或丢失了什么?在我看来,好像细胞甚至无法正确选择。
答案 0 :(得分:5)
两件事略显偏离:
这就是说:获得与细胞坐标相关的上下文支持不足。通常,最好的选择是(下面的代码片段)
如果(在一个表现良好的应用程序中应该这样做),弹出窗口可以由键盘触发失败:如果是这种情况,你需要提供一些其他标记(在焦点单元格上)来进行操作。
final String popupLocation = "table.popupLocation";
final JTable table = new JXTable(new AncientSwingTeam()) {
@Override
public Point getPopupLocation(MouseEvent event) {
// event may be null if triggered by keyboard, f.i.
// thanks to @Mad for the heads up!
((JComponent) event.getComponent()).putClientProperty(
popupLocation, event != null ? event.getPoint() : null);
return super.getPopupLocation(event);
}
};
JPopupMenu popup = new JPopupMenu();
Action printLocation = new AbstractAction("print cell") {
@Override
public void actionPerformed(ActionEvent e) {
Point p = (Point) table.getClientProperty(popupLocation);
if (p != null) { // popup triggered by mouse
int row = table.rowAtPoint(p);
int column = table.columnAtPoint(p);
LOG.info("" + table.getValueAt(row, column));
} else { // popup triggered otherwise
// could choose f.i. by leadRow/ColumnSelection
...
}
}
};
popup.add(printLocation);
table.setComponentPopupMenu(popup);
编辑(由Mad的评论引发):
您应该检查MouseEvent.isPopupTrigger,因为触发点取决于平台。这意味着你需要监控mousePressed,mouseReleased和mouseClicked
不,这不是必需的(只是检查:-):显示componentPopup以响应mouseEvent的机制 - 发生在BasicLookAndFeel.AWTEventHelper中 - 只有当 是popupTrigger时才会这样做。 / p>
通过阅读api doc(应该在昨天;-)再次进行,事实证明该方法在显示componentPopup之前被称为始终,即使用其他方式f.i触发也是如此。键盘。在这种情况下,事件参数为空 - 原始代码会被破坏。从好的方面来说,通过这种保证,找到目标细胞的所有逻辑都可以转移到该方法中。没试过,所以它可能不可行(如果那时位置应该基于当时可能尚未完全处理的leadRow / ColumnSelection)