IWorkbenchPart.openEditor() not opening custom editor - eclipse-plugin

I'm designing an Eclipse plugin designed around a new perspective with an editor that stores code/comment snippets upon highlighting them. The parts to it include: the perspective, the editor, and a mouselistener.
I have the perspective made and can open it. I have the editor class code constructed, however, on programmatically opening the editor via IWorkbenchPart.openEditor() my custom editor does not seem to be initialized in any way. Only the default Eclipse editor appears. I can tell because my custom mouse events do not fire.
I used the vogella tutorial as a reference.
Why is my editor's init() method not being called upon being opened? I can tell it is not since the print statement in both init() and createPartControl() are not executed.
In googling this problem, I found a number of hits but they all revolved around error messages encountered (can't find editor, can't find file, ...). I am getting no error messages, just unexpected behaviour. So those articles were useless.
(I would ideally like a TextViewer instead, since I don't want them editing the contents in this mode anyway, but I decided to start here.)
Code below.
Perspective:
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
public class PluginPerspective implements IPerspectiveFactory {
#Override
public void createInitialLayout(IPageLayout layout) {
layout.setEditorAreaVisible(true);
layout.setFixed(true);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorInput iei = page.getActiveEditor().getEditorInput();
try
{
// Open Editor code nabbed from Vogella tutorial.
// He creates an action to do so - I force it to happen when the
// perspective is created.
// I get the name of the current open file as expected.
System.out.println(iei.getName());
page.openEditor(iei, myplugin.PluginEditor.ID, true);
// This message prints, as expected.
System.out.println("open!");
} catch (PartInitException e) {
throw new RuntimeException(e);
}
}
}
Editor: (Removed the other basic editor stubs (isDirty, doSave) since they are not pertinent)
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.texteditor.ITextEditor;
public class PluginEditor extends EditorPart implements MouseListener {
public static final String ID = "myplugin.plugineditor";
#Override
public void init(IEditorSite site, IEditorInput input)
throws PartInitException {
// TODO Auto-generated method stub
System.out.println("editor init!");
setSite(site);
setInput(input);
}
#Override
public void createPartControl(Composite parent) {
// TODO Auto-generated method stub
System.out.println("editor partcontrol!");
//TextViewer tv = new TextViewer(parent, 0);
//tv.setDocument(getCurrentDocument());
}
#Override
public void mouseDoubleClick(MouseEvent e) {
// TODO Auto-generated method stub
// nothing?
}
#Override
public void mouseDown(MouseEvent e) {
// TODO Auto-generated method stub
// grab start location?
System.out.println("down!");
}
#Override
public void mouseUp(MouseEvent e) {
// TODO Auto-generated method stub
// do stuff!
System.out.println("up!");
}
// to be used for grabbing highlight-selection grabbing later
public IDocument getCurrentDocument() {
final IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.getActiveEditor();
if (!(editor instanceof ITextEditor)) return null;
ITextEditor ite = (ITextEditor)editor;
IDocument doc = ite.getDocumentProvider().getDocument(ite.getEditorInput());
return doc;
//return doc.get();
}
}

Have you registered your editor within your plugin.xml?
<extension
point="org.eclipse.ui.editors">
<editor
default="false"
id="myplugin.plugineditor"
name="name">
</editor>
</extension>
Also, you may want to implement IEditorInput to have specific input for your editor.

Related

"java[934:22850] +[CATransaction synchronize] called within transaction" when a FileChooser dialog box is displayed

In running a Java program, using IntelliJ Community Edition 2021.2, I am seeing console output "java[934:22850] +[CATransaction synchronize] called within transaction" when a FileChooser dialog box is displayed. The dialog appears to work OK, but I'm puzzled about the message.
MacOS 13.0.1 (Ventura);
IntelliJ Community Edition 2021.2;
JDK 15.0.2;
JavaFX 15.0.1+1
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.*;
public class Main extends Application {
// ..................... and now it's time for the main routine .....................
#Override
public void start(Stage primaryStage) {
// we need a FileChooser
FileChooser myChooser = new FileChooser();
// set up a controlled exit
primaryStage.setOnCloseRequest(e -> {
e.consume();
primaryStage.close();
});
// define the main scene's building blocks
VBox root = new VBox(5); // the spacing is between each element in the VBox
Scene mainScene = new Scene(root, 650, 300);
// just one button in the scene
Button websiteSupportButton = new Button("Process file");
websiteSupportButton.setMinWidth(150);
root.getChildren().add(websiteSupportButton);
websiteSupportButton.setOnAction(e -> processFiles(primaryStage, myChooser));
// and now we're ready to associate the root Scene with the primary stage, and show it
primaryStage.setX(20);
primaryStage.setY(20);
primaryStage.setScene(mainScene);
primaryStage.setTitle("Error test");
primaryStage.show();
}
// .................................. tool scenes ..................................
// stuff moved from WebsiteSupport, and severely cut down - select an input file.
private static void processFiles(Stage myStage, FileChooser myChooser) {
File inputFile;
// need to select an input file - displaying this dialog causes multiple "java[1334:69043] +[CATransaction synchronize] called within transaction" messages
inputFile = myChooser.showOpenDialog(myStage);
if (inputFile != null) {
System.out.println(" file processed");
}
}
// .......................................... standard stuff ..........................................
public static void main(String[] args) {
launch(args);
}
}
I tried your code on:
OS X (intel) 13.0.1
JavaFX 19
OpenJDK 19.0.1
It received the same error message (multiple times for a single call):
java[34308:361725] +[CATransaction synchronize] called within transaction
I believe it occurs every time the file chooser showOpenDialog method is invoked in this configuration. A minimal example which replicates the issue on execution is:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class FileChooserCATransactionLogGeneratorApp extends Application {
#Override
public void start(Stage stage) {
stage.setScene(new Scene(new Group()));
stage.show();
FileChooser myChooser = new FileChooser();
myChooser.showOpenDialog(stage);
}
public static void main(String[] args) {
launch(args);
}
}
I advise filing a bug report.
If you do file a bug report and a bug id is generated, you can add a link to the bug report as a comment or an edit on this answer.

How to implement push notification and file upload and download with webview?

I was wanting to know how my app can alert users that they have a notification on my forum? Also I'd like to know how I can allow users to upload and download files to and from my forum within the app. I'm using webview and not sure if my code is up to date. I'm a noob when it comes to this stuff.
Here's my code:
package technologx.technologx;
/**
* Created by Technologx on 12/22/15
* ©2015 Technologx All Rights Reserved
* http://technologx.fulba.com
*/
import android.os.Build;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;
#SuppressLint("SetJavaScriptEnabled")
public class MainActivity extends Activity {
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If the Android version is lower than Jellybean, use this call to hide
// the status bar.
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
// Adds Progress Bar Support
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
// Makes Progress Bar Visible
getWindow().setFeatureInt(Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON);
// Use forum.xml as webview layout
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
// Adds Zoom Control (You may not need this)
webView.getSettings().setSupportZoom(true);
// Enables Multi-Touch. if supported by ROM
webView.getSettings().setBuiltInZoomControls(true);
// Change to your own forum url
webView.loadUrl("http://technologx.96.lt/");
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Loads only your forum domain and no others!
if (url.contains("technologx.96.lt") == true) {
view.loadUrl(url);
// Adds Progress Bar Support
super.onPageStarted(view, url, null);
findViewById(R.id.progressbar).setVisibility(View.VISIBLE);
// If they are not your domain, use browser instead
} else {
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(i);
}
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
// Removes Progress Bar
findViewById(R.id.progressbar).setVisibility(View.GONE);
// Adds Cookies. Yummy!
CookieSyncManager.getInstance().sync();
}
});
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
#Override
public void onBackPressed() {
// Enables going back history
if (webView.copyBackForwardList().getCurrentIndex() > 0) {
webView.goBack();
} else {
// Your exit alert code, or alternatively line below to finish
// Finishes forum activity
super.onBackPressed();
}
}
#Override
public void onStart() {
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://technologx.technologx/http/host/path")
);
AppIndex.AppIndexApi.start(client, viewAction);
}
#Override
public void onStop() {
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Main Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://technologx.technologx/http/host/path")
);
AppIndex.AppIndexApi.end(client, viewAction);
client.disconnect();
}
}

auto pretty formatting in xtext

I want to ask that is there a way to do Pretty formatting in xtext automatically without (ctrl+shift+f) or turning it on from preference menu. What I actually want is whenever a user completes writing the code it is automatically pretty formatted (or on runtime) without (ctrl+shift+f).
There is a way for doing that which is called "AutoEdit". It's not exactly when the user completes writing but it's with every token. That's at least what I have done. You can for sure change that. I will give you an example that I implemented myself for my project. It basically capitalizes everykeyword as the user types (triggered by spaces and endlines).
It is a UI thing. So, In your UI project:
in MyDslUiModule.java you need to attach your AutoEdit custom made class do that like this:
public Class<? extends DefaultAutoEditStrategyProvider> bindDefaultAutoEditStrategyProvider()
{
return MyDslAutoEditStrategyProvider.class;
}
Our class will be called MyDslAutoEditStrategyProvider so, go ahead and create it in a MyDslAutoEditStrategyProvider.java file. Mine had this to do what i explained in the introduction:
import java.util.Set;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.ui.editor.autoedit.DefaultAutoEditStrategyProvider;
import org.eclipse.xtext.ui.editor.model.XtextDocument;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class MyDslAutoEditStrategyProvider extends DefaultAutoEditStrategyProvider {
#Inject
Provider<IGrammarAccess> iGrammar;
private Set<String> KWDS;
#Override
protected void configure(IEditStrategyAcceptor acceptor) {
KWDS = GrammarUtil.getAllKeywords(iGrammar.get().getGrammar());
IAutoEditStrategy strategy = new IAutoEditStrategy()
{
#Override
public void customizeDocumentCommand(IDocument document, DocumentCommand command)
{
if ( command.text.length() == 0 || command.text.charAt(0) > ' ') return;
IRegion reg = ((XtextDocument) document).getLastDamage();
try {
String token = document.get(reg.getOffset(), reg.getLength());
String possibleKWD = token.toLowerCase();
if ( token.equals(possibleKWD.toUpperCase()) || !KWDS.contains(possibleKWD) ) return;
document.replace(reg.getOffset(), reg.getLength(), possibleKWD.toUpperCase());
}
catch (Exception e)
{
System.out.println("AutoEdit error.\n" + e.getMessage());
}
}
};
acceptor.accept(strategy, IDocument.DEFAULT_CONTENT_TYPE);
super.configure(acceptor);
}
}
I assume you saying "user completes writing" can be as "user saves file". If so here is how to trigger the formatter on save:
in MyDslUiModule.java:
public Class<? extends XtextDocumentProvider> bindXtextDocumentProvider()
{
return MyDslDocumentProvider.class;
}
Create the MyDslDocumentProvider class:
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.xtext.ui.editor.model.XtextDocumentProvider;
public class MyDslDocumentProvider extends XtextDocumentProvider
{
#Override
protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite)
throws CoreException {
IHandlerService service = (IHandlerService) PlatformUI.getWorkbench().getService(IHandlerService.class);
try {
service.executeCommand("org.eclipse.xtext.ui.FormatAction", null);
} catch (Exception e)
{
e.printStackTrace();
}
super.doSaveDocument(monitor, element, document, overwrite);
}
}

Cucumber: Unable to find step definition

I have the following feature file: MacroValidation.feature
#macroFilter
Feature: Separating out errors and warnings
Scenario: No errors or warnings when separating out error list
Given I have 0 macros
When I filter out errors and warnings for Macros
Then I need to have 0 errors
And I need to have 0 warnings
My definition files.
package com.test.definition;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import cucumber.runtime.java.StepDefAnnotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.spy;
#StepDefAnnotation
public class MacroValidationStepDefinitions {
private final MacroService macroService = spy(new MacroService());
private final LLRBusList busList = mock(LLRBusList.class);
private final List<String> errorList = new ArrayList<String>();
private final List<String> warningList = new ArrayList<String>();
#Before({"#macroFilter"})
public void setUp() {
errorList.addAll(Arrays.asList("error 1, error2, error 3"));
warningList.addAll(Arrays.asList("warning 1, warning 2, warning 3"));
}
#After({"#macroFilter"})
public void tearDown() {
errorList.clear();
warningList.clear();
}
#Given("^I have (\\d+) macros$")
public void i_have_macros(int input) {
doReturn(input).when(busList).size();
}
#When("^I filtered out errors and warnings for Macros$")
public void i_filtered_out_errors_and_warnings_for_Macros() {
macroService.separateErrorsAndWarning(busList, errorList, warningList);
}
#Then("^I need to have (\\d+) errors$")
public void i_need_to_have_errors(int numOfError) {
if (numOfError == 0) {
assertTrue(errorList.isEmpty());
} else {
assertEquals(errorList.size(), numOfError);
}
}
#Then("^I need to have (\\d+) warnings$")
public void i_need_to_have_warnings(int numOfWarnings) {
if (numOfWarnings == 0) {
assertTrue(warningList.isEmpty());
} else {
assertEquals(warningList.size(), numOfWarnings);
}
}
}
My unit test class.
#CucumberOptions(features = {"classpath:testfiles/MacroValidation.feature"},
glue = {"com.macro.definition"},
dryRun = false,
monochrome = true,
tags = "#macroFilter"
)
#RunWith(Cucumber.class)
public class PageMacroValidationTest {
}
When I execute the test, I get file definition not implemented warnings in the log.
Example log:
You can implement missing steps with the snippets below:
#Given("^I have (\\d+) macros$")
public void i_have_macros(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
#When("^I filter out errors and warnings for Macros$")
public void i_filter_out_errors_and_warnings_for_Macros() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
#Then("^I need to have (\\d+) errors$")
public void i_need_to_have_errors(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
#Then("^I need to have (\\d+) warnings$")
public void i_need_to_have_warnings(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
I don't think file name should matter right?
It looks like Cucumber isn't finding your step defintion class. In your unit test class you say:
glue = {"com.macro.definition"}
However the step definition classes are in com.test.definition
Try changing that line to:
glue = {"com.test.definition"}
You may have to rebuild your project to pick up the change.
Also, Cucumber is sensitive to white space. If you try to make your runner or feature file pretty after having captured the snippets, you will get this problem.
Here's an example that drove me nuts for several hours while creating my first BDD. I had created the feature file and a skeleton runner which I ran and and captured the snippets. Then I prettified the feature file, and when I ran the runner got the errors.
Of course everything looked fine to my human brain, so the next few hours were spent in fruitless research here, and checking versions and bug lists. Finally I decided to compare the first two lines of the snippet to see what was different:
// #Then("^the test result is = \"([^\"]*)\"$")
// public void theTestResultIs(String ruleResult) throws Throwable {
#Then("^the test result is = \"([^\"]*)\"$")
public void theTestResultIs(String arg1) throws Throwable {
Doh!
Try to use all dependencies in POM.xml with io.cucumber group id which is the latest jars instead of info.cukes. After removing jars update the project with new imports and run the project.
Remember you have to replace all dependencies of info.cukes with io.cucumber

How to get path of current selected file in Eclipse plugin development

I am opening an Editor with Open with menu in Eclipse.But i am not able to get path of current selected file.Sometimes it gives proper path but sometimes throws null pointer Exception.
I am writing following code to get selected file path.
IWorkbenchPage iwPage=PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
System.err.println("iwpage::"+iwPage);
ISelection selection=iwPage.getSelection();
System.err.println("selection::::testtttt"+selection.toString());
if(selection!=null && selection instanceof IStructuredSelection)
{
IStructuredSelection selectedFileSelection = (IStructuredSelection) selection;
System.out.println(selection.toString());
Object obj = selectedFileSelection.getFirstElement();
selectedFile=(IResource)obj;
System.err.println("selection::::"+selectedFile.getLocation().toString());
String html=selectedFile.getLocation().toString().replace(" ","%20");
String html_file="file:///"+html;
return html_file;
}
I found an answer in the Eclipse forum that seems easier and works for me so far.
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window =
workbench == null ? null : workbench.getActiveWorkbenchWindow();
IWorkbenchPage activePage =
window == null ? null : window.getActivePage();
IEditorPart editor =
activePage == null ? null : activePage.getActiveEditor();
IEditorInput input =
editor == null ? null : editor.getEditorInput();
IPath path = input instanceof FileEditorInput
? ((FileEditorInput)input).getPath()
: null;
if (path != null)
{
// Do something with path.
}
Some of those classes required new project references, so here's a list of all my imports for that class. Not all of them are related to this snippet, of course.
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.LineNumberRulerColumn;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.osgi.framework.Bundle;
You can ask the active editor for the path of the underlying file. Just register an IPartListener to your active IWorkbenchPage and ask withing this listener when activating a part. Here is a snippet
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.addPartListener(new IPartListener() {
#Override
public void partOpened(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
#Override
public void partDeactivated(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
#Override
public void partClosed(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
#Override
public void partBroughtToTop(IWorkbenchPart part) {
if (part instanceof IEditorPart) {
if (((IEditorPart) part).getEditorInput() instanceof IFileEditorInput) {
IFile file = ((IFileEditorInput) ((EditorPart) part)
.getEditorInput()).getFile();
System.out.println(file.getLocation());
}
}
}
#Override
public void partActivated(IWorkbenchPart part) {
// TODO Auto-generated method stub
}
});