Create new NetBeans "save as" module - netbeans

My goal is simple - save the current HTML file in the NetBeans editor with one additional line at the top and bottom of the file, and with the extension of ".h".
This is my first attempt at a NetBeans module, but following some tutorials and research, I got as far as adding an entry to the popup menu when you right-click on an HTML file in the editor. It currently just shows a "Hello World" message:
The code to do that is here:
package ksmiller99.savehtmlasarduinoresource;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle.Messages;
#ActionID(
category = "Edit",
id = "ksmiller99.savehtmlasarduinoresource.SaveHtmlAsArduinoResource"
)
#ActionRegistration(
displayName = "#CTL_SaveHtmlAsArduinoResource"
)
#ActionReference(path = "Editors/text/html/Popup")
#Messages("CTL_SaveHtmlAsArduinoResource=Save as Arduino Resource")
public final class SaveHtmlAsArduinoResource implements ActionListener {
#Override
public void actionPerformed(ActionEvent ev) {
//todo add a line to top and bottom of current file and save with .h extension
JOptionPane.showMessageDialog(null, "Hello Save As World");
}
}
How can I access the contents of the current editor? Would a different approach make more sense?
I'm using NetBeans 12.0, JDK 13, Windows 10.

Use the New Action wizard to create the source code for a Conditionally Enabled action, enabled when User Selects One Node.
In the 2nd wizard panel select File Type Context Menu and choose text/html as content type. If you want your action to appear only in the context menu you can disable Global Menu Item.
You should end up with code like this:
#ActionID(
category = "File",
id = "org.test.TestHtmlAction"
)
#ActionRegistration(
displayName = "#CTL_TestHtmlAction"
)
#ActionReference(path = "Loaders/text/html/Actions", position = 0)
#Messages("CTL_TestHtmlAction=TestHtmlAction")
public final class TestHtmlAction implements ActionListener
{
private final DataObject context;
private static final Logger LOGGER = Logger.getLogger(TestHtmlAction.class.getName());
public TestHtmlAction(DataObject context)
{
this.context = context;
}
#Override
public void actionPerformed(ActionEvent ev)
{
FileObject file = context.getPrimaryFile();
LOGGER.info("context=" + context.getName() + " file.getPath()=" + file.getPath());
}
}
The wizard creates a context aware action, which is enabled only when user selects a single HTML file node. The DataObject parameter gives you the context of the selected node, so you can retrieve the file path etc.

Related

E4: drag an object from a TableViewer to Windows Explorer (or OS specific file system)

In my Eclipse RCP application I display some business data in a TableViewer.
I want the user to be able to drag a row from the table viewer and drop it on the windows desktop/explorer. Windows should then create a file with the data from the selected row that I could provide in the dragSetData(..) method of the DragSourceAdapter class.
How to implement this? It seems that using FileTransfer as the dragSourceSupport on the table viewer is the way to go as it trigger a call to the dragSetData() method. But what object should I create and assign to "event.data" in this method?
A working example would be appreciated.
I've implemented the reverse without problem, i.e. drag a file from windows explorer onto the TableViewer and add a row in the table. There are plenty on sample for this on the net but can't find a sample of the opposite, drag from eclipse to the OS
[edit + new requirement]
So I understand that I have to create a temporary file somewhere and set the name of that temp file in event.data in dragSetData()
Q: is there a simpler way to do that, eg set somewhere (iun data) the content of the file directly without the temp file?
There is another requirement. When the drop operation is about to occur, I want to show a popup to the user that will have to choose what "business data" from the "row" he wants to export and the name of the file that will be created. I tried the following (only asking for the filename for now) but it does not work as expected as the popup shows up as soon as the cursor reach the first pixel outside my app. I would like to show the popup just "before" the drop operation occurs.
Q: is there a way to have this popup show just before the drop operation occurs, ie when the user "release" the mouse button?
#Override
public void dragSetData(final DragSourceEvent event){
if (FileTransfer.getInstance().isSupportedType(event.dataType)) {
// Will be a more complex dialog with multiple fields..
InputDialog inputDialog = new InputDialog(shell, "Please enter a file name", "File Name:", "", null);
if (inputDialog.open() != Window.OK) {
event.doit = false;
return;
}
event.data = new String[] { inputDialog.getValue() };
}
}
The event.data for FileTransfer is an array of file path strings.
You DragSourceAdapter class might look something like:
public class MyDragSourceAdapter extends DragSourceAdapter
{
private final StructuredViewer viewer;
public MyDragSourceAdapter(final StructuredViewer viewer)
{
super();
this.viewer = viewer;
}
#Override
public void dragStart(final DragSourceEvent event)
{
IStructuredSelection selection = viewer.getStructuredSelection();
if (selection == null)
return;
// TODO check if the selection contains any files
// TODO set event.doit = false if not
}
#Override
public void dragSetData(final DragSourceEvent event)
{
if (!FileTransfer.getInstance().isSupportedType(event.dataType))
return;
IStructuredSelection selection = viewer.getStructuredSelection();
List<String> files = new ArrayList<>(selection.size());
// TODO add files in the selection to 'files'
event.data = files.toArray(new String [files.size()]);
}
}
and you install it on your viewer with:
MyDragSourceAdapter adapter = new MyDragSourceAdapter(viewer);
viewer.addDragSupport(DND.DROP_COPY, new Transfer [] {FileTransfer.getInstance()}, adapter);

Eclipse 4 RCP - how to remove Part from application model?

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.

How to show standard editor statusbar items for MultiPageEditor

When I open a file in a TextEditor the status bar shows information like positions, whether the file is writable or not ...
Now I have created a MultiPageEditor that contains a class derived from org.eclipse.ui.editors.text.TextEditor. If I edit a file with this editor the status bar remains empty.
Is there an easy way make the standard status bar items visible if the TextEditor is embedded in a MultiPageEditor?
Im using Eclipse Kepler.
In your MultiPageEditorActionBarContributor class you need to do:
private StatusLineContributionItem _showLine;
...
_showLine = new StatusLineContributionItem(ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION, true, 14);
#Override
public void setActivePage(IEditorPart part)
{
if (part instanceof ITextEditorExtension)
{
ITextEditorExtension extension = (ITextEditorExtension)part;
extension.setStatusField(_showLine, ITextEditorActionConstants.STATUS_CATEGORY_INPUT_POSITION);
}
}
#Override
public void contributeToStatusLine(IStatusLineManager statusLineManager)
{
statusLineManager.add(_showLine);
}

Eclipse - Opening editor programmatically causes focus problems

I'm having a bit of an issue with an eclipse plugin that I am working on. In this plugin, a special type of plugin-specific editor is often opened programmatically; this is triggered by various actions in various views/editors, but the code to open the editor is the same. The plugin-specific editors open fine; however, I've recently noticed that every time one of these editors is opened, a strange focus glitch happens:
When the editor is opened, it appears to receive focus, but if the previously active view/editor is clicked immediately after this, it does not take back focus. As soon as anything other than the previously active view/editor is clicked, the problem is instantly solved, and focus resumes normally.
As an example, say you choose a context menu option from the Package Explorer view, which causes an editor to open. The editor opens properly and appears to have focus. After this, you first click again on the Package Explorer, but it doesn't get focus (the editor still appears to have focus). You right-click on Package Explorer, but Package Explorer-specific context menu items do not appear. After this, you click on some other view and then on Package Explorer again. Now Package Explorer gets focus, as normal.
This is the code I'm using to open the editor:
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
final GraphEditorPart gp = (GraphEditorPart) page.openEditor(new NullEditorInput(), "editor.id");
After this, the editor is populated with some visuals, via the albireo SWT-AWT bridge (Not sure if this is relevant to the problem -- the class used for main editor elements is org.eclipse.albireo.core.SwingControl).
I thought perhaps the problem was that the editor wasn't "really" getting focus, or the previously active view wasn't "really" losing focus, so I tried adding the following line:
page.activate(gp);
However this didn't seem to change anything. Why this might happen?
package name:rcp_demo.Editor
class name: EmpCommand.java, EmployeeEditor.java and EmployeeEditorInput.java
package rcp_demo.Editor;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.handlers.HandlerUtil;
public class EmpCommand extends AbstractHandler {
public static final String Id = "rcp_demo.Editor.EmpCommand";
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
IWorkbenchPage page = window.getActivePage();
IEditorReference[] editors = page.getEditorReferences();
EmployeeEditorInput input = new EmployeeEditorInput();
//All Comments are easily understand
//public class EmployeeEditorInput implements IEditorInput{}
for (int i=0; i<editors.length; i++) {
//List out all Exist editor
//compare with EmployeeEditor.Id="rcp_demo.Editor.emp";
if (editors[i].getId().equals(EmployeeEditor.Id)) {
//public class EmployeeEditor extends EditorPart
//{
// public static final String Id="rcp_demo.Editor.emp";
// public void createPartControl(Composite parent) {.....}
//}
page.activate(editors[i].getEditor(true));
System.out.println("set focus an existing editor(Employee)");
return null;
}
}
try {
//open new Editor like EmployeeEditor.Id="rcp_demo.Editor.emp";
page.openEditor(input,EmployeeEditor.Id);
System.out.println("open Editor(Employee) ");
} catch (PartInitException e) {
e.printStackTrace();
}
return null;
}
}
Full describe this question and answer visit :
Eclipse RCP : have the same editor open in editor window

Disable the window resize on JFace WizardPage

I want to disable the button maximize/minimize, below I post image to explain
this is my code :
public class ProjectWizardPageOne extends WizardPage {
private String platform;
public ProjectWizardPageOne(String title) {
super(title);
this.setTitle(title);
this.setMessage("Configure Project Name and Location");
}
#Override
public void createControl(Composite parent) {
Composite container = new Composite(parent,SWT.NONE);
setPageComplete(false);
setControl(container);
Canvas leftPanel = new Canvas(container, SWT.NONE);
leftPanel.setBackgroundImage(new Image(leftPanel.getDisplay(), this
.getClass().getClassLoader()
.getResourceAsStream("/icons/mypicture.png")));
leftPanel.setBounds(0, 0, 183, 282);
Composite rightContainer = new Composite(container, SWT.NONE);
rightContainer.setBackground(new Color(null, 255, 255, 255));
rightContainer.setBounds(181, 0, 399, 282);
}
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
}
I tried to get the Composite's Shell like this "container.getShell();"
but I don't understand How I can set these parameters "SWT.SHELL_TRIM | SWT.TOOL"!
Thanks
Controlling the Window/Shell is not the responsibility of a WizardPage, it can not do that. It's the responsibility of the WizardDialog or the code that creates it. In fact, there is no guarantee that a Wizard and its WizardPages will even be contained in a WizardDialog; anything can implement the IWizardContainer interface to present wizards in a different way.
Is it a File -> New wizard or a custom wizard that is programatically launched. If it is custom, you would have to create WizardDialog and then pass Wizard instance to it. When creating WizardDialog, you would also create Shell, for which you can send the argument without SWT.RESIZE. For File -> New, since the dialog is not created by you, I dont think you can control resize option there. The resize can only be passed in the constructor of Shell.
In case of dialogs, I have observed that I need to explicitly specify that I need min, max buttons at upper-right corner. For that I need to call the below method in a constructor:
setShellStyle(getShellStyle() | SWT.MAX | SWT.MIN | SWT.RESIZE);
Since Wizard is also a dialog, I can call the above method to reset the shellStyle not to include max, min, and other buttons (see above code). The wizard by default might be adding these buttons. But I think you can override this by recalling at the end of wizard creation. Hope this helps.
public class InstallerWizard extends Wizard{
...
main()
{
WizardDialog dialog = new DisableMax(shell, new InstallerWizard());
dialog.open();
}
}
public class DisableMax extends WizardDialog {
public DisableMax(Shell parentShell, IWizard newWizard) {
super(parentShell, newWizard);
setShellStyle(SWT.CLOSE | SWT.MIN | SWT.RESIZE | getDefaultOrientation());
}
}