I implemented an entry in the context menu of my Eclipse RCP application. The function should export the right-clicked file in another format. I already implemented the transformation-function.
What I need, is the path and name of the right-clicked file. This is what I have:
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
Shell shell = new Shell();
DirectoryDialog dialog = new DirectoryDialog(shell);
String saveToPath = dialog.open();
String filePath = // ... how to access the clicked file?
exportOtherFormat(filePath, saveToPath);
return null;
}
So basically I would like to know, how I can access the right-clicked file, specially the path and name.
Get the current selection in your handler and adapt it to an IFile with:
ISelection sel = HandlerUtil.getCurrentSelection(event);
if (sel instanceof IStructuredSelection)
{
Object selObj = ((IStructuredSelection)sel).getFirstObject();
IFile file = (IFile)Platform.getAdapterManager().getAdapter(selObj, IFile.class);
// TODO your code
}
Related
In my vaadin application I have a Table with an additional column containing a print Button. The Button calls the following util method to create a pdf and open it in a new window (ui parameter is the button):
public static void printPDF(Offer offer, AbstractComponent ui) throws IOException, DocumentException, TemplateException {
// ... create PDF
FileResource resource = new FileResource(pdfFile);
BrowserWindowOpener opener = new BrowserWindowOpener(resource);
opener.setFeatures("");
opener.extend(ui);
}
Now clicking the button the first time does not work. Clicking it the second time works. Clicking it the third time, opens two windows. This increases on every further click.
I also want to open the pdf using the context menu e.g.
table.addActionHandler(new Handler()...
There I don't even have a button to extend. I would prefer to, not use the .extend() part and just open a new window. How can I do that?
EDIT: This blocks the button from opening mulitple instances, still not a nice solution and the first click does not work.
Collection<Extension> extensions = ui.getExtensions();
for (Extension e : extensions) {
if (e instanceof BrowserWindowOpener) {
((BrowserWindowOpener) e).setResource(resource);
return;
}
}
I guess I would need to create a BrowserWindowOpener for every print Button in my Table.
Not a very clean solution, the table may contain lots of rows which would create a lot of BrowserWindowOpener instances which will never be used. The context menu problem would not be solved as well.
EDIT2: This is the other solution I tried:
ResourceReference rr = ResourceReference.create(resource, ui, "print");
Page.getCurrent().open(rr.getURL(), "blank_");
Here I get the following error:
Button (175) did not handle connector request for
print/2016_9090_R_1634500091131558445.pdf
You can use the FileDownloader to achieve what you want.
FileResource resource = new FileResource(pdfFile);
FileDownloader downloader = new FileDownloader(resource);
Button pdf= new Button("Download PDF");
downloader.extend(pdf);
Use this code
Window window = new Window();
((VerticalLayout) window.getContent()).setSizeFull();
window.setResizable(true);
window.setCaption("Exemplo PDF");
window.setWidth("800");
window.setHeight("600");
window.center();
StreamSource s = new StreamResource.StreamSource() {
#Override
public InputStream getStream() {
try {
File f = new File("C:/themes/repy.pdf");
FileInputStream fis = new FileInputStream(f);
return fis;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
};
StreamResource r = new StreamResource(s, "repy.pdf", mainLayout.getApplication());
Embedded e = new Embedded();
e.setSizeFull();
e.setType(Embedded.TYPE_BROWSER);
r.setMIMEType("application/pdf");
e.setSource(r);
window.addComponent(e);
getMainWindow().addWindow(window);
I would like to be able to display a list of files showing only the file name not the whole file path.
Currently I have a list of files. When I click one of these files the listener passes this to a method out of scope which loads the file.
This means if I was to just pass it a list of just file names it would no longer work as my listener requires a full file path. I do not have any ideas as to how I would go about both storing a list of filenames whilst simultaneously linking them to the full file path.
Happy to answer any questions you may have. Many thanks,
Note: the small for loop shows how I could potentially extract the filename from the file path, but I am not currently doing anything with it at this time. It's just an example to show you how far I have gotten.
public void GetFilesFromFolder(String dirName) throws IOException {
File dir = new File(dirName);
File[] files = dir.listFiles((File dir1, String filename) -> filename.endsWith(".mp3"));
String[] fileName = new String[files.length];
int x = 0;
for (File file : files) {
String fileTemp = file.toString();
fileTemp = fileTemp.substring(fileTemp.lastIndexOf("\\" + 1));
System.out.println(fileTemp);
fileName[x] = fileTemp;
System.out.println(fileName[x]);
x++;
}
observableList.clear();
observableList.addAll(files);
}
public void SetFileListView() throws IOException {
listView.setItems(null);
}
public VBox listStack() throws IOException {
vbox = new VBox();
vbox.getChildren().add(listView);
listView.setItems(observableList);
listView.setMinHeight(500);
MusicDataModel mdm = MainView.getMainView().musicDataModel;
MusicDataViewController mdv = MainView.getMainView().musicDataViewController;
listView.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends File> observable, File oldValue, File newValue) -> {
try {
mdm.load(newValue.toString());
mdv.SetValues();
} catch (UnsupportedTagException | InvalidDataException | IOException | NotSupportedException ex) {
Logger.getLogger(FileListView.class.getName()).log(Level.SEVERE, null, ex);
}
});
return vbox;
}
Populate the list view with Files, as you currently do, and use a cell factory on the list view to change the way the file is displayed:
listView.setCellFactory(lv -> new ListCell<File>() {
#Override
protected void updateItem(File file, boolean empty) {
super.updateItem(file, empty);
setText(file == null ? null : file.getName());
}
});
This will ensure each cell in the list view displays only the file name (the last component of the file's full path), though it still retains the File instance as its data (so you can still get the selected File, etc).
I have some trouble with the Windows Explorer.
My Application starts the download of a file and puts it into the system clipboard meanwhile. If the User now pastes the file at some place of the Windows Explorer, the file isn't having its real size, but the size depending on the progress of the download.
Does somebody have an idea of how I could advise the Explorer to wait until the download has finished and copy the file to the target directory afterwards?
I also tried to "tunnel" the file over the loopback Interface using the local SMB server but it didnt help unfortunately...
Thanks in advance
Downloading the file and calling the paste to clipboard method:
new Thread(new Runnable() {
#Override
public void run() {
final String where = getText();
int selectedRows[] = CustomJTableModel.table.getSelectedRows();
List<File> fileList = new ArrayList<File>();
for( int i=0; selectedRows.length>i; i++ ) {
// Build the relative file/folder path
String fileName = (String)table.getValueAt(table.getSelectedRow(), 0);
final String value = buildPath(where, fileName);
new Thread(new Runnable() {
#Override
public void run() {
staticNetworkDaemon.getFile(value, where);
}
}).start();
fileList.add(new File("\\\\127.0.0.1\\r$\\downloaded" + value.replace("/", "\\")));
}
setClipboardFile(fileList);
}
}).start();
Copying the file to the clipboard:
public static void setClipboardFile(final List<File> files) {
Transferable trans = new Transferable() {
List<File> fileList = new ArrayList<File>();
public DataFlavor[] getTransferDataFlavors() {
for( File f: files ) {
fileList.add(f);
}
return new DataFlavor[] { DataFlavor.javaFileListFlavor };
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.javaFileListFlavor.equals(flavor);
}
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (isDataFlavorSupported(flavor))
return fileList;
throw new UnsupportedFlavorException(flavor);
}
};
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null);
}
What you're doing is simply wrong. Don't put something in the clipboard unless it's ready to be pasted -- you're breaking the contract that you should be following when using the clipboard.
Maybe my answer is a little bit simplistic, but why not simply wait until the file is completely downloaded before setting it in the clipboard? What about using something like a Future to wait for it, then set it in the clipboard.
This...
fileList.add(new File("\\\\127.0.0.1\\r$\\downloaded" + value.replace("/", "\\")))
Is so wrong as to be mind boggling. You only want to add the where to the fileList but only AFTER it has been successfully downloaded.
Once the file has been downloaded, only then do you want to add it to the clipboard.
The creation of your Transferable is also a "little" troubling, the Transferable should make a copy of the File List the moment it is created, this prevents the List from been modified before it is used, which could change the results
In languages like C++ or Delphi it is possible to put to clipboard IDataObject object. IDataObject object can contain absolutely different formats. If your can paste IDataObject with CFSTR_FILEDESCRIPTOR and CFSTR_FILECONTENTS formats to clipboard your problem will be solved.
When shell requests files from clipboard it checks for CF_HDROP, CF_IDLIST, CF_FILEDESCRIPTORW/CF_FILEDESCRIPTORA or CF_FILENAMEW/CF_FILENAMEA formats. And if clipboard contains CF_FILEDESCRIPTOR format only shell will use this format for file transfer.
CF_FILEDESCRIPTOR format contains names, attributes and dates of files. CF_FILECONTENTS format contains IStream of file. And you are absolutely free to create any implementation of IStream object. When shell call IStream.Read and request the part of file which is already downloaded just return this part of file. But when shell call IStream.Read and request the part of file which is not downloaded yet - just wait and after the part is downloaded return it.
all related
With JFace TableViewer, I want to select some entry(e.g select a file) by single-click, and do some other operations(e.g go into a directory) by double-click.
Noticing addSelectionChangedListener() and addDoubleClickListener() via a webpage: http://javafact.com/2010/08/07/example-tableviewer-events/ , I add SelectionChangedListener and DoubleClickListener for my TableViwer, and find out:
Either of the two listeners can work, but they can't work together - actually it's DoubleClickListener that can't work.
What's the problem? How I should implement listeners for single-click and double-clicks?
Any comments is appreciated.
About code:
I created a tableViewer, and want to show filesystem structure.
The expected behavior: User can double click a directory entry and tableViewer will show the structure of selected directory; user select a generic file by single-click. For other operations, warning message dialog will be shown.
The following is just code related with event handlers.
tableView.addSelectionChangedListener( new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection sel = (IStructuredSelection) tableView.getSelection();
File selFile = (File) sel.getFirstElement();
if(selFile != null){
if (selFile.isDirectory()) {
MessageDialog.openWarning(getShell(), "Warning", "You select a directory");
return;
}
System.out.println("Selected : "+ selFile.getAbsolutePath());
selectFileName = selFile.getAbsolutePath();
}
}
});
tableView.addDoubleClickListener( new IDoubleClickListener() {
#Override
public void doubleClick(DoubleClickEvent arg0) {
Object selected;
IStructuredSelection selection = (IStructuredSelection) tableView.getSelection();
if (selection.size() != 1) return;
selected = selection.getFirstElement();
File file = (File) selected;
if (file.isFile()) {
MessageDialog.openInformation(getShell(),"Warning", "You double-clicks a generic file");
return;
}
if (file.isDirectory()) {
System.out.println("Clicked direcotry: " + file.getAbsolutePath());
//applyNewDirectory(file);
}
}
});
Regards & Thanks from
Sunzen
(prolog: still working with JFace/SWT here, so this might be of interest to someone)
The problem is that the API allows you to do this, but it does not work (oh SWT...).
You cannot have both listeners on the TableView, as the SelectionChangedListener will always grab the click and consume the event.
The solution is to attach the SelectionChangedListener to the underlying table, and the DoubleClickListener to the TableViewer.
This way you can have both, e.g.:
table.addSelectionChangedListener(new ISelectionChangedListener(...));
tableViewer.addDoubleClickListener(new IDoubleClickListener(...));
I have made one preference page whose programming is:
public class SAML
extends FieldEditorPreferencePage
implements IWorkbenchPreferencePage {
public SAML() {
super(GRID);
setPreferenceStore(RmpPlugin.getDefault().getPreferenceStore());
setDescription("Browse Appropriate files");
}
public FileFieldEditor f;
public FileFieldEditor f1;
public void createFieldEditors() {
f=new FileFieldEditor(PreferenceConstants.P_PATH,
"&Prism.bat File:", getFieldEditorParent());
addField(f);
f1=new FileFieldEditor(PreferenceConstants.P_PATH1,
"&NuSMV Application File:", getFieldEditorParent());
addField(f1);
}
I want to get path of FileFieldEditor f and want this path to run on a button which is embedded on workbench (but programming of that button is in different project on the same workspace).
The button programming which has hard coded path of "prism.bat" file is:
try {
//to clear the console on every click of button
IViewPart view = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(IConsoleConstants.ID_CONSOLE_VIEW);
if (view != null) {
(myConsole).clearConsole();
}
ProcessBuilder pb=new ProcessBuilder("C:\\Program Files\\prism-4.0\\bin\\prism.bat");
pb.directory(new File("C:\\Program Files\\prism-4.0\\bin"));
Process p=pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String in;
while((in = input.readLine()) != null) {
out.println(in);
}
int exitVal=p.waitFor();
if(exitVal==0)
{
out.println("Process Successful");
out.println("Printing on console with Exitvalue =0");
}
else
{out.println("Process failed");
out.println("Exitvalue = 1");
}
}
catch (Exception e)
{
out.println(e.toString());
e.printStackTrace();
}
But I want to fetch file from my preference page FileFieldEditor f and want this path to embed in button programming so that when button is pressed, result is shown.
You need two parts:
Code that initialize the default for the preference
Code that use the current value
To set the default, you use the following code in the Activator:
public class Activator extends AbstractUIPlugin {
#Override
public void start(BundleContext context) throws Exception {
super.start(context);
IPreferenceStore ps = getPreferenceStore();
ps.setDefault(SHOW_IMAGE, true);
}
public static final String SHOW_IMAGE = "showImage";
}
Alternatively, you can use the org.eclipse.core.runtime.preferences extension point...
Note that the code above assume that the type of the preference is Boolean - there are other methods for numbers, strings, etc... A file name is a string.
To use the current value, just use
if (Activator.getDefault().getPreferenceStore().getBoolean(Activator.SHOW_IMAGE)) {
…
}
The following slides contains a little more information...