forked from fanruan/design
Henry.Wang
3 years ago
4 changed files with 331 additions and 105 deletions
@ -0,0 +1,24 @@ |
|||||||
|
package com.fr.design.base.clipboard; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class ClipboardHelper { |
||||||
|
public static String formatExcelString(List<List<Object>> table) { |
||||||
|
StringBuffer stringBuffer = new StringBuffer(); |
||||||
|
|
||||||
|
for (int row = 0; row < table.size(); row++) { |
||||||
|
List<Object> rowValue = table.get(row); |
||||||
|
for (int col = 0; col < rowValue.size(); col++) { |
||||||
|
Object cell = rowValue.get(col); |
||||||
|
stringBuffer.append(cell); |
||||||
|
if (col != rowValue.size() - 1) { |
||||||
|
stringBuffer.append("\t"); |
||||||
|
} |
||||||
|
} |
||||||
|
if (row != table.size() - 1) { |
||||||
|
stringBuffer.append("\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
return stringBuffer.toString(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,203 @@ |
|||||||
|
package com.fr.design.data.datapane.preview; |
||||||
|
|
||||||
|
import com.fr.design.base.clipboard.ClipboardHelper; |
||||||
|
import com.fr.design.gui.itable.SortableJTable; |
||||||
|
import com.fr.design.gui.itable.TableSorter; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.os.OperatingSystem; |
||||||
|
|
||||||
|
import javax.swing.table.TableCellRenderer; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.datatransfer.Clipboard; |
||||||
|
import java.awt.datatransfer.StringSelection; |
||||||
|
import java.awt.datatransfer.Transferable; |
||||||
|
import java.awt.event.KeyAdapter; |
||||||
|
import java.awt.event.KeyEvent; |
||||||
|
import java.awt.event.MouseAdapter; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Comparator; |
||||||
|
|
||||||
|
public class CopyableJTable extends SortableJTable { |
||||||
|
|
||||||
|
//区域选中用到的定位数据
|
||||||
|
public int startRow = -1; |
||||||
|
public int startCol = -1; |
||||||
|
public int endRow = -1; |
||||||
|
public int endCol = -1; |
||||||
|
//单元格不连续多选用到的定位数据
|
||||||
|
java.util.List<Point> pointList = new ArrayList<>(); |
||||||
|
//shift键是否被按下
|
||||||
|
public boolean isShiftDown = false; |
||||||
|
//control\command键是否被按下
|
||||||
|
public boolean isControlDown = false; |
||||||
|
//是否可以复制
|
||||||
|
public boolean isCopy = true; |
||||||
|
int ctrlKeyCode = 17; |
||||||
|
int cKeyCode = 67; |
||||||
|
int shiftKeyCode = 16; |
||||||
|
int commandKeyCode = 157; |
||||||
|
//选中单元格的背景色
|
||||||
|
Color selectBackGround = new Color(54, 133, 242, 63); |
||||||
|
|
||||||
|
|
||||||
|
public CopyableJTable(TableSorter tableModel) { |
||||||
|
super(tableModel); |
||||||
|
initListener(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initListener() { |
||||||
|
CopyableJTable self = this; |
||||||
|
this.addMouseMotionListener(new java.awt.event.MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseDragged(MouseEvent evt) { |
||||||
|
int row = self.rowAtPoint(evt.getPoint()); |
||||||
|
int col = self.columnAtPoint(evt.getPoint()); |
||||||
|
if (self.updateEndPoint(row, col)) { |
||||||
|
self.repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
this.addMouseListener(new MouseAdapter() { |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
int row = self.rowAtPoint(e.getPoint()); |
||||||
|
int col = self.columnAtPoint(e.getPoint()); |
||||||
|
if (!self.isControlDown) { |
||||||
|
self.clearPoint(); |
||||||
|
} |
||||||
|
if (self.isShiftDown) { |
||||||
|
self.clearPoint(); |
||||||
|
} else { |
||||||
|
self.updateStartPoint(row, col); |
||||||
|
} |
||||||
|
self.addPoint(row, col); |
||||||
|
self.updateEndPoint(row, col); |
||||||
|
|
||||||
|
self.repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
}); |
||||||
|
this.addKeyListener(new KeyAdapter() { |
||||||
|
@Override |
||||||
|
public void keyPressed(KeyEvent e) { |
||||||
|
if (isControlKey(e)) { |
||||||
|
isControlDown = true; |
||||||
|
} else if (e.getKeyCode() == shiftKeyCode) { |
||||||
|
isShiftDown = true; |
||||||
|
} else if (e.getKeyCode() == cKeyCode) { |
||||||
|
if (isControlDown && isCopy) { |
||||||
|
self.copy(); |
||||||
|
isCopy = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void keyReleased(KeyEvent e) { |
||||||
|
if (isControlKey(e)) { |
||||||
|
isControlDown = false; |
||||||
|
isCopy = true; |
||||||
|
} else if (e.getKeyCode() == shiftKeyCode) { |
||||||
|
isShiftDown = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isControlKey(KeyEvent e) { |
||||||
|
if (e.getKeyCode() == ctrlKeyCode) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (e.getKeyCode() == commandKeyCode && OperatingSystem.isMacos()) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { |
||||||
|
Component comp = super.prepareRenderer(renderer, row, column); |
||||||
|
if (isChoose(row, column)) { |
||||||
|
comp.setBackground(selectBackGround); |
||||||
|
} else { |
||||||
|
comp.setBackground(this.getBackground()); |
||||||
|
} |
||||||
|
return comp; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private boolean updateEndPoint(int row, int col) { |
||||||
|
if (endRow != row || endCol != col) { |
||||||
|
endRow = row; |
||||||
|
endCol = col; |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean updateStartPoint(int row, int col) { |
||||||
|
if (startRow != row || startCol != col) { |
||||||
|
startRow = row; |
||||||
|
startCol = col; |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private void addPoint(int row, int col) { |
||||||
|
pointList.add(new Point(row, col)); |
||||||
|
} |
||||||
|
|
||||||
|
private void clearPoint() { |
||||||
|
pointList = new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
private void copy() { |
||||||
|
FineLoggerFactory.getLogger().info("copy cell value"); |
||||||
|
java.util.List<java.util.List<Object>> table = new ArrayList<>(); |
||||||
|
if ((startRow != endRow || startCol != endCol) && |
||||||
|
Math.min(startRow, endRow) > -1 && Math.min(startCol, endCol) > -1) { |
||||||
|
for (int i = Math.min(startRow, endRow); i <= Math.max(startRow, endRow); i++) { |
||||||
|
table.add(new ArrayList<>()); |
||||||
|
for (int j = Math.min(startCol, endCol); j <= Math.max(startCol, endCol); j++) { |
||||||
|
Object text = this.getValueAt(i, j); |
||||||
|
table.get(i - Math.min(startRow, endRow)).add(text); |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (pointList.size() > 0) { |
||||||
|
Collections.sort(pointList, Comparator.comparing(Point::getX).thenComparing(Point::getY)); |
||||||
|
int startRow = pointList.get(0).x; |
||||||
|
int currentRow = startRow; |
||||||
|
table.add(new ArrayList<>()); |
||||||
|
for (Point point : pointList) { |
||||||
|
while (currentRow < point.x) { |
||||||
|
table.add(new ArrayList<>()); |
||||||
|
currentRow++; |
||||||
|
} |
||||||
|
Object text = this.getValueAt(point.x, point.y); |
||||||
|
table.get(currentRow - startRow).add(text); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); |
||||||
|
Transferable tText = new StringSelection(ClipboardHelper.formatExcelString(table)); |
||||||
|
clip.setContents(tText, null); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isChoose(int row, int col) { |
||||||
|
if (row >= Math.min(startRow, endRow) && row <= Math.max(startRow, endRow)) { |
||||||
|
if (col >= Math.min(startCol, endCol) && col <= Math.max(startCol, endCol)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
for (Point point : pointList) { |
||||||
|
if (point.x == row && point.y == col) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue