B4J Question Adding an icon via code

hanyelmehy

Active Member
Licensed User
Longtime User
i use this to add icon to button
B4X:
Sub AppStart (Form1 As Form, Args() As String)
...
  'Define the button and add to the rootpane of the mainform
  Dim btn As Button
  btn.Initialize("btn")
  btn.Tag = "This is my ImageButton"
  MainForm.RootPane.AddNode(btn, 20,20,50, 50)
  'Create the imageview and add to the button
  Dim iv As ImageView
  iv.Initialize("")
  'Ensure the image myimage.png is added to the files tab and stored in the files folder
  iv.SetImage(fx.LoadImage(File.DirAssets, "myimage.png"))
  ButtonSetGraphic(btn, iv)
End Sub

'Add the icon using API call
Sub ButtonSetGraphic(btn As Button, Graphic As Node)
   Dim jo As JavaObject = btn
   jo.RunMethod("setGraphic", Array(Graphic))
End Sub

the problem in this case ,Button size is changed according to image size
i just need to add image to a button without changing its size
 

Roycefer

Well-Known Member
Licensed User
Longtime User
I haven't tested to see if this fixes your problem but this solution jumps out at me. Use:
B4X:
fx.LoadImageSample(File.DirAssets, "myimage.png", btn.width, btn.height)
instead of
B4X:
fx.LoadImage(File.DirAssets, "myimage.png")
 
Upvote 0

hanyelmehy

Active Member
Licensed User
Longtime User
Thank you for your idea
in most cases using width and height of object after add it dynamical return non correct dimension ,so you must put calculated dimension
any way i modify to this code
B4X:
Sub ButtonSetGraphic(btn As Button,Fn1 As String,Sw As Int,Sh As Int )
   Private iv As ImageView
   iv.Initialize("")
   'iv.SetImage(fx.LoadImage(File.DirApp,Fn1))
   iv.SetImage(fx.LoadImageSample(File.DirApp, Fn1, Sw, Sh))
   'iv.Width=btn.Width
   'iv.Height=btn.Height
   Private Graphic As Node=iv
   Dim jo As JavaObject = btn
   jo.RunMethod("setGraphic", Array(Graphic))
End Sub

but the problem now ,image not good like original when using LoadImageSample
 
Upvote 0

Roycefer

Well-Known Member
Licensed User
Longtime User
You can't call btn.Width immediately after adding btn to its parent Node. You have to wait until the parent Node has completed measuring stuff and drawing the Button. Then, you can call btn.Width and it will return correct values. Unfortunately, I don't think there's an event that tells you when the parent Node has completed drawing the Button so you might try using a Timer to wait a few milliseconds after adding btn to its parent Node.

As for image quality, that's probably a result of how images are down-sampled by fx.LoadImageSample(). If you don't like how fx down-sampled your image, you can try using Photoshop or something to create a smaller version of myimage.png that is more to your liking and closer to the dimensions of btn. But regardless of how it is down-sampled, an image will have less apparent resolution than the image file that generated it if it is displayed at anything less than its native resolution. That's inescapable. If you have a 500x500 image and you're trying to display it in a 50x50 button, you have to discard 99% of the pixels that are in the original image.

Finally, it shouldn't matter much except for very small Buttons but fxLoadImageSample takes Double values and btn.Width gives Double values but your ButtonSetGraphic sub is asking for Int values. You should probably change it to ask for Double values.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…