I am new to JavaFX, and while I want to load a fxml file, I use the bellow codes.
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("view/secondAttempt.fxml"));
I am curious about a new way for setting location. I don't like to use
Main.class.getResource("view/secondAttempt.fxml")
Is there any straightforward way for setting the location of this fxml file?
I am looking for a new solution that doesn't need memorizing so many information to use a fxml file. for example:
loader.setLocation("C:/view/secondAttempt.fxml"));
If you have a lot of load calls, just make a small utility function:
public class FXMLUtil {
// loads an FXML file from a location relative to this class.
public static <T> T load(String loc) throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(FXMLUtil.class.getResource(loc));
return loader.load();
}
}
Use it like so:
Parent content = FXMLUtil.load("view/secondAttempt.fxml");
Related
I'm writing an Eclipseplugin, which has to create a new project. This works so far, but i need to copy an external file into the projectfolder. I intend to have a 'Browse' button on one of my WizardPages, which opens a filedialog, where the user can browse to the file and after closing the dialog i can use the path to this file for various actions. My problem is that the dialog window never opens. Right now i'm trying it that way (snippet from my wizardpage):
public void createControl(Composite composite) {
this.container = new Composite(composite, SWT.NONE);
GridLayout layout = new GridLayout();
this.container.setLayout(layout);
layout.numColumns = 2;
Button browseButton = new Button(this.container, SWT.PUSH);
browseButton.setText("Browse");
browseButton.addSelectionListener(new SelectionListener() {
#Override
public void widgetDefaultSelected(SelectionEvent arg0) {
FileDialog fileDialog = new FileDialog(DataPage.this.container.getShell(), SWT.OPEN);
fileDialog.setText("JZOS created File");
String path = fileDialog.open();
DataPage.this.setJzosCreatedName(path);
}
});
I tried several implementations, that i have seen in examples and tutorials but nothing did work. I'm assuming a problem with the Shell that i give to the filedialog. I tried to open a new Shell within the widgetDefaultSelected function but it didn't work either. Any Suggestions?
You should be using the widgetSelected method of SelectionListener not widgetDefaultSelected
I am trying to figure out if there is a way to get a reference to the FXML for a given node.
For example I am dynamically loading views - assume I have a Pane referenced in the current Controller:
private void openView() {
FXMLLoader loader = new FXMLLoader();
Parent node = loader.load(this.getClass().getResource("MyView.fxml").openStream());
pane.getChildren().add(node);
node.requestFocus();
}
I would like to save which views were open so that I can relaunch them next time the window is open. Something like this:
private void saveOpenViews() {
pane.getChildren().forEach(child -> {
String fxmlLocation = child.getFXML();
etc....
}
}
I can't seem to find a way to get that back to persist what was open... Was hoping there was a way, other than manually tracking in another place.
Thanks.
Store the related fxml information in the node userData when you load the node from fxml, then lookup the userdata when you need to know what fxml the node is related to.
private void openView() {
FXMLLoader loader = new FXMLLoader();
URL fxmlLocation = this.getClass().getResource("MyView.fxml");
Parent node = loader.load(fxmlLocation.openStream());
node.setUserData(fxmlLocation);
pane.getChildren().add(node);
node.requestFocus();
}
private void saveOpenViews() {
pane.getChildren().forEach(child -> {
URL fxmlLocation = (URL) child.getUserData();
etc....
}
}
I have this utility method which allows easily to change what is shown in specific location of my application.
The problem is it looks more like that the new Part is on top of the old Part (the old Part is not removed and it is still visible under the new Part).
package cz.vutbr.fit.xhriba01.bc.ui;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
public class UI {
public static final String PART_INSPECTOR_ID = "bc.part.inspector";
public static void changeInspectorView(String partDescriptorId, EPartService partService, EModelService modelService) {
MPart part = partService.createPart(partDescriptorId);
MPart oldPart = partService.findPart(UI.PART_INSPECTOR_ID);
MPartSashContainer parent = (MPartSashContainer) modelService.getContainer(oldPart);
parent.getChildren().remove(oldPart);
part.setElementId(UI.PART_INSPECTOR_ID);
parent.getChildren().add(0, part);
}
}
You should use:
partService.hidePart(oldPart);
to hide the old part (also removes it from the children).
You might also just be able to do:
oldPart.setToBeRendered(false);
but I am not sure that does enough to update the Eclipse internal state.
I need to show annotations on files outside of Workspace.
I am able to show annotations on files present in Worspace
When i try to do the same for files outside the Workspace I need to create resource and ifile object. How do i achieve the same?
How do i read contents of file outside workspace since i am unable to create a ifile object.
Here is what i am doing right now:
IEditorPart editor =(IEditorPart) wins[i].getPartService().getActivePart()
IEditorInput input = editor.getEditorInput();
IPath path = ((FileEditorInput)input).getPath();
IFile file= workspace.getRoot().getFileForLocation(path);
You cannot annotation files outside of workspace. An IFile is only defined for workspace files.
Just in case you don't know, files and projects don't have to the under the workspace's folder on the file system to be in the workspace.
Maybe you can surreptitiously add a hidden project to the workspace and link the file as a resource in it. I don't think that an external file converted to an internal file loses any behaviors. But, it could gain more than you want. One that I can think of is that source control plugins might then detect it.
Or, you could point out to the user that there are advantages to adding the file to the workspace and let them make the choice. You might be able to show a dialog asking which new or existing project/folder to add it to. Of course, if they decline then you should remember and not ask again about that external file.
UPDATE:
FileStoreEditorInput represents a file that is not part of the current workspace. To listen for external files being opened, subscribe with an IPartListener2 on each window.
public class Activator extends AbstractUIPlugin implements IStartup {
#Override
public void earlyStartup() {
final PartListener partListener = new PartListener();
for (final IWorkbenchWindow window : getWorkbench().getWorkbenchWindows()) {
window.getPartService().addPartListener(partListener);
}
getWorkbench().addWindowListener(new IWindowListener() {
#Override
public void windowOpened(IWorkbenchWindow window) {
window.getPartService().addPartListener(partListener);
}
});
}
private class PartListener implements IPartListener2 {
#Override
public void partOpened(final IWorkbenchPartReference partRef) {
if (partRef.getPart(false) instanceof EditorPart) {
final EditorPart editor = (EditorPart) partRef.getPart(false);
if (editor.getEditorInput() instanceof FileStoreEditorInput) {
final FileStoreEditorInput input = (FileStoreEditorInput) editor.getEditorInput();
System.out.println(input.getURI());
}
}
}
}
I'm trying to use a custom widget: gwtupload with it's custom handlers. The handlers are defined as interfaces, as in, Interface.OnCustomEventHandler and the method, according to the API, that I want to use is like this code, but I'm not sure how to implement this with uiBinder.:
void onCustomEvent (Interface interface)
Normally for uiBinder I use this code for the regular gwt widgets:
#Widget widget;
#UiHandler("widget")
void onClick(ClickEvent event){
//Handle the event processing here.
}
Presently, when I try this,
#UiHandler("widget")
void onCustomEvent(ICustomInterface customInterface){
...
I get this null pointer exception:
[ERROR] Generator 'com.google.gwt.uibinder.rebind.UiBinderGenerator' threw an exception while rebinding '...ViewImpl.ViewImplUiBinder'
java.lang.NullPointerException
Here is the new code I tried:
public class MUpld extends Composite {
private static MUpldUiBinder uiBinder = GWT.create(MUpldUiBinder.class);
interface MUpldUiBinder extends UiBinder<Widget, MUpld> {
}
#UiField MultiUploader uploader;
public MUpld() {
final IUploader.OnFinishUploaderHandler onFinishUploaderHandler = new IUploader.OnFinishUploaderHandler() {
#Override
public void onFinish(IUploader iUploader) {
if (uploader.getStatus() == Status.SUCCESS){
System.out.println("In the onFinish method!");
}
}
};
initWidget(uiBinder.createAndBindUi(this));
uploader.addOnFinishUploadHandler(onFinishUploaderHandler);
}
}
In the debugger, I saw the handler get attached to the uploader widget I defined, but then the current uploader became a different one once the code moved out of this class. I tried using the final modifier, as that is the only way I know to get a variable into an inner class, but gwt would complain with:
[ERROR] com.cdg.complexityCalculator.client.view.MUpld has no default (zero args) constructor.
To fix this, you can define a #UiFactory method on the UiBinder's owner, or annotate a constructor of MUpld with #UiConstructor.
I wasn't able to get either of those options to work, but I realized I had the last two lines of code switched, so I changed it to what I have now and the handler loaded up with the correct object.
Any ideas as to how to get this to work? Everything else is in place, I just need a way to capture this event after my servlet has finished processing.
When I changed the last two lines of code, the handler got loaded properly. Now the objects are being created with the handler binding to the correct object.
initWidget(uiBinder.createAndBindUi(this));
uploader.addOnFinishUploadHandler(onFinishUploaderHandler);
I had to wait until the uiBinder created the instance of the uploader widget, then I was able to add the handler to it.
One of the tricks I've learned is to add a handler in the constructor for a composite widget you create, that way it's more of an encapsulated component. It handles it's own events.