If you have ever used Window.alert("msg"); API in GWT to show popup, I am not sure but the call to this API pauses the code execution until a user action is taken (cliking the ok button), Simillar to that i have created a custom popup, when it is shown i don't want the code to execute further till any user input in received on the popup, How can i pause the code execution further?
Assume :-
//Some Code
MY Popup (Here i want to wait till a user action is received.)
//Some code
I read somewhere to use Synchronized key word but that didn't work either,Do you have answer to this. How GWT compiler sees "Synchronized" keyword does it ignores the keyword?
Create something like a ConfirmCallBack that you fire when the "OK" button (or whatever) is clicked in the popuppanel.
//method in your own popup class
public static void confirm(String message, ConfirmCallBack confirmCallBack)
{
Button confirmButton = new Button(confirmButtonText, event ->
{
confirmCallBack.callback(true);
//hide popup
});
}
Than also have the ConfirmCallBack interface like
public interface ConfirmCallBack
{
void callback(boolean result);
}
Then call your own popup like
MyPopup.confirm("Hello world", result ->
{
if (result)
{
//my code to be executed after clicking the ok button
}
}
Related
So I have two ways of exiting my applications, with the buttons I created and with the keybindings I created.
The problems I am having are with minimize. For the button, I click it on initial launch and it doesnt work. The second time I click it, it will then work. Here is the code for the button.
#FXML
public void minimizeClick() {
minimizeButton.setOnAction(e ->
( (Stage) ( (Button) e.getSource() ).getScene().getWindow() ).setIconified(true)
);
}
Now for the keybindings, it will work the first time when I press CMD+M on Mac OS. When I bring up the application again in the same session, it will stutter. So I then have to use the key-bind combination twice for it to execute the action. Here is the code:
scene.setOnKeyPressed(e -> {
if(e.getCode() == KeyCode.COMMAND) {
detW = true;
detM = true;
}
if(detW && e.getCode() == KeyCode.W) {
System.exit(0);
detW = false;
}
else if(detM && e.getCode() == KeyCode.M) {
primaryStage.setIconified(true);
detM = false;
}
});
The 3rd condition handles the minimizing. The method handles exiting program as well but obviously I can only exit the program once, so far at least. In the future I will have termination be mapped to CMD+Q instead of CMD+W.
Why is this not working?
You didn't post your FXML file, but I'm going to assume you have something like
<Button text="..." fx:id="minimizeButton" onAction="#minimizeClick" />
in it.
Buttons have a property called onAction, of type EventHandler<ActionEvent>. If the button is clicked (or otherwise fired, e.g. via the keyboard), then if onAction is not null, it is executed.
The onAction="#minimizeClick" sets the onAction property to an EventHandler which invokes the minimizeClick() method defined in the controller.
So you can think of all this as "when the button is clicked, minimizeClick() is invoked in the controller".
Your minimizeClick() method is this:
#FXML
public void minimizeClick() {
minimizeButton.setOnAction(e ->
( (Stage) ( (Button) e.getSource() ).getScene().getWindow() ).setIconified(true)
);
}
What this method does, is set the button's onAction property to a new handler; i.e. it replaces the current onAction handler with a new handler (which minimizes the window).
So the first time the button is clicked, minimizeClick() is invoked. That replaces the current onAction handler (invoke minimizeClick()) with a new handler.
The second (and any subsequent) time the button is clicked, the newly-installed onAction handler is invoked, which minimizes the window.
Consequently the behavior you actually see is that nothing happens on the first button click, but on the second button click the window is minimized.
If you were not using FXML (Java only), then your code would be equivalent to
minimizeButton.setOnAction(e1 -> {
minimizeButton.setOnAction(e2 -> {
((Stage)((Button)e2.getSource()).getScene().getWindow()).setIconified(true);
});
});
Obviously, you just want a simple handler that minimizes the button, i.e. you want the minimizeClick() method to minimize the window. So you need
#FXML
public void minimizeClick() {
( (Stage) ( (Button) e.getSource() ).getScene().getWindow() ).setIconified(true);
}
I don't understand what you mean by "when I bring up the application again it will stutter", but it sounds like that is unrelated to the code you posted. For your key event handlers, you should use KeyEvent.isShortcutDown() etc to see if the cmd key is pressed when the key of interest is pressed, instead of trying to keep track of it yourself. I.e. try
scene.setOnKeyPressed(e -> {
if(e.getCode() == KeyCode.W && e.isShortcutDown()) {
System.exit(0);
// Aside: you should really use Platform.exit() instead of System.exit(0)
// as it will gracefully shutdown the FX toolkit and ensure your
// Application's stop() method is called, etc.
} else if(e.getCode() == KeyCode.M && e.isShortcutDown()) {
primaryStage.setIconified(true);
}
});
Note that the default (native OS) behavior of cmd-M on a Mac is to minimize the window, so this may be confounding the behavior you observe. (I.e. I think on a Mac this behavior may occur without any of these key handlers.)
I have created a JFace wizard PCWizard extending Wizard and have four pages
PCPageOne ,PCPageTwo, PCPageThree and PCPageFour extending WizardPage.
When I reach the last page I want the back and cancel button disabled.
when I press the back button on other pages I want the data in the widgets of the page to get cleared and when I press next again I want the text fields to be empty so that the next button doesn't get activated .
I have also captured the data collected in another class, if u want me to override the WizardDialog class and do the action how do I do it . I'm new to java and SWT a more elaborate explanation would be fine.Thanx in advance
Override the WizardPage setVisible method to clear fields when the page becomes active:
#Override
public void setVisible(final boolean visible)
{
super.setVisible(visible);
if (visible) {
// TODO clear your fields
}
}
To disable the back button do the following in the last page:
#Override
public IWizardPage getPreviousPage() {
// prevent going back
return null;
}
Also clearing the input in pages might be done in a IPageChangedListener:
WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), wizard);
dialog.addPageChangedListener(new IPageChangedListener() {
public void pageChanged(PageChangedEvent event) {
// this is just a suggestion..
IClearablePage page = (IClearablePage)event.getSelectedPage();
page.clear();
}
});
Where IClearablePage is your own interface with a clear(), and all your pages implement IClearablePage.
EDIT: override setVisible as greg stated in his answer is probably more convenient.
What is the best practice for subscribing to events from another JFrame? For example, I have a "settings" form, and when the user presses okay on the settings form, I want the main form to know about this so it can retrieve the settings.
Thanks.
Here is my ideal interface:
public void showSettingsButton_Click() {
frmSettings sForm = new sForm(this._currentSettings);
//sForm.btnOkay.Click = okayButtonClicked; // What to do here?
sForm.setVisible(true);
}
public void okayButtonClicked(frmSettings sForm) {
this._currentSettings = sForm.getSettings();
}
Someone publishes an Event, that something has changed, here the settings. A subscriber that registered for this specifig event, gets notified about it and can do his work, here get the settings. This is called publisher/subscriber.
For this you can use Eventbus or implementing something smaller on your own.
One approach is to have only a single JFrame. All the other 'free floating top level containers' could be modal dialogs. Access the the main GUI will be blocked until the current dialog is dismissed, and the code in the main frame can check the settings of the dialog after it is dismissed.
For anyone interested, here is what I ended up going with. I'm not sure if it's the best way, but it is working for my purposes.
// Method called when the "Show Settings" button is pressed from the main JFrame
private void showSettingsButton_Click() {
// Create new settings form and populate with my settings
frmSettings sForm = new frmSettings(this.mySettings);
// Get the "Save" button and register for its click event...
JButton btnSave = sForm.getSaveButton();
btnSave.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent evt) {
SaveSettings(sForm);
}
});
// Show the settings form
sForm.setVisible(true);
}
// Method called whenever the save button is clicked on the settings form
private void SaveSettings(frmSettings sForm) {
// Get the new settings and assign them to the local member
Settings newSettings = sForm.getSettings();
this.mySettings = newSettings;
}
And if, like me, you are coming from a .NET perspective, here is the C# version:
private void showSettingsButton_Click(object sender, EventArgs e)
{
frmSettings sForm = new frmSettings(this.mySettings);
sForm.btnSave += new EventHandler(SaveSettings);
sForm.Show();
}
private void SaveSettings(object sender, EventArgs e)
{
frmSettings sForm = (frmSettings)sender; // This isn't the exact cast you need..
Settings newSettings = sForm.Settings;
this.mySettings = newSettings;
}
I'm writing an applet and want to figure out how to make a button and a key event cover the same bit of code. For this question, I'll call this button fireButton. The code for the action event would of course look like this:
public void actionPerformed(ActionEvent e) {
if (e.getSource() == fireButton) {
//all the code that pressing button executes
}
}
Now, I want pressing the 'enter' key to perform the same code that the action event handles, but I do not want to rewrite all the code again in a keyPressed method.
To be specific, I'm writing a battleship program, and the 'Fire' button takes input from two textFields, handles exceptions, and passes the input as parameters to a method that fires at a particular square in the grid. Ideally, pressing the enter key would function the same way as if I had pressed the fire button. Is there a way to make a certain method call an actionPerformed method? If not, what would be an elegant solution to the problem?
Create an Action
Add the Action to the JButton
Use Key Bindings to bind the Enter key to the Action
Read the Swing tutorial. There are sections on:
How to Use Actions
How to Use Key Bindings
If you are just talking about invoking the "Fire" button with the enter key then check out Enter Key and Button for a couple of approaches.
I suggest you put all the code in a separate method that receives all the relevant data from the event (if any) as parameters:
public void actionPerformed(ActionEvent e) {
if (e.getSource() == fireButton) {
Object relevantData0 = new Object(); // e.getSomething();
Object relevantData1 = new Object(); // e.getSomethingElse();
handleFireAction(relevantData1, relevantData2);
}
}
public void actionPerformed(KeyEvent e) {
if (e.getSource() == fireButton) {
Object relevantData0 = new Object(); // e.getSomething();
Object relevantData1 = new Object(); // e.getSomethingElse();
handleFireAction(relevantData1, relevantData2);
}
}
private void handleFireAction(Object relevantData0, Object relevantData1) { // Object relevantDat2, and so on
//all the code that pressing button executes
}
If you don't need any data from the event its even easier ;)
This way you just write your code once for both events. It's a general OO aproach.
Hope this helps.
Borrowing from MVC I would recommend you have a controller class which handles these sorts of requests. Then all you have to do is delegate to the controller in each event handler.
Like so:
public class BattleShipController {
public void handleFireAction() {
// ...
}
}
//-- in your UI class(es)
private BattleShipController _controller = new BattleShipController();
//-- in event calls:
_controller.handleFireAction();
If you post relevant code I can make further suggestions.
I'm looking for a simple solution for a yes/no dialog to use in a Java ME midlet. I'd like to use it like this but other ways are okey.
if (YesNoDialog.ask("Are you sure?") == true) {
// yes was chosen
} else {
// no was chosen
}
You need an Alert:
An alert is a screen that shows data to the user and waits for a certain period of time before proceeding to the next Displayable. An alert can contain a text string and an image. The intended use of Alert is to inform the user about errors and other exceptional conditions.
With 2 commands ("Yes"/"No" in your case):
If there are two or more Commands present on the Alert, it is automatically turned into a modal Alert, and the timeout value is always FOREVER. The Alert remains on the display until a Command is invoked.
These are built-in classes supported in MIDP 1.0 and higher. Also your code snippet will never work. Such an API would need to block the calling thread awaiting for the user to select and answer. This goes exactly in the opposite direction of the UI interaction model of MIDP, which is based in callbacks and delegation. You need to provide your own class, implementing CommandListener, and prepare your code for asynchronous execution.
Here is an (untested!) example class based on Alert:
public class MyPrompter implements CommandListener {
private Alert yesNoAlert;
private Command softKey1;
private Command softKey2;
private boolean status;
public MyPrompter() {
yesNoAlert = new Alert("Attention");
yesNoAlert.setString("Are you sure?");
softKey1 = new Command("No", Command.BACK, 1);
softKey2 = new Command("Yes", Command.OK, 1);
yesNoAlert.addCommand(softKey1);
yesNoAlert.addCommand(softKey2);
yesNoAlert.setCommandListener(this);
status = false;
}
public Displayable getDisplayable() {
return yesNoAlert;
}
public boolean getStatus() {
return status;
}
public void commandAction(Command c, Displayable d) {
status = c.getCommandType() == Command.OK;
// maybe do other stuff here. remember this is asynchronous
}
};
To use it (again, untested and on top of my head):
MyPrompter prompt = new MyPrompter();
Display.getDisplay(YOUR_MIDLET_INSTANCE).setCurrent(prompt.getDisplayable());
This code will make the prompt the current displayed form in your app, but it won't block your thread like in the example you posted. You need to continue running and wait for a commandAction invocation.
I dont have programed in Java ME, but i found in it's reference for optional packages the
Advanced Graphics and User Interface API, and it's used like the Java SE API to create these dialogs with the JOptionPane Class
int JOptionPane.showConfirmDialog(java.awt.Component parentComponent, java.lang.Object >message, java.lang.String title, int optionType)
Return could be
JOptionPane.YES_OPTION, JOptionPane.NO_OPTION, JOptionPane.CANCEL_OPTION...