Stacking modal dialogs in SWT - java

I've a problem stacking dialog windows in pure SWT.
It's a little bit complicated to describe it but I try it: I have a starter class which builds the main application window. From the main window I open a first modal dialog by clicking a button. And from this first dialog I open a second dialog which is a modal window again. This second dialog contains only one label and no other components.
The use case is to have the main GUI and a first dialog in which the user can manage menu shortcuts. For this purpose the window contains for example a dorpdown list with the existing shortcuts and a button to change a selected one. By clicking this button the second window is opened in which the user will prompt for pressing the new keys.
My code looks like this:
public class Runner {
public static void main(String[] args) {
Display display = new Display();
MainWindow app = new MainWindow(display);
app.open();
display.dispose();
}
}
public class MainWindow {
private Display display;
private Shell shell;
public MainWindow(Display display) {
this.display = display;
createContents();
}
public void open() {
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
private void createContents() {
shell = new Shell(display);
shell.setLayout(new FillLayout());
Button button = new Button(shell, SWT.PUSH);
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
showFirstWindow();
}
});
}
private void showFirstWindow() {
FirstWindow firstWindow = new FirstWindow(shell);
firstWindow.open();
}
}
public class FirstWindow extends Dialog {
private Display display;
private Shell shell;
public FirstWindow(Shell parent) {
super(parent, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
display = parent.getDisplay();
createContents();
}
public void open() {
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
private void createContents() {
shell = new Shell(getParent(), getStyle());
shell.setLayout(new FillLayout());
Button button = new Button(shell, SWT.PUSH);
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
showSecondWindow();
}
});
}
private void showSecondWindow() {
SecondWindow secondWindow = new SecondWindow(shell);
secondWindow.open();
}
}
public class SecondWindow extends Dialog {
private Display display;
private Shell shell;
private Label label;
public SecondWindow(Shell parent) {
super(parent, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
display = parent.getDisplay();
createContents();
}
public void open() {
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
private void createContents() {
shell = new Shell(getParent(), getStyle());
label = new Label(shell, SWT.NONE);
label.setLocation(10, 10);
label.setSize(200, 13);
label.setText("prompt text");
}
}
Under Windows this construct works fine but under Mac OS X the second dialog is invisible. It's interesting that the KeyPressedHandler is triggered but the window and thus the prompt message is not shown.
Is it not possible to overlay a few dialogs in OS X or is it a bug of SWT or is it a problem in my code? I can't figure out the reason.

Related

How to close all open dialogs of a given SWT shell?

My program opens a dialog (on a given shell):
new FileDialog(shell).open();
My Question is: How can I (in another part of my program) close all open dialogs of a given
shell?
private void closeDialogs(Shell shell) {
// how to close open dialogs?
}
Below is minimal test case, one button opens the dialogs. The other button should
close all open dialogs of the current shell.
public static void main(final String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("Testcase");
shell.setLayout(new FillLayout());
final Button button = new Button(shell, SWT.PUSH);
button.setText("Open Dialog");
button.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
new NonModalDialog(shell).open();
}
});
Button button2 = new Button(shell, SWT.PUSH);
button2.setText("Close open dialogs");
button2.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
// How to close all open dialogs of the given shell?
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
You will have to collect the dialogs in a list as you open them.
When the "close" button is clicked, walk through the list and close the dialogs.
Note: This will not work when any of the dialogs are modal. A modal dialog will take over the event loop and ignore any events that aren't directed at itself, so clicking on the button will be impossible.

Styled Text setText have bad perfomance

I have little problem with StyledText. When I use setText() Method and text is long, I must wait few seconds for render that text. Is there any method what can I use to speed up showing this text?
The only optimisation you can implement is putting your setText() in a Job or in a Runnable to not block the UI.
Other than that, it's an API limitation from SWT.
Other suggestions:
File a bug/feature request
Search for a StyledText, although apparently none exist
Rethink your program. Don't you have a backup plan? Is the performance critical?
Edit:
#greg-449
/**
*
* #author ggrec
*
*/
public class Test
{
public static void main(final String[] args)
{
new Test();
}
private Test()
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout(1, false));
final Button button = new Button(shell, SWT.PUSH);
button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
button.setText("Press me");
final StyledText text = new StyledText(shell, SWT.NONE);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
button.addSelectionListener(new SelectionAdapter()
{
#Override public void widgetSelected(final SelectionEvent e)
{
Display.getDefault().asyncExec(new Runnable()
{
#Override public void run()
{
text.setText("*put very long text here*");
}
});
}
});
shell.setSize(1000, 1000);
shell.open();
while (!shell.isDisposed())
{
if ( !display.readAndDispatch() )
display.sleep();
}
display.dispose();
}
}

How can i expand a textfield when it's in focus and when it's out of focus it should collapse?

I want to use a text field which will expand when the user enters some data and when the user is done editing and move out of text field than it should collapse. After that when ever user focus on the text field it should expand like a tooltip. Any pointer regarding this will help me.
This code should give you an idea of how to do it:
public static void main(String[] args)
{
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout(1, false));
final Text text = new Text(shell, SWT.BORDER | SWT.MULTI);
text.setText("edasdasdas\n\nasdasda\n\nasdasd");
final GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
data.heightHint = 100;
text.setLayoutData(data);
text.addListener(SWT.FocusIn, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
data.heightHint = 100;
shell.layout(true);
}
});
text.addListener(SWT.FocusOut, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
data.heightHint = 50;
shell.layout(true);
}
});
Button button = new Button(shell, SWT.PUSH);
button.setText("Button");
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
It basically changes the heightHint of the GridData when focus is lost/gained. Afterwards you need to re-layout the parent.
You will have to make some adjustments for the "focused height" and "unfocused height" values yourself.
Here are some screenshots:
With focus:
Without focus:
Just press the Button to lose focus.
Just add a FocusListener to your text field:
text.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
text.setSize(); // put in the size you want
}
#Override
public void focusLost(FocusEvent e) {
text.setSize(); // put in the size you want
}
});
Note that for setSize to work properly, parent of text can't have a layout.

SWT Tray Item in gnome

I have an issue about the tray items display in Gnome Shell.
The item icon appears in the lower bar, and I'm fine with that, and just like the other ones, when moving the mouse over the icon, a text is displayed.
My problem is that this text cannot be changed: setting a text with .setText does not work, neither the class support any event, but Selected and MenuDetect, which detect the left and right click, respectively.
Has anybody experienced the same problem?
Thanks a lot in advance for your answers,
Gianluca
Not quite sure what problem you are facing, but this works for me:
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Tray tray = display.getSystemTray();
TrayItem item;
if (tray != null) {
item = new TrayItem(tray, SWT.NONE);
item.setToolTipText("A");
item.setImage(display.getSystemImage(SWT.ICON_ERROR));
}
Button button = new Button(shell, SWT.PUSH);
button.setText("Change tray text");
button.addListener(SWT.Selection, new Listener() {
#Override
public void handleEvent(Event arg0) {
if(tray != null)
{
TrayItem item = tray.getItem(0);
item.setToolTipText(item.getToolTipText() + "A");
}
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
Note that I don't use setText(), but rather setToolTipText().

any way to determine the event like mouse click for title bar in eclipse Application

i am using eclipse rcp and swt for developing application.i have a list and i need to set its visibility false on a movement of title bar or when user click a titleBar. i am unable to find any event of titleBar. Is there any event of titleBar so that i can solve my problem? Or any thing that could probably solve my problem? i searched but could find for flex only as
function panelClick ( event:MouseEvent ) : void
{
trace( event.localX + '/' + event.localY );
}
is there same thing for swt using eclispe.
thanks in advance.
The following code will output "Move" and "Minimize" when the corresponding events happen:
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Button dummy = new Button(shell, SWT.PUSH);
dummy.setText("Dummy");
shell.addListener(SWT.Move, new Listener() {
#Override
public void handleEvent(Event arg0) {
System.out.println("Move");
}
});
shell.addListener(SWT.Iconify, new Listener() {
#Override
public void handleEvent(Event arg0) {
System.out.println("Minimize");
}
});
shell.pack();
shell.setSize(400, 300);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
However, the SWT.MOVE event is only fired after the shell has been moved, i.e. when the "move" is over.

Categories