How to set value of label and textarea when a button is click?

Public Window MainWindow
    Title = "MainWindow"
    Frame = (200, 200, 640, 480)

    Control Label lbl_Address
        Text = "Label"
        Frame = (16, 16, 120, 20)
    End Control

    Control TextArea ta_Address
        Text = "TextArea"
        Frame = (136, 16, 300, 200)
    End Control
End Window

Public Class GlobalVars
    Public Property x_MainWindow As MainWindow
End Class

Class btn_ChangeAddress Inherits Button
    Handle Action()
        If GlobalVars.x_MainWindow IsNot Nothing Then
            GlobalVars.x_MainWindow.lbl_Address.Text = "Your Address:"
            GlobalVars.x_MainWindow.ta_Address.Text = "Your Address"
        End If
    End Handle
End Class

Sub Main()
    Dim w As New MainWindow()
    GlobalVars.x_MainWindow = w 

    ' Set initial values
    w.lbl_Address.Text = "My Address:"
    w.ta_Address.Text = "My Address"

    ' Create button and capture window reference
    Dim b As New btn_ChangeAddress()
    b.Caption = "Change to Address"
    b.Move(136, 224, 300, 32)
    b.target_window = w  ' ✅ Pass the window reference
    w.AddSubview(b)

    w.Show()
    Application.Run()
End Sub

in the above code, I am setting the value for labels and textarea to “My Address” and when I click on the button, want it to change to “Your Address”

the error I got is as follows

error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
error: class 'btn_ChangeAddress' has no field 'target_window'
error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
error: undefined variable 'Nothing'
error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
error: unknown member 'lbl_Address' on type Unknown
error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
error: unknown member 'lbl_Address' on type Unknown
error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
error: unknown member 'lbl_Address' on type Unknown
error: unknown member 'Text' on type Unknown
error: class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
unknown member 'ta_Address' on type Unknown
class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
unknown member 'ta_Address' on type Unknown
class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
class 'GlobalVars' has no shared member, constant, nested enum, or nested structure 'x_MainWindow'
unknown member 'ta_Address' on type Unknown
unknown member 'Text' on type Unknown
  1. the error message says

/Users/npalardy/Desktop/Buoy/For Norman/Norm Work In Progress/junktest.bui:31:0: error: class ‘GlobalVars’ has no shared member, constant, nested enum, or nested structure ‘x_MainWindow’

so make x_mainWindow SHARED PUBLIC
In your code you never create an instance of Globals but I suspect the intent is, or was, to create a single shared set of global variables
SHARED PUBLIC means that you do not need to create an instance of the GlobalsVars class for the shared property to exist

  1. once you do step 1 you will likely get this as an error

/Users/npalardy/Desktop/Buoy/For Norman/Norm Work In Progress/junktest.bui:41:0: error: class ‘btn_ChangeAddress’ has no field ‘target_window’

which is true there’s no such property so comment out the line trying to set it
b.target_window = w ' ✅ Pass the window reference

3)next you’ll get
/Users/npalardy/Desktop/Buoy/For Norman/Norm Work In Progress/junktest.bui:22:0: error: undefined variable ‘Nothing’

because of this line
If GlobalVars.x_MainWindow IsNot Nothing Then

You CAN just use the ? operator so avoid the comparison entirely

GlobalVars.x_MainWindow?.lbl_Address.Text = "Your Address:"
GlobalVars.x_MainWindow?.ta_Address.Text = "Your Address"

see the example in optional_chain.bui

Optional-chain assignment: obj?.Field = value
Desugars to: If obj <> Nil Then obj.Field = value

The assignment is silently skipped when the receiver is Nil.

after these changes this turns into

Public Window MainWindow
    Title = "MainWindow"
    Frame = (200, 200, 640, 480)

    Control Label lbl_Address
        Text = "Label"
        Frame = (16, 16, 120, 20)
    End Control

    Control TextArea ta_Address
        Text = "TextArea"
        Frame = (136, 16, 300, 200)
    End Control
End Window

Public Class GlobalVars
    Shared Public Property x_MainWindow As MainWindow
End Class

Class btn_ChangeAddress Inherits Button
    Handle Action()
            GlobalVars.x_MainWindow?.lbl_Address.Text = "Your Address:"
            GlobalVars.x_MainWindow?.ta_Address.Text = "Your Address"
    End Handle
End Class

Sub Main()
    Dim w As New MainWindow()
    GlobalVars.x_MainWindow = w 

    ' Set initial values
    w.lbl_Address.Text = "My Address:"
    w.ta_Address.Text = "My Address"

    ' Create button and capture window reference
    Dim b As New btn_ChangeAddress()
    b.Caption = "Change to Address"
    b.Move(136, 224, 300, 32)
    w.AddSubview(b)

    w.Show()
    Application.Run()
End Sub

Thanks Norman for helping out. I check a few sample BUI file.

So I was missing the SHARE in class GlobalVars.

then the target_window is some left over from previous attempts instead of using GlobalVars

Yeah just like in Xojo a CLASS you USUALLY have to create using NEW

Except when you don’t :stuck_out_tongue:

Shared Public Properties act that way in both languages

the other way to do the same things as above code but without using global.

notice the btn_ChangeAddress is using target_window. and I remove the checking and use ? after target_window

and at the Main(), I assign w to b.target_window

Public Window MainWindow
    Title = "MainWindow"
    Frame = (200, 200, 640, 480)

    Control Label lbl_Address
        Text = "Label"
        Frame = (16, 16, 120, 20)
    End Control

    Control TextArea ta_Address
        Text = "TextArea"
        Frame = (136, 16, 300, 200)
    End Control
End Window

Class btn_ChangeAddress Inherits Button
    Public Property target_window As MainWindow
    Handle Action()
        target_window?.lbl_Address.Text = "Your Address:"
        target_window?.ta_Address.Text = "Your Address"
    End Handle
End Class

Sub Main()
    Dim w As New MainWindow()
    
    ' Set initial values
    w.lbl_Address.Text = "My Address:"
    w.ta_Address.Text = "My Address"

    ' Create button and capture window reference
    Dim b As New btn_ChangeAddress()
    b.Caption = "Change to Address"
    b.Move(136, 224, 300, 32)
    b.target_window = w  ' ✅ Pass the window reference
    w.AddSubview(b)

    w.Show()
    Application.Run()
End Sub

indeed I suspect there are many ways to achieve the same goal without the use of a global

I tend to avoid globals as much as possible

What you’re experiencing here is temporary. I need to get us to the point where we can attach code to a Window and execute it all within that same scope, just like you can in Xojo… but I’m trying to make it so these things don’t all need to be stored in the same file, while at the same time not making it completely confusing.

I’m confident that there’s a solution coming but I’ve been over the guidelines I’ve set for this and nothing’s come forward yet.

One more simplification

Your code could look like

NOTE the MainWindowLayout is roughly what you design in Xojo’s layout editor
Then in the subclass you add all the code - the handlers for events of controls etc

Public Window MainWindowLayout
    Title = "MainWindow"
    Frame = (200, 200, 640, 480)

    Control Label lbl_Address
        Text = "My Address:"
        Frame = (16, 16, 120, 20)
    End Control

    Control TextArea ta_Address
        Text = "My Address"
        Frame = (136, 16, 300, 200)
    End Control

    Control Button btn_ChangeAddress
        Caption = "Change to Address"
        Frame = (136, 224, 300, 32)
    end Control

End Window

Public Class MainAppWindow inherits MainWindowLayout
    Public Overrides Sub btn_ChangeAddress_Action()          ' generated hook
            me.lbl_Address.Text = "Your Address:"
            me.ta_Address.Text = "Your Address"
    End Sub
End Class

Sub Main()
    Dim w As New MainAppWindow()

    w.Show()

    Application.Run()
End Sub

Xojo had .parent reference to the window from the button perspective, does Buoy have this too?

I refine the code NOT using global here

Const x_Old As String = "My Address"
Const x_New As String = "Your Address"   

Public Window MainWindow
    Title = "Using Local"
    Frame = (200, 200, 640, 480)

    Control Label lbl_Address
        Text = "Label"
        Frame = (16, 16, 120, 20)
    End Control

    Control TextArea ta_Address
        Text = "TextArea"
        Frame = (136, 16, 300, 200)
    End Control
End Window


Class btn_ChangeAddress Inherits Button
    Public Property target_window As MainWindow
    Handle Action()
        target_window?.lbl_Address.Text = x_New + ":"
        target_window?.ta_Address.Text = x_New
    End Handle
End Class


Class btn_ResetAddress Inherits Button
    Public Property target_window As MainWindow
    Handle Action()
        target_window?.lbl_Address.Text = x_Old + ":"
        target_window?.ta_Address.Text = x_Old
    End Handle
End Class

Sub Main()
    
    Dim w As New MainWindow()
    w.lbl_Address.Text = x_Old + ":"
    w.ta_Address.Text = x_Old

    Dim b1 As New btn_ChangeAddress()
    b1.Caption = "Change Address"
    b1.Move(136, 224, 300, 32)
    b1.target_window = w  
    w.AddSubview(b1)

    Dim b2 As New btn_ResetAddress()
    b2.Caption = "Reset Address"
    b2.Move(136, 250, 300, 32)
    b2.target_window = w  
    w.AddSubview(b2)

    w.Show()
    Application.Run()
End Sub

and this one using global

Public Window MainWindow
    Title = "Using Global"
    Frame = (200, 200, 640, 480)

    Control Label lbl_Address
        Text = "Label"
        Frame = (16, 16, 120, 20)
    End Control

    Control TextArea ta_Address
        Text = "TextArea"
        Frame = (136, 16, 300, 200)
    End Control
End Window

Public Class GlobalVars
    Shared Public Const x_Old As String = "My Address"
    Shared Public Const x_New As String = "Your Address"   
    Shared Public Property x_MainWindow As MainWindow
End Class

Class btn_ChangeAddress Inherits Button
    Handle Action()
            GlobalVars.x_MainWindow?.lbl_Address.Text = GlobalVars.x_New + ":"
            GlobalVars.x_MainWindow?.ta_Address.Text = GlobalVars.x_New 
    End Handle
End Class


Class btn_ResetAddress Inherits Button
    Handle Action()
            GlobalVars.x_MainWindow?.lbl_Address.Text = GlobalVars.x_Old + ":"
            GlobalVars.x_MainWindow?.ta_Address.Text = GlobalVars.x_Old 
    End Handle
End Class


Sub Main()
    Dim w As New MainWindow()
    GlobalVars.x_MainWindow = w 

    ' Set initial values
    w.lbl_Address.Text = GlobalVars.x_Old + ":"
    w.ta_Address.Text = GlobalVars.x_Old

    ' Create button and capture window reference
    Dim b1 As New btn_ChangeAddress()
    b1.Caption = "Change Address"
    b1.Move(136, 224, 300, 32)
    w.AddSubview(b1)

    Dim b2 As New btn_ResetAddress()
    b2.Caption = "Reset Address"
    b2.Move(136, 250, 300, 32)
    w.AddSubview(b2)



    w.Show()
    Application.Run()
End Sub

I like your code… so much cleaner… and make Main() much simpler

I’m looking into that. Just so you can see the problem…

If we simply add a ParentWindow property, it would be of type Window. That only gets you part of the way there because you still need to cast to the actual window type.

Dim w as myWindow = CType(parentWindow, myWindow)

IIRC Xojo does this with all that magic they did during the “rendering phase” right before sending code to the compiler. I’m trying really hard to avoid that type of thing because bad things happen when rendered code causes bugs. I don’t want users to be beholden to buoy in that way if I can help it.

a quick question, how to add a open event and a close event??

I know I can add the following to the sample code from Norm but I am having trouble with close event when the window is closed

    Public Sub Open_Event()
        me.lbl_Address.Text = x_Old + ":"
        me.ta_Address.Text = x_Old
    End Sub
Sub Main()
    Dim w As New MainAppWindow()
    w.Open_Event()
    w.Show()
    Application.Run()
End Sub

First of all, Windows currently have two “open” events. Opening (before showing) and Opened (after opening). You write them inside your Window subclass code as:

Handle Opening()

End Handle

There’s also a Closing event.

just try this and it is working although “closing” should be “closed” instead.. I try “close” and it does not work either.

found the code in lifecycle_events.bui which does not including closing, closed, close

I’m very actively updating the language references so these things are easier to find :slight_smile:

Thanks Norm

Class MyWindow Inherits Window
    Handle Opening()
        ' last-minute setup before display
    End Handle

    Handle Opened()
        ' safe to focus a control or start an animation
    End Handle

    Handle Shown()
        ' fires on every show, including restore from minimized
    End Handle

    Handle Hidden()
    End Handle

    Handle Activated()
    End Handle

    Handle Deactivated()
    End Handle

    Handle Resized(width As Double, height As Double, finished As Boolean)
        Me.Layout(width, height)   ' re-solve anchor constraints
    End Handle

    Handle Closed()
        ' nil out references held elsewhere, e.g. app.CurrentWindow = Nil
    End Handle

    Handle MenuSelected(item As MenuItem)
        If item.Tag = "quit" Then Application.Quit()
    End Handle

    Handle MenuNeedsUpdate(menu As Menu)
    End Handle

    Handle ScaleFactorChanged(newFactor As Double, oldFactor As Double)
    End Handle
End Class

FWIW, I got that example by going to the /Applications/Buoy directory in a Terminal window, opening Claude and telling it this:

Using the markdown in this folder, what are the events for a Window and how do I write code for them?

Mostly because I wanted to make sure this functionality worked for end-users.