B4J Question Displayed ProgressBar doesn't update

Discussion in 'B4J Questions' started by DarkMann, May 1, 2015.

  1. DarkMann

    DarkMann Member Licensed User

    I've been working on this all afternoon and it is driving me slowly more insane than I already am!

    My program is set up to import a load of JPEG files that you drag onto it. This all works fine. I select an album, drag the images from a Windows Explorer window into the mane panel and after a period of time they all appear as expected. If there are a lot of images or they are very large, then it takes quite some time and during this time I can't get any indication of progress.

    I've added a ProgressBar and set up a timer to check the state of a progress variable and update the bar. I have tried to offload the hard work by using CallSubDelayed. This seems to improve responsiveness but the timer only fires right at the end. I only know this because all the log of the progress variable shows a progress of 1 and appears all at the same time, once for every call to the sub.

    These two subs loop through the dropped images
    Code:
    Sub ScrlMainView_DragDropped(e As DragEvent)
        
    If CurrentAlbum=-1 Then Return
        
    Dim Files() As String
        
    Dim FileList As String=e.GetDataObjectForId("text/uri-list")
        FileList=FileList.Replace(
    "file:/","").Replace("/","\")
        Files=
    Regex.Split("\r\n",FileList)
        
    If Files.Length=0 Then Return
        ProgWorking.Progress=
    0
        TimerMain.Enabled=
    True
        
    Dim gap As Double = 1/Files.Length
        
    Dim count As Int=0
        
    For Each source As String In Files
            
    If source.Contains(".jpg")=True Then
                count=count+
    1
                CallSubDelayed3(Me,
    "InsertPicture",source,count*gap)
            
    End If
        
    Next
    End Sub

    Sub InsertPicture(Source As String, Position As Double)
        
    Dim imgname As String=File.GetName(Source)
        imgname=imgname.Replace(
    ".jpg","")
        
    Dim imgwork As Image=Graphics.ResizeImage(Source,120)
        
    Dim imgaspect As Int=0
        
    If imgwork.Width>imgwork.Height Then imgaspect=1
        
    Dim blob() As Byte
        blob=Graphics.CreateSQLiteBlob(imgwork)
        SQLMain.ExecNonQuery2(
    "INSERT INTO pictures (_album,source,title,thumb,aspect) VALUES (?,?,?,?,?)",Array As Object(CurrentAlbum,Source,imgname,blob,imgaspect))
        ProCount=Position
        FillPhotoPanel
    End Sub
    and this one in the Graphics Module does the sizing. This will be the one that takes a long time.

    Code:
    Public Sub ResizeImage(Source As String, Size As Int) As Image
        
    Dim temp As Image
        temp.Initialize(
    File.GetFileParent(Source),File.GetName(Source))
        
    Dim wid As Int=temp.Width
        
    Dim hid As Int=temp.Height
        
    If wid>hid Then
            
    Dim swid As Int=Size
            
    Dim shid As Int=(Size/wid)*hid
        
    Else
            
    Dim shid As Int=Size
            
    Dim swid As Int=(Size/hid)*wid
        
    End If
        
    Dim temp2 As Image
        temp2.InitializeSample(
    File.GetFileParent(Source),File.GetName(Source),swid,shid)
        
    Return temp2
    I've attached the project and any help would save my sanity.

    I'm using JRLDialogs8 and jDragAndDrop so you may need these.

    David
     

    Attached Files:

  2. Erel

    Erel Administrator Staff Member Licensed User

    The purpose of Image.InitializeSample is to allow you to load downsampled large images, without loading the full image. Your code load each image twice. You should avoid loading the full image to make your program faster.
     
  3. DarkMann

    DarkMann Member Licensed User

    That is what I would like to do Erel, but I need to know the dimensions of the full-sized image first to get the aspect ratio right.

    Is there any way to read the dimensions of the bitmap before it's opened?

    If so, then in this case, the problem will be solved as the speed will increase dramatically. Having said that, I can see a scenario where I drag 1000 images to the window and then we are back needing to have some way of showing progress. What I don't understand is the way the timer doesn't fire. I get that it needs the message loop to be processed and may not be accurate, but I don't see why the message loop isn't being processed between each delayed call to the ResizeImage sub firing.

    I've found in my searches an early response to a similar question where AGraham does it with his threading library, but I don't want to do something that complex for something seemingly so simple and honestly it seems like total overkill to do so. I've also looked at examples where it clearly does work, but I just can't see why it works there but not for this case.

    Thanks,

    David
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    Use this code to load the image without breaking the ratio:
    Code:
    Sub LoadImageSamplePreserveRatio(Dir As String, FileName As String, _
         Width 
    As Double, Height As Double) As Image
       
    Dim jo As JavaObject
       
    Dim in As InputStream = File.OpenInput(Dir, FileName)
       jo.InitializeNewInstance(
    "javafx.scene.image.Image"Array( _
         
    in ,Width, Height, TrueTrue))
       
    in.Close
       
    Return jo
    End Sub
     
    Mashiane and DarkMann like this.
  5. DarkMann

    DarkMann Member Licensed User

    Thanks Erel, that's good enough for it to no longer be a problem. For the moment I'll find another way of indicating that the system will be busy for a few moments.

    David
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice