My program contain two classes, one represent the main program and the other one is a gui implemented using swing,
I'm trying to create an "event type", meaning I want my main program to wait until the UserInterface (GUI) will indicate some event, like pressing a button, and I would like to sends some information when my button is pressed.
General Code for the main program (this is the relevant section)
// Open window GUI with the requested BID and wait for confirmation or denial
HumanIFWindow nextWindowGUI = new HumanIFWindow();
nextWindowGUI.setVisible(true);
// ----------------- //
// - Wait on event - //
// ----------------- //
// Here is where I want to wait for the gui Indication
return returnedBid;
Code for the GUI (Again only relevant part)
JButton btnAprove = new JButton("Aprove");
btnAprove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// ----------------- //
// - Trigger event - //
// ----------------- //
// Here is where I want to trigger the event
}});
Preferably I would like to use some library, is there's one that match my needs?
(Maybe BusEvent?)
Edit to specify the question (Thanks Kishan Sarsecha Gajjar)
I want the first class (the general one) to enter a wait statement, I know how to wait using:
while( someBoolean...)
Thread.sleep(...)
and I can change someBoolean with a handle in the GUI class, Like:
FisrtClass.someBoolean == False
But I want something nicer and neater, like a library that Implements the sleep statement. and there's no additional code needed. Is there something like that?
I've looked at Google-BusEvent library but I'm not sure if that's compatible
EDIT, adding JDialog
updated code: Main program:
Bid returnedBid = requestBid;
// Open window GUI with the requested BID and wait for confirmation
DialogHumanConfirmManual nextWindowGUI = new DialogHumanConfirmManual(requestBid);
// Wait on event
if ( (returnedBid = nextWindowGUI.getAnswer()) != null ){
System.out.println("Got Bid " + returnedBid.print());
}
GUI - Dialog:
public DialogHumanConfirmManual(Bid requestedBid){
currentBid = requestedBid;
currentBid.approvedHuman = false;
Dialog mainFrame = new Dialog(new Frame());
myPanel = new JPanel();
getContentPane().add(myPanel);
myPanel.add(new JLabel("Confirmation Dialog"));
yesButton = new JButton("Confirm");
yesButton.addActionListener(this);
myPanel.add(yesButton);
noButton = new JButton("No");
noButton.addActionListener(this);
myPanel.add(noButton);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (yesButton == e.getSource()) {
currentBid.approvedHuman = true;
answeredBid = currentBid;
}
}
After opening the Dialog the if ( returnBid ) is called, which result in Null Pointer Exception later on in the code, So How can I delay the main program until the user can Confirm the request??
the other one is a gui implemented using swing,
Use a modal JDialog not a JFrame.
Once the dialog is made visible, the code after the setVisible(true) statement will NOT execute until the dialog is closed.
Read the section from the Swing tutorial on How to Make Dialogs for more information. The tutorial covers the JOptionPane class, but you can just use a JDialog, which is created exactly the same way a JFrame is. You can choose whether to use a JOptionPane or JDialog depending on your exact requirement.
Related
I'm currently trying to code an interactive timeline for my Uni project (keep in mind im a new coder) and we go over basic actionscript stuff. I was taught to communicate between scripts using a movieclip variable and declaring this.parent.
I have 3 scripts, one that controls the button that is used to move forward in the timeline, one is main, and the other controls the text box which displays the timeline. I placed a number variable in main, initialised at 0(timeCount). In the button script, i have it linked to main using refToMain, my movieclip variable. Within the button script, if the user clicks on the button, it rises the number variable from main using refToMain(refToMain.timeCount). It was my ambition to have the text box script track the number and each number has a different bit of the timeline on. However, when I trace timeCount in the button script, the number seems fine and raises accordingly, however it doesnt change the number in any other script. How can I fix this using basic as3 code?
In Main:
var timeCount:Number = 0;
In Button:
public function mDown (mDown:MouseEvent){
refToMain.timeCount += 1;
if(refToMain.timeCount >= 10){
refToMain.timeCount = 10;
}
trace(refToMain.timeCount);
In timeline:
if(refToMain.timeCount == 0){
timelineText.text = "welcome"
}
if(refToMain.timeCount == 1){
timelineText.text = "hello"
}
Are you expecting the code in your timeline to run continuously instead of just once? A frame script will only run once each time the timeline reaches that frame. And if you only have one frame, the timeline won't advance at all. If that's the case, a simple fix would be to add another frame to your timeline with F5, and then your timeline will alternate between your two frames forever so that your script on frame 1 will execute every other frame.
A better option would be to call the script that updates the timeline text directly every time the button is clicked. So you would move the code from your timeline script to your button script like this:
public function mDown (mDown:MouseEvent) {
refToMain.timeCount += 1;
if(refToMain.timeCount >= 10) {
refToMain.timeCount = 10;
}
trace(refToMain.timeCount);
if(refToMain.timeCount == 0) {
MovieClip(root).timelineText.text = "welcome";
}
if(refToMain.timeCount == 1) {
MovieClip(root).timelineText.text = "hello";
}
}
There are several ways and approaches to access objects and variables across your application.
1) Traversing. The (probably) older and the most straightforward one is fully understanding and controlling the display list tree. If you understand where your current script is and where your target script is, you just traverse this tree with root to go straight to the top, parent to go level up and getChildByName or [] or dot notation to go level down.
Pros: it's simple. Contras: The weak point of this approach is its inflexibility. Once you change the structure of display list tree, the access would presumably be broken. Also, this way you might not be able to access things that are not on the display list. Also, there are cases the dot notation would not work, and there are cases getChildByName would not work. Not that simple, after all.
2) Bubbling events. These are events that bubble from the depths of display list to the root. Mouse events are bubbling: you can catch it anywhere from the deepest object that had some mouse event then all its parents right up to the stage. You can read about them here. So, you can send bubbles from whatever depth you want then intercept them at the any parent of the event target:
// *** TextEvent.as class file *** //
package
{
import flash.events.Event;
public class TextEvent extends Event
{
static public const TEXT_EVENT:String = "text_event";
public var text:String;
// Although it is not a very good practice to leave the basic Event
// parameters out of it, but it will do for this example.
public function TextEvent(value:String)
{
// Set type = "text_event" and bubbles = true.
super(TEXT_EVENT, true);
text = value;
}
}
}
// *** Button script *** //
import TextEvent;
// Dispatch the event.
dispatchEvent(new TextEvent("welcome"));
// *** Main timeline *** //
import TextEvent;
// Subscribe to catch events.
addEventListener(TextEvent.TEXT_EVENT, onText);
function onText(e:TextEvent):void
{
// Extract the passed text value.
timelineText.text = e.text;
}
Pros: it is good in an app architecture terms. Contras: you cannot catch the bubbling event at the point that is not parent of event source.
3) Static class members. Or singleton pattern, its basically the same. You can devise a class that shares certain values and references over the whole application:
// *** SharedData.as class file *** //
package
{
import flash.display.MovieClip;
public class SharedData
{
static public var MainTimeline:MovieClip;
}
}
// *** Main timeline *** //
import SharedData;
// Make root accessible from anywhere.
SharedData.MainTimeline = this;
// *** Button script *** //
import SharedData;
// You can access main timeline via shared reference.
SharedData.MainTimeline.timelineText.text = "welcome";
Pros: you are not limited by display list structure any more, you can also share non-visual instances this way, anything. Contras: careful with timelines, they tend to destroy and create timeline instances as playhead moves, so it is not impossible to end up with a reference to a removed object while timeline holds a new instance that is no longer shared.
I’ve tried a few different methods to get a selected item from a list (see code below), but everything I’ve tried only returns the first item in the list no matter which item was actually selected. Visually it appears to work because the correct item gets highlighted when it is clicked on.
As a general overview of what I’m trying to do, I have a folder that contains all of the saved preset files (json files), then I read the names of all the files into a list of strings, from this list a specific preset can be selected, and then I have a separate “load” textbutton that loads the item that was selected from the list. But as mentioned above, the correct item is not loaded from the list when the load button is clicked.
Here is my code:
public class PresetLoadMenu extends Menu {
private GUI gui;
private SaveManager saveManager;
private Table scrollPaneContainerTable;
private ScrollPane scrollPane;
private Table scrollTable;
private List<String> presetList;
private TextButton loadButton;
private FileHandle rootFolderHandle = Gdx.files.external(“presets/”);
public PresetLoadMenu(GUI gui){
this.gui = gui;
refreshList();
scrollTable = new Table();
scrollTable.add(presetList);
scrollPane = new ScrollPane(scrollTable);
scrollPaneContainerTable = new Table();
scrollPaneContainerTable.add(scrollPane).size(this.getWidth(), this.getHeight()*.2f);
add(scrollPaneContainerTable);
row();
loadButton = new TextButton("LOAD", gui.menuStyles.getMenuOkCancelButtonStyle());
loadButton.addCaptureListener(new ChangeListener(){
#Override
public void changed(ChangeEvent event, Actor actor){
// METHOD 1:
// System.out.println("SELECTED PRESET: " + presetList.getSelected());
// METHOD 2:
// System.out.println("SELECTED PRESET: " + presetList.getSelection().getLastSelected());
// METHOD 3:
// for (int i=0; i<presetList.getSelection().size(); i++){
// System.out.println("INDEX: " + i + " SELECTED PRESET: " + presetList.getSelection().toArray().get(i));
// }
}
});
add(loadButton).size(loadButton.getWidth(), loadButton.getHeight());
}
public void refreshList(){
FileHandle[] files = rootFolderHandle.list();
Array<String> namesArray = new Array<String>();
for(FileHandle file: files) {
namesArray.add(file.name());
}
presetList = new List<String>(gui.menuStyles.getListStyle());
presetList.setItems(namesArray);
}
}
The last method I tried using a for loop just to see if it would print out the other items that I clicked on, but it still printed the first item just one time and didn't detect that I had clicked on any of the other items.
On request I'm copying my last comment as an answer in order to close my question.
The problem was actually something else outside of the class that I posted, so presetList.getSelected() may work just fine now that I figured out what the problem was. But before I figured it out, I had swapped out the List for a ButtonGroup, which is actually better for me than using the List anyways so it worked out. The List has a built in listener that selects the item on touch down, so items would get selected when trying to scroll up or down. With a button I can have a listener just for the checked state, which is what I want.
Based on your answer, I solved it by creating a table of TextButton (buttonTable) , every of them initialize with an string:
final TextButton button = new TextButton("my string",skin);
and a listener:
button.addListener(new ClickListener() {
public void clicked (InputEvent event, float x, float y) {
button.getText()));
}
});
This buttonTable initialize a ScrollPane to allow vertical scrolling:
scrollPane = new ScrollPane(buttonsTable);
This scrollPane was added to table used to format my form:
mainTable.add(scrollPane);
This table was the actor added to the stage:
stage.addActor(mainTable);
I do want to ensure that in case an app is navigated to a certain page, the app is on another (in my case the previous) page after it was suspended or terminated. In my case the page is for taking photos. I do not want the user to return to this page after the app was in the background since it has no context information. The context information is on the previuos page.
How could I achieve this with Prism.StoreApps?
Background: If an app was just suspended the state of the app remains after it was resumed, hence the last active page is active again. I have no real idea how to set another page active in this case. If an app was terminated Prim.StoreApps restores the navigation state and navigates to the last active view model (hence to the last active page). I do not know either how to alter the navigation state in this case so that another page is navigated to.
In the meantime I fond a working solution myself. Might not be the best and there might be better solutions, but it works.
For resuming the app I handle the Resuming event:
private void OnResuming(object sender, object o)
{
// Check if the current root frame contains the page we do not want to
// be activated after a resume
var rootFrame = Window.Current.Content as Frame;
if (rootFrame != null && rootFrame.CurrentSourcePageType == typeof (NotToBeResumedOnPage))
{
// In case the page we don't want to be activated after a resume would be activated:
// Go back to the previous page (or optionally to another page)
this.NavigationService.GoBack();
}
}
For the page restore after termination I firstly use a property in the App class:
public bool MustPreventNavigationToPageNotToBeResumedOn { get; set; }
public App()
{
this.InitializeComponent();
// We assume that the app was restored from termination and therefore we must prevent navigation
// to the page that should not be navigated to after suspension and termination.
// In OnLaunchApplicationAsync MustPreventNavigationToPageNotToBeResumedOn is set to false since
// OnLaunchApplicationAsync is not invoked when the app was restored from termination.
this.MustPreventNavigationToPageNotToBeResumedOn = true;
this.Resuming += this.OnResuming;
}
protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
// If the application is launched normally we do not prevent navigation to the
// page that should not be navigated to.
this.MustPreventNavigationToPageNotToBeResumedOn = false;
this.NavigationService.Navigate("Main", null);
return Task.FromResult<object>(null);
}
In OnNavigatedTo of the page I do not want to be activated on a resume I check this property and simply navigate back if it is true (and set the property to false to allow subsequent navigation):
public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode,
Dictionary<string, object> viewModelState)
{
if (((App)Application.Current).MustPreventNavigationToPageNotToBeResumedOn)
{
// If must prevent navigation to this page (that should not be navigated to after
// suspension and termination) we reset the marker and just go back.
((App)Application.Current).MustPreventNavigationToPageNotToBeResumedOn = false;
this.navigationService.GoBack();
}
else
{
base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
}
}
Windows phone 8.1 new to world. Basic function is back button click. Is that function not working properly is this windows phone 8.1. Is that behavior or i'm made mistake.
Below code using in Homepage but this code calling from all other class too while clicking back. I need to access below method only on Home page .
Please check below code and refer me good solution.
Please look my code:
public HomePage()
{
this.InitializeComponent();
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
}
Thanks
It is working properly. The BackPressed event is working app-wide. Two options that come to my mind:
write eventhandler that would recognize the Page in which you currently invoke it - simple example can look like this:
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
Frame frame = Window.Current.Content as Frame;
if (frame == null) return;
if (frame.Content is HomePage)
{
e.Handled = true;
Debug.WriteLine("I'm in HomePage");
}
else if (frame.CanGoBack)
{
frame.GoBack();
e.Handled = true;
}
}
second option - subscribe to Windows.Phone.UI.Input.HardwareButtons.BackPressed when you enter the Page and unsubscribe when you leave the Page. Note that in this way there are some pitfalls - you have to handle properly OnNavigatedTo, OnNavigatedFrom, Suspending and Resuming (more about Lifecycle here). Note also that the subscription should be done before others - for example NavigationHelper.
Some remarks - the above code should work, but it also depends on other circumstances:
if there is something other subscribed to BackPressed before (in App.xaml.cs) - remember that usually events are fired in order they were subscribed
check if you are using NavigationHelper - it also subscribes to BackPressed
remember not to subscribe multiple times
remember to allow the User to leave your HomePage
I'm working on an assignment due at midnight tomorrow and I'm about to rip my hair out. I am fairly new to ActionScript and Flash Builder so this might be an easy problem to solve. I think I know what it is but I do not know for sure...
I'm developing a weather application. I designed the GUI in Flash CS5. The interface has 2 frames. The first frame is the menu which has a zipcode input and a button instance called "submit". On the second frame, it has another button instance called "change" which takes you back to the first frame, menu.
In Flash Builder 4, I wrote a class to extend that GUI called Application. When Main.as instantiates it, the constructor function runs. However, this was my first problem.
public class Application extends InputBase {
public function Application() {
super();
// Y U NO WORK???
this.gotoAndStop(1);
this.change.tfLabel.text = "Change";
}
}
When I ran debug it tossed a #1009 error saying it could not access the property or method of undefined object. It is defined on frame 2 in Flash CS5. I think this is the problem... Isn't ActionScript a frame based programming language? Like, you cannot access code from frame 2 on frame 1? But, I'm confused by this because I'm not coding on the timeline?
Anyway, I thought of a solution. It kinda works but its ugly.
public class Application extends InputBase {
public function Application() {
super();
// Y U NO WORK???
this.gotoAndStop(1); // when app is first ran, it will stop on the first frame which is the menu frame
setButton(this.submit, "Submit", 1);
setInput(this.tfZipCode);
}
private function submitZip(e:MouseEvent):void {
this.nextFrame();
setButton(this.change, "Change", 2);
}
private function menu(e:MouseEvent):void {
this.prevFrame();
setButton(this.submit, "Submit", 1); // if I comment this out, the submit button will return to the default text label and it forgets it event.
}
private function setButton(button:ButtonBase, string:String="", action:uint=0):void {
button.buttonMode = true;
button.mouseChildren = false;
button.tfLabel.selectable = false;
button.tfLabel.text = string;
switch (action) {
case 1:
button.addEventListener(MouseEvent.CLICK, submitZip);
break;
case 2:
button.addEventListener(MouseEvent.CLICK, menu);
break;
default:
trace("Action code was invalid or not specified.");
}
}
}
Its not my cup of tea to run the set button function every time one of the button instances are clicked. Is this caused by frames or something else I maybe looking over?
I believe you have two keyframes & both have an instance of the button component called button.
If you are working on the timeline try putting the button in a separate layer, with only one key frame.
Something like the following:
Ensures that you are referencing the same button every time & not spawning new ones on each frame.