I have a small problem trying to figure out how to check if a user presses a button in a custom JOptionPane.
My dialog is based on an inputDialog with custom texts for the YES, NO and CANCEL buttons ("Select", "Cancel", "Open Editor").
I tried searching for a solution, but all I found was questions that used the static JOptionPane functions.
Here is my code I am using for now:
public SelectItemDialog(Component parent) {
super("Please select an item:", YES_NO_CANCEL_OPTION, PLAIN_MESSAGE, Editor.getIcon("bookmark"),
new String[] { "Select", "Cancel", "Open Item Editor" }, "Select"
);
setWantsInput(true);
setSelectionValues(null); // Would replace with an Object array
setInitialSelectionValue(null);
setComponentOrientation(getRootFrame().getComponentOrientation());
JDialog dialog = createDialog(parent, "Select Item");
selectInitialValue();
dialog.setVisible(true);
dialog.dispose();
Object obj = getInputValue();
if(obj instanceof Item) {
this.openEditor = false;
this.item = (Item) obj;
} else {
this.openEditor = (obj.equals( CANCEL_OPTION));
this.item = null;
}
}
The check for CANCEL_OPTION is not working at all, same with UNDEFINED_OPTION.
Any ideas?
Actually I just had to use the Object returned by the JOptionPane itself: getValue(), problem solved!
Related
I created a SWT dialog with this implementation:
public class FindDialog extends Dialog {
private DialogResult result;
private Display display;
private Shell shell;
private Button okayButton;
/*...*/
public FindDialog(Shell parent) {
this(parent, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
}
public FindDialog(Shell parent, int style) {
super(parent, style);
display = getParent().getDisplay();
initUI();
}
public DialogResult open() {
result = DialogResult.Cancel;
shell.open();
while (shell.isVisible()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
return result;
}
private void initUI() {
shell = new Shell(getParent(), getStyle());
shell.addListener(SWT.Close, new ShellClosingHandler());
okayButton = new Button(shell, SWT.PUSH);
okayButton.addListener(SWT.Selection, new ButtonClickedHandler());
/*...*/
}
private class ButtonClickedHandler implements Listener {
public void handleEvent(Event e) {
Button button = (Button)e.widget;
if (button == okayButton) {
result = DialogResult.OK;
shell.close();
}
}
}
private class ShellClosingHandler implements Listener {
public void handleEvent(Event e) {
if (result == DialogResult.OK) {
e.doit = validate();
}
}
private boolean validate() {
/*...*/
}
}
}
There are some more text fields, buttons and checkboxes but I think that it's not important for my question.
The dialog window popups correctly and I can make my changes on the GUI without any problems.
At last I click the ok button and then the following happens:
The SWT.Close event is firing, my validation method is called and depending on the result the dialog is closed or not. That's ok so far.
But shell.close() not only closes the dialog, it also disposes the shell. And exactly here is the problem because
I don't want to rebuild the dialog GUI everytime the open method is called. I create all my dialogs at program startup and then only want to open and close it if needed.
I need some values of the text fields or states of checkboxes after closing the dialog at different positions in the main program. So it seems a good idea to hold a reference of the dialog object and implement some getters to pull out the data. But if the shell is disposed I have no chance to get the information.
If the shell is disposed then I will loose the "state" of the dialog so I have to refill it next time I display the dialog.
So my question: Is there a possibility to prevent the shell from disposing?
Or is there another concept that I overlooked so I don't have to restructure my complete dialog set?
if (button == okayButton) {
result = DialogResult.OK;
shell.setVisible(false);
}
You can use setVisible(false) instead of close
So it will get hide and wont get dispose.
You can get the values of the text box after hide
No need to rebuild again
The past values in the textbox will be there after hide.
I know that in order to prevent JOptionpane from hiding behind any of the frame we have to give the current frame as parent frame to JOptionpane.
I have a JTree with popupmenu
it has popup menu follows
Add
Rename
Delete
when I click the delete menu i'll call the showDeleteConfirmation() to confirm the action to delete or not
But the problem if I use currentMainframe(the one which jtree is present) as parent frame for JOptionpane and when I click the JPopumenu is not hiding(still in focus) so I have to click on Joptionpane once (to hide the popupmenu) and then only I can select the options
If I use null as parentframe it is working perfectly(onclicking the the menuitem it is automatically hiding).
How to solve the issue
//Have to click anywhere on JOptionpane to gain focus(also to hide popupmenu)
public static Boolean showDeleteConfirmation() {
if (deleteConfirmation) {
int value = JOptionPane.showConfirmDialog(currentMainFrame, "Are you sure want to delete?", "Delete", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
return value == JOptionPane.YES_OPTION;
}
return true;
}
//This is working perfectly
public static Boolean showDeleteConfirmation() {
if (deleteConfirmation) {
int value = JOptionPane.showConfirmDialog(null, "Are you sure want to delete?", "Delete", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
return value == JOptionPane.YES_OPTION;
}
return true;
}
I manually called JPopupmenu.hide() before calling that function.It solved the problem
There is a good thread on how to correctly hook up a right-click menu to a Jface TreeViewer depending on the selected item.
I would like to show the right click menu depending on: if the right-click was on a node or into "empty space". The problem is that TreeViewer does not automatically clear the selection if you click into empty space. Is there any clean way how to achieve this?
My current approach would be to simply hook up a MouseListener to the tree with the following mouseDown method:
#Override
public void mouseDown(MouseEvent e) {
TreeItem item = treeViewer.getTree().getItem(new Point(e.x, e.y));
if (item == null) {
treeViewer.getTree().deselectAll();
}
}
This seems to work quite well. What do you think of this?
Ok, I found a dirty workaround. So if you really want to do it, here is a possible solution:
final Tree tree = viewer.getTree();
final Menu menu = new Menu(tree);
tree.setMenu(menu);
menu.addMenuListener(new MenuAdapter()
{
#Override
public void menuShown(MenuEvent e)
{
Point point = tree.toControl(Display.getDefault().getCursorLocation());
boolean found = false;
for (TreeItem item : tree.getItems())
{
for (int i = 0; i < tree.getColumnCount(); i++)
if (item.getBounds(i).contains(point))
found = true;
}
System.out.println(found);
}
});
How to add popup menu to your SWT/JFace TreeViewer
Hi, in your applications main class (that extends ApplicationWindow) in protected Control createContents(Composite parent) method you should add code like this:
//Author: Darius Kucinskas (c) 2008-2009
//Email: d[dot]kucinskas[eta]gmail[dot]com
//Blog: http://blog-of-darius.blogspot.com/
//License: GPL
// Create the popup menu
MenuManager menuMgr = new MenuManager();
Menu menu = menuMgr.createContextMenu(mTreeViewer.getControl());
menuMgr.addMenuListener(new IMenuListener() {
#Override
public void menuAboutToShow(IMenuManager manager) {
if(mTreeViewer.getSelection().isEmpty()) {
return;
}
if(mTreeViewer.getSelection() instanceof IStructuredSelection) {
IStructuredSelection selection = (IStructuredSelection)mTreeViewer.getSelection();
DatabaseModelObject object = (DatabaseModelObject)selection.getFirstElement();
if (object.getType() == DATABASE_OBJECT_TYPE.TABLE){
manager.add(new ShowTableDataAction(SWTApp.this));
}
}
}
});
menuMgr.setRemoveAllWhenShown(true);
mTreeViewer.getControl().setMenu(menu);
DatabaseModelObject - is class from my problem domain (specific to my program). mTreeViewer - is object of TreeViewer class (JFace). Thanks, have a nice day!
Is this the intended functionality or am I doing something wrong?
All I'm doing is creating a GXT Button and calling setMenu to attach a GXT menu. On first click, the menu shows properly, on second click, the menu disappears on MouseDown, but reappears on MouseUp. The only way to get the menu to hide is to click away from the button.
I confirmed that it isn't anything strange with a particular button in my code by adding another button:
Button button = new Button("test");
Menu menu = new Menu();
button.setMenu(menu);
add(button);
If this is intended, is there a suggestion on how to add a listener to close the menu on second click?
I am guessing that it is working as intended since the menu always hides as soon as it loses focus. What I did below is override the onAutoHide method in the menu to not hide if the button with the specified ID is pressed (change accordingly). This gives me the ability to check if the menu is shown in the onClick method of the button - and then not show it again. Be warned though...I am in no way an expert and this is a hack :)
Button button = new Button("Test") {
#Override
protected void onClick(ComponentEvent ce) {
ce.preventDefault();
focus();
hideToolTip();
if (!disabled) {
ButtonEvent be = new ButtonEvent(this);
if (!fireEvent(Events.BeforeSelect, be)) {
return;
}
if (menu != null) {
if (!menu.isVisible())
showMenu();
else
hideMenu();
}
fireEvent(Events.Select, be);
}
}
};
button.setId("TESTBUTTONID");
Menu menu = new Menu() {
#Override
protected boolean onAutoHide(PreviewEvent pe) {
if (pe.getEventTypeInt() == Event.ONMOUSEDOWN
&& !(pe.within(getElement()) || (fly(pe.getTarget())
.findParent(".x-ignore", -1) != null))
&& !(fly(pe.getTarget()).findParent(".x-btn", -1) != null
&& fly(pe.getTarget()).findParent(".x-btn", -1).getId()
.equalsIgnoreCase("TESTBUTTONID"))) {
MenuEvent me = new MenuEvent(this);
me.setEvent(pe.getEvent());
if (fireEvent(Events.AutoHide, me)) {
hide(true);
return true;
}
}
return false;
}
};
button.setMenu(menu);
RootPanel.get().add(button);
My task is necessary and shouldn't be canceled, how do I ask ProgressMonitor not to display the "Cancel" button, so when it finishes, it will auto close the panel.
Frank
I was thinking maybe I can ask it to
return the components in it and delete
the button
Using the ProgressMonitorDemo from the Swing tutorial (linked to by BalusC) I made the following changes:
public void propertyChange(PropertyChangeEvent evt) {
if ("progress" == evt.getPropertyName() ) {
int progress = (Integer) evt.getNewValue();
progressMonitor.setProgress(progress);
// Added this
AccessibleContext ac = progressMonitor.getAccessibleContext();
JDialog dialog = (JDialog)ac.getAccessibleParent();
java.util.List<JButton> components =
SwingUtils.getDescendantsOfType(JButton.class, dialog, true);
JButton button = components.get(0);
button.setVisible(false);
// end of change
String message =
String.format("Completed %d%%.\n", progress);
progressMonitor.setNote(message);
taskOutput.append(message);
if (progressMonitor.isCanceled() || task.isDone()) {
Toolkit.getDefaultToolkit().beep();
if (progressMonitor.isCanceled()) {
task.cancel(true);
taskOutput.append("Task canceled.\n");
} else {
taskOutput.append("Task completed.\n");
}
startButton.setEnabled(true);
}
}
}
You will need to download the Swing Utils class as well.
The code should only be executed once, otherwise you get a NPE when the dialog closes. I'll let you tidy that up :).
That's not possible. You can however create a custom progress monitor as outlined in this tutorial.