File handling
File system
Swing applications running inside Webswing are ultimately using the file system of the server where Webswing is running. This causes problems to applications that consume or generate files and interact with file system.
Webswing solves this problem by providing an automatic JFileChooser
integration dialog, which offers users ability to interact with server's file system by uploading, downloading and deleting files from the browser.
Permissions
It is possible to disable upload, download or delete files in the application configuration.
Isolated file system
If the users are not supposed to have access to the full servers file system, Webswing offers the option to limit the access to isolated folder that they are allowed to interact with. This isolatedFs
setting can be set in application configuration. If it is enabled, the user will only see folder "upload"
in homeDir
folder.
File types restrictions
Due to security reasons it is sometimes necessary to restrict specific file types when uploading.
Following customization in index.html
shows how to handle file extensions:
injector.services.files.manager.getAcceptFilter = function(fileChooserName, filter) {
if (fileChooserName === 'uploadFC') {
return "image/png";
}
return filter;
};
injector.services.files.manager.validateUploadedFile = function(file) {
if (file.name.endsWith(".png") || file.type === 'image/png') {
return { valid: true };
}
return { valid: false, error: "Cannot upload file - " + file.name };
};
Drag & Drop
Webswing supports drag & drop functionality between swing components, drag & drop upload to file chooser and direct drag & drop of file from local system to swing component.
File chooser upload
To upload a file using drag & drop to a file chooser, simply open file chooser and drop a file from local file system to the marked area. Note that transparentFileSave
config should be false
.
Direct drag & drop
To use direct drag & drop you first need to register a swing component that should receive the uploaded file. Use WebswingApi
method to do this:
if (WebswingUtil.isWebswing()) {
WebswingApi api = WebswingUtil.getWebswingApi();
api.registerDropComponent(pic1);
}
The same way you can unregister an already registered component:
if (WebswingUtil.isWebswing()) {
WebswingApi api = WebswingUtil.getWebswingApi();
api.unregisterDropComponent(pic1);
}
The registered component must have a valid TransferHandler
:
pic1.setTransferHandler(picHandler);
This is an example of a simple TransferHandler
:
class PictureTransferHandler extends TransferHandler {
private static List<DataFlavor> supportedFlavors = Arrays.asList(DataFlavor.javaFileListFlavor);
public boolean importData(JComponent c, Transferable t) {
if (canImport(c, t.getTransferDataFlavors())) {
if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
try {
List<File> fileList = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
if (fileList != null && !fileList.isEmpty()) {
File droppedFile = fileList.get(0);
return true;
}
} catch (IOException | UnsupportedFlavorException e) {
// log
}
}
}
return false;
}
public boolean canImport(JComponent c, DataFlavor[] flavors) {
for (int i = 0; i < flavors.length; i++) {
if (supportedFlavors.contains(flavors[i])) {
return true;
}
}
return false;
}
}
File viewers
In webswing config you can configure a mapping of file extension to URL handler for specific AWT Desktop file operation.
In the configuration above, files with txt
extension are handled with /txt-viewer
URL handler when Desktop.getDesktop().open()
, Desktop.getDesktop().edit()
or Desktop.getDesktop().print()
is called for the file. If you want to use the browser's default action use ${file}
as URL value.
You can implement a URL handler by creating a folder with index.html inside application web folder:
This is an example code for a simple file viewer:
<!DOCTYPE html>
<html>
<head>
<title>Demo text file viewer</title>
<meta charset="utf-8">
<script language="javascript" type="text/javascript">
const searchParams = new URLSearchParams(window.location.search);
const blobId = searchParams.get('file');
console.log("blobId", blobId)
document.addEventListener("DOMContentLoaded", function(event) {
var fileContent = document.getElementById('filecontent');
fileContent.value = 'Loading file content ...';
fetch(blobId)
.then(response => response.blob())
.then(blob => {
const reader = new FileReader();
reader.readAsText(blob);
reader.onloadend = function() {
fileContent.value = reader.result;
};
})
.catch(error => {
fileContent.value = "Blob error " + error
console.error('blob error', error)
});
});
</script>
</head>
<body>
<h1>Text file viewer</h1>
<textarea id="filecontent" rows="20" cols="110" style="white-space: pre" readonly></textarea>
</body>
</html>
File chooser provider interface
If you do not integrate a JFileChooser in your application and you have a custom solution for accessing file system, you can integrate Webswing with your solution using WebswingFileChooserProvider
interface.
This interface allows you to provide all necessary methods that Webswing uses for file integration.
You can see an example implementation of the interface in our Webswing Demo app: