Eclipse PDE: Programmatically detect opened dialog and close it - eclipse

On Eclipse Luna, I select a server and click the Start button on Servers view, then the server (for example Tomcat8) will get started. If something is wrong during the start-up process, a dialog will be populated to display the error messages (for example time-out). The dialog is modeless in this test case.
Now I need to start the server programmatically from a plugin. In case that errors occur, how could I programmatically detect that a dialog has been opened and how to close it?

You could use the Display.addFilter method to listen for all SWT.Activate events which will tell you about all Shells (and other things) being activated. You can then detect the shells you want to close.
Something like:
Display.getDefault().addFilter(SWT.Activate, new Listener()
{
#Override
public void handleEvent(final Event event)
{
// Is this a Shell being activated?
if (event.widget instanceof Shell)
{
final Shell shell = (Shell)event.widget;
// Look at the shell title to see if it is the one we want
if ("About".equals(shell.getText()))
{
// Close the shell after it has finished initializing
Display.getDefault().asyncExec(new Runnable()
{
#Override
public void run()
{
shell.close();
}
});
}
}
}
});
which closes a dialog called 'About'.
In more recent versions of Java the above can be simplified to:
Display.getDefault().addFilter(SWT.Activate, event ->
{
// Is this a Shell being activated?
if (event.widget instanceof Shell shell)
{
// Look at the shell title to see if it is the one we want
if ("About".equals(shell.getText()))
{
// Close the shell after it has finished initializing
Display.getDefault().asyncExec(shell::close);
}
}
});
This uses Java 8 lambdas and method references and Java 16 instanceof type patterns.

Related

How to intercept system keypress in a GTK application

I am working on a Vala GTK application that starts minimized by default and I want to bind a specific keyword shortcut to bring the minimized window to the front.
I am able to handle Keyboard events using Accelerators when the app is focus ed, but I am unable to intercept any key press from the system when the app is minimized.
How can I make the app listen to system keyboard events so I can detect the key press accordingly?
Thank you.
I took a look at the source for Ideogram to see how it registers Super-e as a hot-key. It looks to be basically the following, including first checking that a custom hot-key has not already been registered for the application.
// These constants are set at class level.
public const string SHORTCUT = "<Super>e";
public const string ID = "com.github.cassidyjames.ideogram";
// Set shortcut within activate method.
CustomShortcutSettings.init ();
bool has_shortcut = false;
foreach (var shortcut in CustomShortcutSettings.list_custom_shortcuts ()) {
if (shortcut.command == ID) {
has_shortcut = true;
return;
}
}
if (!has_shortcut) {
var shortcut = CustomShortcutSettings.create_shortcut ();
if (shortcut != null) {
CustomShortcutSettings.edit_shortcut (shortcut, SHORTCUT);
CustomShortcutSettings.edit_command (shortcut, ID);
}
}
It uses a CustomShortcutSettings class included in its source to handle the reading and writing to the system settings. The class originated in another application called Clipped.

JavaFX: Capture screen focused event

Is there a way to capture the event when a stage or screen gets focus? I tried to use focusedProperty but I guess that is used only when initially the stage/screen gets shown.
I am not sure if essentially I have to capture, WindowEvent.WINDOW_SHOWN event. I did try the following piece of code in my application, but there is probably a mistake.
stage.addEventFilter(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>()
{
#Override
public void handle(WindowEvent window)
{
System.out.println("EventFilter :: Window shown");
}
});
stage.addEventHandler(WindowEvent.WINDOW_SHOWN, new EventHandler<WindowEvent>()
{
#Override
public void handle(WindowEvent window)
{
System.out.println("EventHandler :: Window shown");
}
});
None of the sysouts is shown when I execute the program.
Another part to the same problem is whether the event handler would get triggered if lets say I minimize and maximize the application(i.e the application again got focus) or I lock my machine and unlock it?

Making Ctrl-C copy from whichever SourceViewer has focus in Eclipse plug-in

I successfully extended the PyDev editor in Eclipse with a side-by-side display, but I can't copy the contents of the extra SourceViewer that I added. I can select some text in the display, but when I press Ctrl+C, it always copies the main PyDev editor's selected text.
I found an article on key bindings in Eclipse editors, but the code there seems incomplete and a bit out-of-date. How can I configure the copy command to copy from whichever SourceViewer has focus?
The reason I want to do this is that I've written a tool for live coding in Python, and it would be much easier for users to submit bug reports if they could just copy the display and paste it into the bug description.
David Green's article was a good start, but it took a bit of digging to make it all work. I published a full example project on GitHub, and I'll post a couple of snippets here.
The TextViewerSupport class wires up a new action handler for each command you want to delegate to the extra text viewer. If you have multiple text viewers, just instantiate a TextViewerSupport object for each of them. It wires up everything in its constructor.
public TextViewerSupport(TextViewer textViewer) {
this.textViewer = textViewer;
StyledText textWidget = textViewer.getTextWidget();
textWidget.addFocusListener(this);
textWidget.addDisposeListener(this);
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
handlerService = (IHandlerService) window
.getService(IHandlerService.class);
if (textViewer.getTextWidget().isFocusControl()) {
activateContext();
}
}
The activateContext() method has a list of all the commands you want to delegate, and registers a new handler for each one. This was one of the changes from David's article; his ITextEditorActionDefinitionIds has been deprecated and replaced with IWorkbenchCommandConstants.
protected void activateContext() {
if (handlerActivations.isEmpty()) {
activateHandler(ITextOperationTarget.COPY,
IWorkbenchCommandConstants.EDIT_COPY);
}
}
// Add a single handler.
protected void activateHandler(int operation, String actionDefinitionId) {
StyledText textWidget = textViewer.getTextWidget();
IHandler actionHandler = createActionHandler(operation,
actionDefinitionId);
IHandlerActivation handlerActivation = handlerService.activateHandler(
actionDefinitionId, actionHandler,
new ActiveFocusControlExpression(textWidget));
handlerActivations.add(handlerActivation);
}
// Create a handler that delegates to the text viewer.
private IHandler createActionHandler(final int operation,
String actionDefinitionId) {
Action action = new Action() {
#Override
public void run() {
if (textViewer.canDoOperation(operation)) {
textViewer.doOperation(operation);
}
}
};
action.setActionDefinitionId(actionDefinitionId);
return new ActionHandler(action);
}
The ActiveFocusControlExpression gives the new handler a high enough priority that it will replace the standard handler, and it's almost identical to David's version. However, to get it to compile, I had to add extra dependencies to my plug-in manifest: I imported packages org.eclipse.core.expressions and org.eclipse.ui.texteditor.

Cancel a close event

I have an editor in Eclipse. When the user chooses to close it, a dialog shall appear with several options. One of them is "Cancel" and should cancel the close event. How can I do that?
The partial code I have so far:
...
IEditorPart openEditor = page.openEditor(input, CS_STRINGEDITOR_ID);
openEditor.getEditorSite().getPage()
.addPartListener(new IPartListener() {
public void partOpened(IWorkbenchPart part) {}
public void partDeactivated(IWorkbenchPart part) {}
public void partClosed(IWorkbenchPart part) {
Shell sh = new Shell(cv.getViewSite().getShell());
// My MessageDialog with the options, one being "cancel"
CloseDialog closeDialog = new CloseDialog(sh);
closeDialog.open();
int returnCode = closeDialog.getReturnCode();
switch (returnCode) {
case CloseDialog.CANCEL_ID:
// Abort the close event and keep the editor alive
break;
}
}
This thread points out there is no closing event per se.
Eclipse provides mostly post-activite events, i.e. on IPartListener2, partClosed(*) is a
post-closing event.
You can provide your own dialog on close, but it will only be shown if the
editor is dirty at the time it is closed. See ISaveablePart2.promptToSaveOnClose()
(as presented in the Prevent that a RCP Editor is closed)
However, note that implementing ISaveablePart2 may lead to many dialogs being opened when you close multiple editors.

Can't hit breakpoints for user generated actions when debugging jython code with PyDev in Eclipse

I'm implementing a GUI application in Jython, using Eclipse and PyDev plugin.
The problem is that I have a hard time using the builtin debugger. When I start a debug session it just stops. Of course this should be expected as the program just creates a JFrame and then it's finished.
So any breakpoints I put for different events .e.g. pressing a button, will never happen as the debug session is already terminated.
What should I do ? I'm growing tired of using prints for all my debugging.
For instance, when I tried debugging this small Java example. I have no problem to hit
the breakpoint I had set in the windowClosing-method
import java.awt.event.*;
import javax.swing.*;
public class Test1 {
public static void main(String s[]) {
JFrame frame = new JFrame("JFrame Source Demo");
// Add a window listner for close button
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
}
}
And then I tried this somewhat more or less similiar example in jython
from javax.swing import JFrame;
import java.awt.event.WindowListener as WindowListener
class Test1 (JFrame, WindowListener):
def __init__(self):
super(JFrame, self).__init__('Some name goes here', defaultCloseOperation = JFrame.EXIT_ON_CLOSE, size = (800, 800))
self.addWindowListener(self)
self.setVisible(True)
def windowClosing(self, windowEvent):
print 'window closing'
pass # want to hit this breakpoint
someFrame = Test1()
pass #breakpoint here maybe
If I tried to run the jython example in the debugger and it just terminates. Ok then I added a breakpoint after I created someFrame and a breakpoint in the windowClosing method. Still no luck, It doesn't get hit when I close the window but I see it executed as I see the printout.
Can anyone tell me what I'm doing wrong ? I'm sure I forgot something very simple.
Put a breakpoint in the first line of your main method that initiates the application.
If you want to debug certain actions like pressing a button add an action listener to a button and inside the handling method add the breakpoint. For example:
JButton button = new JButton("OK");
button.addActionListener(new ActionListener()
{
#Override
public void action(ActionEvent e)
{
System.out.println("button OK has been pressed"; // add breakpoint here
// call to some code that handles the event
}
});
I had the same problem
btnCompilar = new JButton("Compilar");
btnCompilar.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
compile(); //can't hit breakpoint here
}
});
I couldn't hit breakpoints inside actionPerformed, so I just made a method and used breakpoints in it.
void compile(){
//can hit breakpoint here
}