当您单击加密时,应用程序会加密放入表中的每个文件,我想显示文件加密的进度。然后,“状态”列将从“未处理”更改为“已处理”。
类似于您在电子邮件中查看多个文件附件的方式。我一直在研究单元格渲染器和 ProgressBarTablecell,但不确定如何实现它们。任何帮助表示赞赏。我正在张贴表格。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class DropTable {
public static void main(String[] args) {
new DropTable();
}
public DropTable() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());//get look and feel of whatever OS we're using
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException
| UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DropPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DropPane extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTable table;
private JScrollPane scroll;
private DefaultTableModel tm = new DefaultTableModel(new String[] {
"File", "File Type", "Size", "Status" }, 0);
public DropPane() {
table = new JTable();
table.setShowGrid(true);
table.setShowHorizontalLines(true);
table.setShowVerticalLines(true);
table.setGridColor(Color.GRAY);
table.setModel(tm);
table.setFillsViewportHeight(true);
table.setPreferredSize(new Dimension(500, 300));
scroll = new JScrollPane(table);
table.setDropTarget(new DropTarget() {
@Override
public synchronized void dragOver(DropTargetDragEvent dtde) {
Point point = dtde.getLocation();
int row = table.rowAtPoint(point);
if (row < 0) {
table.clearSelection();
} else {
table.setRowSelectionInterval(row, row);
}
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
}
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
{//make sure the flavors are files
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);//dndconstants tells what to do with the drag files
//change to ACTION_COPY so it removes the file from the directory
Transferable t = dtde.getTransferable();
List fileList = null;
try {
fileList = (List) t.getTransferData(DataFlavor.javaFileListFlavor);//get file
if (fileList.size() > 0) {
table.clearSelection();
Point point = dtde.getLocation();//point is (x,y)
int row = table.rowAtPoint(point);
DefaultTableModel model = (DefaultTableModel) table.getModel();
for (Object value : fileList) {
if (value instanceof File) {
File f = (File) value;
if (row < 0) {//insert rows into the right columns
model.addRow(new Object[]{f.getAbsolutePath(), "", f.length(), "", ""});//path under "File"
} else {
model.insertRow(row, new Object[]{f.getAbsolutePath(), "", f.length(), "", ""});//get size of file
row++;
}
}
}
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
dtde.rejectDrop();
}
}
});
add(scroll, BorderLayout.CENTER);
}
}
}
最佳答案
这是一个基本示例,它主要使用 SwingWorker 扫描驱动器的根目录并列出所有文件。一旦完成,它将尝试读取每个文件,在它自己的 SwingWorker 中更新表。
免责声明:这是一个例子。我使用 Thread.sleep 稍微减慢读取速度,忽略缓冲区和其他一些我会在生产代码中以不同方式做的事情,但我想突出显示进度更新。
工作原理
首先,您需要一个能够显示进度更新的单元格渲染器。我选择了一个简单的自定义 JProgressBar,但您可能会喜欢一些更复杂的东西。
您需要一些方法来更新表模型。我选择提供一个简单的 updateStatus 方法,传递我正在更新的文件,这允许我使用内部查找来查找有问题的行。然后我使用 setValueAt 方法更新行对象。这并不是真正需要的,但我想演示 setValueAt 方法的使用,您可以直接从 updateStatus 方法更新行对象。
最后,将模型的更改通知表格,以便它重新绘制自己。
public class UpdateTable {
public static void main(String[] args) {
new UpdateTable();
}
public UpdateTable() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
UpdatableTableModel model = new UpdatableTableModel();
JTable table = new JTable();
table.setModel(model);
table.getColumn("Status").setCellRenderer(new ProgressCellRender());
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
FileFinderWorker worker = new FileFinderWorker(model);
worker.execute();
}
});
}
public class ProgressCellRender extends JProgressBar implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
int progress = 0;
if (value instanceof Float) {
progress = Math.round(((Float) value) * 100f);
} else if (value instanceof Integer) {
progress = (int) value;
}
setValue(progress);
return this;
}
}
public class RowData {
private File file;
private String type;
private long length;
private float status;
public RowData(File file, String type) {
this.file = file;
this.type = type;
this.length = file.length();
this.status = 0f;
}
public File getFile() {
return file;
}
public long getLength() {
return length;
}
public float getStatus() {
return status;
}
public String getType() {
return type;
}
public void setStatus(float status) {
this.status = status;
}
}
public class UpdatableTableModel extends AbstractTableModel {
private List<RowData> rows;
private Map<File, RowData> mapLookup;
public UpdatableTableModel() {
rows = new ArrayList<>(25);
mapLookup = new HashMap<>(25);
}
@Override
public int getRowCount() {
return rows.size();
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public String getColumnName(int column) {
String name = "??";
switch (column) {
case 0:
name = "File";
break;
case 1:
name = "File Type";
break;
case 2:
name = "Size";
break;
case 3:
name = "Status";
break;
}
return name;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
RowData rowData = rows.get(rowIndex);
Object value = null;
switch (columnIndex) {
case 0:
value = rowData.getFile();
break;
case 1:
value = rowData.getType();
break;
case 2:
value = rowData.getLength();
break;
case 3:
value = rowData.getStatus();
break;
}
return value;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
RowData rowData = rows.get(rowIndex);
switch (columnIndex) {
case 3:
if (aValue instanceof Float) {
rowData.setStatus((float) aValue);
}
break;
}
}
public void addFile(File file) {
RowData rowData = new RowData(file, "A File");
mapLookup.put(file, rowData);
rows.add(rowData);
fireTableRowsInserted(rows.size() - 1, rows.size() - 1);
}
protected void updateStatus(File file, int progress) {
RowData rowData = mapLookup.get(file);
if (rowData != null) {
int row = rows.indexOf(rowData);
float p = (float) progress / 100f;
setValueAt(p, row, 3);
fireTableCellUpdated(row, 3);
}
}
}
public class FileFinderWorker extends SwingWorker<List<File>, File> {
private UpdatableTableModel model;
public FileFinderWorker(UpdatableTableModel model) {
this.model = model;
}
@Override
protected void process(List<File> chunks) {
for (File file : chunks) {
model.addFile(file);
}
}
@Override
protected List<File> doInBackground() throws Exception {
File files[] = new File(System.getProperty("user.dir")).listFiles();
List<File> lstFiles = new ArrayList<>(Arrays.asList(files));
for (File file : lstFiles) {
// You could actually publish the entire array, but I'm doing this
// deliberatly ;)
publish(file);
}
return lstFiles;
}
@Override
protected void done() {
try {
List<File> files = get();
for (File file : files) {
new FileReaderWorker(model, file).execute();
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
public class FileReaderWorker extends SwingWorker<File, File> {
private File currentFile;
private UpdatableTableModel model;
public FileReaderWorker(UpdatableTableModel model, File file) {
this.currentFile = file;
this.model = model;
addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("progress")) {
FileReaderWorker.this.model.updateStatus(currentFile, (int) evt.getNewValue());
}
}
});
}
@Override
protected File doInBackground() throws Exception {
if (currentFile.isFile()) {
setProgress(0);
long fileLength = currentFile.length();
BufferedReader reader = null;
char[] cbuf = new char[1024];
try {
reader = new BufferedReader(new FileReader(currentFile));
int bytesRead = -1;
int totalBytesRead = 0;
while ((bytesRead = reader.read(cbuf)) != -1) {
totalBytesRead += bytesRead;
int progress = (int) Math.round(((double) totalBytesRead / (double) fileLength) * 100d);
setProgress(progress);
Thread.sleep(25);
}
setProgress(100);
} catch (Exception e) {
e.printStackTrace();
setProgress(100);
} finally {
try {
reader.close();
} catch (Exception e) {
}
}
} else {
setProgress(100);
}
return currentFile;
}
}
}
重要概念。
永远不要用任何类型的长时间运行的操作来阻塞事件调度线程。相反,将这些耗时的操作移到后台线程中。在这里,我使用了 SwingWorker
通读Concurrency in Swing了解更多信息
关于java - 为文件进度的每个表格单元格添加进度条 - Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13753562/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信