I have a JFace dialog and a toggle button( whose text is either "freeze" or "unfreeze") in the button bar.
Initially i select an object and click on a menu item to open the dialog.
From then on, whenever I click on toggle button(when text on it is "unfreeze") the dialog should close and reopen.
How do i achieve this ?
This should give you an idea how to do it (quick hack):
private static MyDialog dialog;
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Button openDialog = new Button(shell, SWT.TOGGLE);
openDialog.setText("Toggle dialog");
openDialog.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
if (openDialog.getSelection())
{
if (dialog == null)
{
dialog = new MyDialog(new Shell(display));
dialog.open();
}
if(dialog.getShell() != null && !dialog.getShell().isDisposed())
dialog.getShell().setVisible(openDialog.getSelection());
}
else
{
if (dialog != null && dialog.getShell() != null && !dialog.getShell().isDisposed())
dialog.getShell().setVisible(openDialog.getSelection());
}
}
});
shell.open();
shell.pack();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
}
private static class MyDialog extends Dialog
{
public MyDialog(Shell parentShell)
{
super(parentShell);
setShellStyle(SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE);
}
#Override
protected Control createDialogArea(Composite parent)
{
Composite container = (Composite) super.createDialogArea(parent);
Text text = new Text(container, SWT.BORDER);
return container;
}
#Override
protected void configureShell(Shell newShell)
{
super.configureShell(newShell);
newShell.setText("Some dialog");
}
#Override
protected Point getInitialSize()
{
return new Point(450, 300);
}
}
It will create and open the dialog on first press of the button and hide/unhide in on consequent press events (using Shell#setVisible(boolean)).
If this is not what you had in mind, please update your question or post a comment.
Related
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I am trying to create a shell in java swt application as dialog Shell. There is two button 'Accept' and 'Decline'. I want if user does not click any button during 30sec then shell will be disposed automatically. for this I am trying following code but its not working.Please help me Using any idea or suggestion
public class ServiceRequestDialog extends Dialog {
public ServiceRequestDialog(Shell parent,String nameofrequestor) {
// Pass the default styles here
this(parent,SWT.NO_TRIM|SWT.ON_TOP|SWT.DIALOG_TRIM|SWT.APPLICATION_MODAL);
this.parent=parent;
nameofRequester=nameofrequestor;
}
public ServiceRequestDialog(Shell parent, int style) {
// Let users override the default styles
super(parent, style);
}
public Shell open() {
shell = new Shell(getParent(), getStyle());
shell.setText(getText());
shell.setLocation(parent.getLocation().x+190, parent.getLocation().y+215);
shell.setSize(279, 181);
shell.setLayout(new FormLayout());
......
shell.open();
Display display = getParent().getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
// Return the entered value, or null
try {
System.out.println("Thread Sleep");
Thread.sleep(15000);
dispose();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return shell;
}
public void dispose(){
try {
if (shell != null) {
if (shell.isDisposed()==false) {
shell.dispose();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
I implemented something myself which should give you a starting point. It basically opens a JFace Dialog when you press the Button. This Dialog will close itself after a specified number of seconds (5 in the example):
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
shell.setText("StackOverflow");
Button button = new Button(shell, SWT.PUSH);
button.setText("Open dialog");
button.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
new MyDialog(shell, 5).open();
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static class MyDialog extends Dialog
{
private int counter = 0;
private int maxSeconds;
public MyDialog(Shell parentShell, int maxSeconds)
{
super(parentShell);
this.maxSeconds = maxSeconds;
setShellStyle(SWT.APPLICATION_MODAL | SWT.CLOSE);
setBlockOnOpen(true);
}
#Override
protected Control createDialogArea(Composite parent)
{
Composite composite = (Composite) super.createDialogArea(parent);
composite.setLayout(new GridLayout(1, false));
final Display display = composite.getShell().getDisplay();
final Label label = new Label(composite, SWT.NONE);
label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
/* Set up the timer here */
final Runnable timer = new Runnable()
{
public void run()
{
if(!label.isDisposed())
{
label.setText("" + counter++);
label.pack();
if(counter <= maxSeconds)
display.timerExec(1000, this);
else
MyDialog.this.close();
}
}
};
/* And start it */
display.timerExec(0, timer);
return composite;
}
#Override
protected void configureShell(Shell newShell)
{
super.configureShell(newShell);
newShell.setText("Dialog");
}
}
When the content of a the Text exceeds the width of the Text, I want to show dots (...) at the end of the text field.
I have tried to using a ModifyListener without success. Any help regarding this would be much appreciated.
#Override
public void modifyText(ModifyEvent e) {
// TODO Auto-generated method stub
if (wakeupPatternText.getText().length()>=12) {
String wakeuppattern=wakeupPatternText.getText(0, 11);
String dot="...";
String wakeup=wakeuppattern+dot;
wakeupPatternText.setText(wakeup);
}
}
});
This should do what you want:
private static String textContent = "";
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout(SWT.VERTICAL));
Text text = new Text(shell, SWT.BORDER);
text.addListener(SWT.FocusOut, new Listener()
{
#Override
public void handleEvent(Event e)
{
Text text = (Text) e.widget;
textContent = text.getText();
text.setText(textContent.substring(0, Math.min(10, textContent.length())) + "...");
}
});
text.addListener(SWT.FocusIn, new Listener()
{
#Override
public void handleEvent(Event e)
{
Text text = (Text) e.widget;
text.setText(textContent);
}
});
Button button = new Button(shell, SWT.PUSH);
button.setText("Lose focus");
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
It listens to focus events and truncates the visible String if it is too long.
This is how it looks:
With focus:
Without focus:
The reason why your code isn't working is the following: When you call wakeupPatternText.setText(wakeup); from within the VerifyListener the listener itself is called again recursively.
When I have a operation running in the back ground, I am setting my cursor to busy until the process completes. Is there a way to also grey out and disable the current Display/Dialog/Shell until the process completes. I want to visually let the user know that something is working and they have to wait.
EDIT
plotButton.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event arg0) {
getShell().setEnabled(!getShell().getEnabled());
getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_WAIT));
recursiveSetEnabled(getShell(), getShell().getEnabled());
startPrinterListOperation(); <== This is method that runs operation
}
});
Method that runs a printer operation.
private void startPrinterListOperation() {
listOp = new AplotPrinterListOperation(appReg.getString("aplot.message.GETPRINTERLIST"), session);
listOp.addOperationListener(new MyOperationListener(this) {
public void endOperationImpl() {
try {
printers.clear();
printers.addAll((ArrayList<PrinterProfile>) listOp.getPrinters());
Display.getDefault().asyncExec(new Runnable() {
public void run() {
showAplotPlotterDialog(); <== When operation returns - opens selection dialog
}
});
}
finally {
listOp.removeOperationListener(this);
listOp = null;
}
}
});
session.queueOperation(listOp);
} // end startPrinterListOperation()
showAplotPlotterDialog() (Seperate Class) opens a dialog with network printers, then with a button push sends a job to the selected printer. When that operation finishes the Plotter Dialog closes - This is the end of that method - baseDialog is the MAIN GUI
finally {
plotOp.removeOperationListener(this);
plotOp = null;
Display.getDefault().asyncExec(new Runnable() {
public void run() {
baseDialog.removeAllTableRows();
baseDialog.plotRequestCompleted = true;
baseDialog.setResultsButtonVisibility();
getShell().close();
}
});
}
The following should do what you want. It will recursively disable and grey out all the Controls in your Shell. The Shell itself does not have a setGrayed method, but this will work:
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Button button = new Button(shell, SWT.PUSH);
button.setText("Button");
button.addListener(SWT.Selection, new Listener() {
#Override
public void handleEvent(Event arg0) {
shell.setEnabled(!shell.getEnabled());
shell.setCursor(new Cursor(display, SWT.CURSOR_WAIT));
recursiveSetEnabled(shell, shell.getEnabled());
}
});
new Text(shell, SWT.NONE).setText("TEXT");
shell.setSize(400, 400);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private static void recursiveSetEnabled(Control control, boolean enabled) {
if (control instanceof Composite)
{
Composite comp = (Composite) control;
for (Control c : comp.getChildren())
recursiveSetEnabled(c, enabled);
}
else
{
control.setEnabled(enabled);
}
}
Use
BusyIndicator.showWhile(Display.getDefault(), new Runnable()
{
public void run()
{
//operation
}
});
It sets the busy cursor on all Shells (Window, Dialog, ...) for the current Display until the Runnable.run() is executed.
Baz's answer was a great start for me, but doesn't act on Combo since it extends Composite. By making the call to setEnabled unconditional, every Control (including Combo) are enabled/disabled correctly.
private static void recursiveSetEnabled(Control control, boolean enabled) {
if (control instanceof Composite)
{
Composite comp = (Composite) control;
for (Control c : comp.getChildren())
recursiveSetEnabled(c, enabled);
}
control.setEnabled(enabled);
}
I am working with SWT JFace dialog.
I added a listener to the OK button, I want to display a message box once the user clicks on the OK button.
The problem in this step is that when I once click on the OK button the shell gets disposed. How I can prevent this behavior?
The following code will prevent the dialog from beeing closed via the "OK" button. Just don't call this.close() in the okPressed() method:
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
new OptionsDialog(shell).open();
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private static class OptionsDialog extends Dialog {
private Composite composite;
public OptionsDialog(Shell parentShell)
{
super(parentShell);
setShellStyle(parentShell.getStyle() | SWT.CLOSE | SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL);
setBlockOnOpen(true);
}
protected Control createDialogArea(Composite parent) {
this.composite = (Composite) super.createDialogArea(parent);
GridLayout layout = new GridLayout(1, false);
layout.marginHeight = 5;
layout.marginWidth = 10;
composite.setLayout(layout);
createContent();
return composite;
}
private void createContent()
{
/* add your widgets */
}
protected void configureShell(Shell newShell)
{
super.configureShell(newShell);
newShell.setText("Shell name");
}
public void okPressed()
{
/* DO NOTHING HERE!!! */
//this.close();
}
}
Group group = new Group(parent, SWT.NONE);
StyledText comment = new StyledText(group, SWT.BORDER_DASH);
This creates a group with a text area inside.
How can I later delete the text (remove it from the screen so that I can replace it with something else)?
Use Widget.dispose.
public class DisposeDemo {
private static void addControls(final Shell shell) {
shell.setLayout(new GridLayout());
Button button = new Button(shell, SWT.PUSH);
button.setText("Click to remove all controls from shell");
button.addSelectionListener(new SelectionListener() {
#Override public void widgetDefaultSelected(SelectionEvent event) {}
#Override public void widgetSelected(SelectionEvent event) {
for (Control kid : shell.getChildren()) {
kid.dispose();
}
}
});
for (int i = 0; i < 5; i++) {
Label label = new Label(shell, SWT.NONE);
label.setText("Hello, World!");
}
shell.pack();
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
addControls(shell);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Another option is to use a StackLayout to switch between underlying controls. This prevents you from running into a "widget is disposed" error.
You have to either call comment.changeParent(newParent) or comment.setVisible(false) to remove/hide it from the Group. I am unsure if comment.changeParent(null) would work but I would give that a try.
We do it this way because SWT uses the Composite Pattern.
group.getChildren()[0].dispose() will remove the first child. You need to find a way to identify the precise child you want to delete. It could be comparing the id. You can do that by using the setData / getData on that control:
For example:
StyledText comment = new StyledText(group, SWT.BORDER_DASH);
comment.setData("ID","commentEditBox");
and then:
for (Control ctrl : group.getChildren()) {
if (control.getData("ID").equals("commentEditBox")) {
ctrl.dispose();
break;
}
}