how to catch event of change focus of row in tableViewer? - java

I created a tableViewer.
The tableViewer could be update.
The update of the table is in inline mode meaning in change of row Ii will update the table.
The problem that if I changed the focus to different view ( outline , tasks... ) or to different windows I want to catch the event that the focus of the table was changed.( the row still mark and this is the reason that the selectionChanegd event is not trigger )
This is the event that for the selectionChanged
gridController.addSelectionChangedListener(new ISelectionChangedListener() {
.. do update
}
The event is not trigger when I changed the focus to different window,view.
Do you know on different way to catch the change of the focus of the table ?

Try this :
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class TestCase {
private static List<String> model = new ArrayList<String>();
private static TableViewer viewer;
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
// viewer = new TableViewer(shell, SWT.SINGLE | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL);
viewer = new TableViewer(shell, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL);
viewer.getTable().setHeaderVisible(true);
viewer.getTable().setLinesVisible(true);
viewer.setUseHashlookup(true);
viewer.setContentProvider(ArrayContentProvider.getInstance());
viewer.setLabelProvider(new LabelProvider());
model.add("element2");
model.add("element1");
model.add("element0");
viewer.setInput(model);
viewer.setSelection(new StructuredSelection(model.get(1)));
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
#Override
public void selectionChanged(SelectionChangedEvent event) {
System.out.println("selection changed");
}
});
addContent();
shell.setSize(400, 400);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
private static void addContent() {
Display.getCurrent().timerExec(2000, new Runnable() {
#Override
public void run() {
model.add(0, "element" + model.size());
viewer.refresh();
addContent();
}
});
}
}

Related

Eclipse SWT: Can't scroll over Text when vertical scrolling is enabled

I have a Text inside a Group, which is inside a Composite and that resides inside a ScrolledComposite. All Elements are inside an EditorPart.
ScrolledComposite mySc
|- Composite myComposite
|- Group myGroup
|- Text myText
I can scroll (using the mouse wheel) over all Elements in the EditorPart, but when the cursor is over the Text area, the scrolling stops.
I want to scroll inside the Text only when it has keyboard focus.
Instantiation of the Text myText:
myText = new Text(myGroup, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
Without SWT.V_SCROLL it works, but then I don't have scroll bars and the possibility to scroll in the Text.
I thought I could maybe use forceFocus() on the parent in case the Text has no Focus Control:
myText.addListener(SWT.MouseWheel, new Listener() {
#Override
public void handleEvent(Event event) {
if (!commandText.isFocusControl()) {
System.out.println("no focus");
Control wheelControl = myText.getParent();
Point cursorPos = wheelControl.toControl(event.display.getCursorLocation());
event.x = cursorPos.x;
event.y = cursorPos.y;
event.widget = wheelControl;
wheelControl.forceFocus();
wheelControl.notifyListeners(SWT.MouseWheel, event);
} else {
System.out.println("Focus control");
}
}
});
But it doesn't work. No change at all. It only prints "Focus control" and "no focus" correctly.
EDIT:
Here is a minimal working example:
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
public class MyEditor extends EditorPart {
private Text myText;
private boolean dirty = false;
public MyEditor() {
super();
}
#Override
public void init(IEditorSite site, IEditorInput input) {
setSite(site);
setInput(input);
}
#Override
public void doSave(IProgressMonitor monitor) {
return;
}
#Override
public void doSaveAs() {
return;
}
#Override
public boolean isDirty() {
return dirty;
}
#Override
public boolean isSaveAsAllowed() {
return false;
}
#Override
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout());
ScrolledComposite mySc = new ScrolledComposite(parent, SWT.V_SCROLL);
Composite myComposite = new Composite(mySc, SWT.BORDER);
myComposite.setLayout(new GridLayout(1, false));
// Set the child as the scrolled content of the ScrolledComposite
mySc.setContent(myComposite);
// Expand both horizontally and vertically
mySc.setExpandHorizontal(true);
mySc.setExpandVertical(true);
Group myGroup = new Group(myComposite, SWT.NONE);
myGroup.setText("Hello or something");
myGroup.setLayout(new GridLayout(1, false));
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.verticalIndent = 10;
myGroup.setLayoutData(gd);
Label aLabel = new Label(myGroup, SWT.NONE);
aLabel.setText("You can write here: ");
myText = new Text(myGroup, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
myText.setText("Some Default Text");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.heightHint = 300;
gd.horizontalIndent = 10;
myText.setLayoutData(gd);
myText.addListener(SWT.MouseWheel, new Listener() {
#Override
public void handleEvent(Event event) {
if (!myText.isFocusControl() ) {
System.out.println("no focus");
Control wheelControl = myText.getParent();
Point cursorPos = wheelControl.toControl(event.display.getCursorLocation());
event.x = cursorPos.x;
event.y = cursorPos.y;
event.widget = wheelControl;
wheelControl.forceFocus();
wheelControl.notifyListeners(SWT.MouseWheel, event);
myText.setCapture(false);
} else {
System.out.println("Focus control");
myText.setCapture(true);
}
}
});
mySc.setMinSize(myComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
// TODO Auto-generated method stub
}
#Override
public void setFocus() {
// TODO Auto-generated method stub
}
}
The solution I found was to disable the vertical scrollbar. This also disables scrolling by mouse wheel. Also use SWT's addMouseWheelListener() and mouseScrolled() methods instead of addListener(). Than just scroll the ScrolledComposite by using its getOrigin() method.
myText.addMouseWheelListener(new MouseWheelListener() {
#Override
public void mouseScrolled(MouseEvent e) {
if (!myText.isFocusControl() ) {
myText.getVerticalBar().setEnabled(false);
if (e.count == 3) {
mySc.setOrigin(sc.getOrigin().x, mySc.getOrigin().y - 30);
} else if (e.count == -3) {
mySc.setOrigin(sc.getOrigin().x, mySc.getOrigin().y + 30);
}
} else {
myText.getVerticalBar().setEnabled(true);
}
}
});
count always returns 3 or -3, depending on the scroll direction. The value of 30 for scrolling up/down is good for me, might be more or less for other purposes. I didn't check the behavior on a Windows machine yet.

Overriding Cut/Copy/Paste in SWT Text control

What is the correct way to override the cut(), copy(), and paste() methods of the Text control? What triggers the execution of these methods?
I have created an example application with a custom class that overrides these methods. Unfortunately, nothing seems to execute these overridden methods, including the act of using Ctrl+X / Ctrl+C / Ctrl+V or selecting cut/copy/paste from the context menu.
Custom Text Class:
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
public class TextCopyable extends Text{
public TextCopyable(Composite parent, int style) {
super(parent, style);
}
#Override
public void checkSubclass() {
}
#Override
public void cut() {
System.out.println("Cut!");
}
#Override
public void copy() {
System.out.println("Copy!");
}
#Override
public void paste() {
System.out.println("Paste!");
}
}
Test Shell:
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.layout.GridData;
public class CopyPasteTest extends Shell {
private TextCopyable text;
public static void main(String args[]) {
try {
Display display = Display.getDefault();
CopyPasteTest shell = new CopyPasteTest(display);
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public CopyPasteTest(Display display) {
super(display, SWT.SHELL_TRIM);
createContents();
}
protected void createContents() {
setText("SWT Application");
setSize(450, 300);
GridLayout gridLayout = new GridLayout();
setLayout(gridLayout);
text = new TextCopyable(this, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
}
#Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
}
My expectation was that the copy() method would be called any time that I use the Ctrl+C command to copy text from the textbox. However, the methods do not trigger at all. Is my assumption faulty?

Opening one shell each time

In my project i have a shell, in the shell there are 3 buttons, i want that a click on each button will open a shell ,but i want that if a shell is already open due to a click on a button then that shell will be closed and a new shell will be opened.
(I dont want 2 shell from clicking buttons to be open at the same time)
But i have no idea how to do this.
In this class the opening of the shells should be.
public class ClickLabel implements MouseListener
{
Shell shell;
int p;
public ClickLabel(int p)
{
shell = new Shell();
this.p = p;
}
#Override
public void mouseDoubleClick(MouseEvent e) {}
#Override
public void mouseDown(MouseEvent e) {}
#Override
public void mouseUp(MouseEvent e) {
shell.open();
}
}
Can anyone help me?
Here is simple example with buttons and one active Shell, examine that:
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Example{
public static void main(String[] args) {
new Example();
}
private Shell openedShell;
public Example() {
final Display display = new Display ();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
SelectionAdapter adapter = new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
if(openedShell != null){
openedShell.dispose();
}
openedShell = new Shell(display);
openedShell.setSize(200,200);
openedShell.setText(((Button)e.getSource()).getText());
openedShell.open();
}
};
for(int i =1;i<4;i++){
Button b = new Button(shell, SWT.PUSH);
b.setText("shell "+i);
b.addSelectionListener(adapter);
b.pack();
}
shell.pack();
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}

Show Page loading no browser until page is fully loaded

I want to hide the content of html page until its fully loaded. The idea is I want to get the content of html page do some processing and set the content back again. For doing so I am able to retrieve the text and do some processing on it. But the problem is , till the time processing is not complete, I want to hide the original html page and instead wanna show some dummy page.
I want to hover a shell on browser window and remove it when the loading is complete. I tried to hide the browser widget but that is not working as per the expectations.
Here is the snippet for the same.
package browserapp;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.extended.LocationEvent;
import org.eclipse.swt.browser.extended.LocationListener;
import org.eclipse.swt.browser.extended.ProgressEvent;
import org.eclipse.swt.browser.extended.ProgressListener;
import org.eclipse.swt.browser.extended.Browser;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class MyBrowser_1 {
/**
* Runs the application
*/
Display display = new Display();
protected boolean done;
public void run() {
final Shell shell = new Shell(display);
shell.setText("Simple Browser");
createContents(shell);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
/**
* Creates the main window's contents
*
* #param shell the main window
*/
private void createContents(final Shell shell) {
shell.setLayout(new FormLayout());
// Create the composite to hold the buttons and text field
Composite controls = new Composite(shell, SWT.NONE);
FormData data = new FormData();
data.top = new FormAttachment(0, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
controls.setLayoutData(data);
// Create the web browser
final Browser browser = new Browser(shell, SWT.NONE);
browser.addLocationListener(new LocationListener() {
#Override
public void changing(LocationEvent event) {
// TODO Auto-generated method stub
//browser.setVisible(false);
Image image = new Image(display,
"C:\\Documents and Settings\\My
Documents\\Pictures\\loadingAnimation.gif");
///shell.setBackgroundImage(image);
}
#Override
public void changed(LocationEvent event) {
// TODO Auto-generated method stub
}
});
browser.addProgressListener(new ProgressListener()
{
public void completed(ProgressEvent event)
{
}
public void changed(ProgressEvent event)
{
int progressWorked=0;
if (event.total == 0)
return;
done = (event.current == event.total);
int percentProgress = event.current * 100 / event.total;
System.out.println("Loading...");
if (done)
{
progressWorked = 0;
System.out.println("Loading completed...");
//browser.setVisible(true);
//maskPage(browser, maskedMap);
} else if (progressWorked == 0)
{
progressWorked = percentProgress;
} else
{
progressWorked = event.current;
}
}
});
data = new FormData();
data.top = new FormAttachment(controls);
data.bottom = new FormAttachment(100, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
browser.setLayoutData(data);
// Create the controls and wire them to the browser
controls.setLayout(new GridLayout(7, false));
// Create the back button
Button button = new Button(controls, SWT.PUSH);
button.setText("Back");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.back();
}
});
// Create the forward button
button = new Button(controls, SWT.PUSH);
button.setText("Forward");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.forward();
}
});
// Create the refresh button
button = new Button(controls, SWT.PUSH);
button.setText("Refresh");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.refresh();
}
});
// Create the stop button
button = new Button(controls, SWT.PUSH);
button.setText("Stop");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.stop();
}
});
// Create the address entry field and set focus to it
final Text url = new Text(controls, SWT.BORDER);
url.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
url.setText("https://netbanking.hdfcbank.com/netbanking/");
url.setFocus();
// Create the go button
button = new Button(controls, SWT.PUSH);
button.setText("Go");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.setUrl(url.getText());
}
});
GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, true, false);
Label status = new Label(controls, SWT.BORDER);
status.setLayoutData(gridData2);
// Allow users to hit enter to go to the typed URL
shell.setDefaultButton(button);
}
/**
* The application entry point
*
* #param args the command line arguments
*/
public static void main(String[] args) {
MyBrowser_1 browser=new MyBrowser_1();
browser.run();
}
}

Disable close button in java JFace dialog?

How can i disable the close button (or make it disappear completely if possible) in a java JFace dialog?
Buttons in a Dialog are created with the method createButton(). To "filter out" the cancel button, you can override it as follows:
protected Button createButton(Composite parent, int id,
String label, boolean defaultButton) {
if (id == IDialogConstants.CANCEL_ID) return null;
return super.createButton(parent, id, label, defaultButton);
}
However, the Dialog's close button (provided by the OS) still works. To disable it, you can override canHandleShellCloseEvent():
protected boolean canHandleShellCloseEvent() {
return false;
}
Here is a complete, minimal example:
package stackoverflow;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class JFaceDialogNoCloseButton {
private static final Display DISPLAY = Display.getDefault();
public static void main(String[] args) {
Shell shell = new Shell(DISPLAY, SWT.CLOSE | SWT.RESIZE);
shell.setSize(200, 100);
shell.setLayout(new FillLayout());
final Dialog dialog = new InputDialog(shell, "Title", "Message",
"initial value", null) {
#Override
protected Button createButton(Composite parent, int id,
String label, boolean defaultButton) {
if (id == IDialogConstants.CANCEL_ID)
return null;
return super.createButton(parent, id, label, defaultButton);
}
#Override
protected boolean canHandleShellCloseEvent() {
return false;
}
};
Button button = new Button(shell, SWT.PUSH);
button.setText("Launch JFace Dialog");
button.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
dialog.open();
}
});
shell.open();
while (!shell.isDisposed()) {
if (!DISPLAY.readAndDispatch()) {
DISPLAY.sleep();
}
}
DISPLAY.dispose();
}
}
To make the X button not visible on a Dialog you have to turn off the SWT.CLOSE style property. Important to note that this has to be done before the dialog is opened, so in the constructor of your dialog would work.
public NoCloseDialog(...){
super(...);
setShellStyle(getShellStyle() & ~SWT.CLOSE);
}
The default shell style on a JFace Window is SWT.SHELL_TRIM which is equal to SWT.CLOSE | SWT.TITLE | SWT.MIN | SWT.MAX | SWT.RESIZE
See here for an example showing how to hide the close button in a Dialog. You simply override following method:
protected void setShellStyle(int arg0){
//Use the following not to show the default close X button in the title bar
super.setShellStyle(SWT.TITLE);
}
Otherwise override close() and return false to prevent closing.
Update: While the above code "solves" the problem at hand, it doesn't explain a lot, and introduces a nasty bug. Please see Goog's answer, for a way better version.
For a dialog extended from org.eclipse.jface.dialogs.Dialog, overrding canHandleShellCloseEvent did not work for me,
Then closing the entire application worked as a good strategy for my situation, because I had to do the same if the user choose to cancel.
I know this is not the exact answer to the question but can be used as a workaround to handle the situation.
under open() or createContents() method,
shell.addListener(SWT.Close, new Listener() {
public void handleEvent(Event event) {
System.exit(0);
}
});

Categories