ImageButton: is functional but will not display any graphics or the image file

Thank you to the members of JUCE for your patience with us University of London Goldsmiths comp sci students; twice a year we inundate you with noob questions as the instructor assigns large JUCE projects to each of us, and we are many.


Attempting to create an image button for a simple audio player (player is very similar to the one in the JUCE beginner’s tutorials).

The button works when I click on the space I reserved for it. It functions, but it’s invisible. At least one, possibly two, issues here.

My pertinent code. It compiles:

.hpp file (the relevant parts : the inclusion list, the constructor, the class inheritance, the ImageButton declaration)

 #include "../JuceLibraryCode/JuceHeader.h"
#include "DJAudioPlayer.h"
#include "WaveformDisplay.h"

class DeckGUI  : public juce::Component,
                  public Button::Listener,
                  public Slider::Listener,
                  public FileDragAndDropTarget,
                  public Timer
                  
{

public:
  DeckGUI(DJAudioPlayer* _player,
          AudioFormatManager & formatManagerToUse, 
          AudioThumbnailCache & cacheToUse);
……...

// declaration looks good to me
ImageButton rewindButton{"REWIND"};

.cpp file (the relevant parts):

#include "../JuceLibraryCode/JuceHeader.h"
#include <iostream>
#include "DeckGUI.h"

DeckGUI::DeckGUI(DJAudioPlayer* _player, 
                  AudioFormatManager &  formatManagerToUse, 
                  AudioThumbnailCache &  cacheToUse)
                  : player{_player}, 
                  waveformDisplay(formatManagerToUse, cacheToUse)
{
………..

// button added, does what it is supposed to do, but actually not visible
 addAndMakeVisible(rewindButton);

…………………………………………….

// has listener
rewindButton.addListener(this);

// load an image file
const File  rwNorm = File("~/JUCE/Projects/OtoDecks/Source/ assets / tp.jpg");

// test
    if (rwNorm.exists())
    {
      std::cout << "rwNorm exists!!! " << std::endl;
      std::cout << "rwNorm.exists() returns: " << rwNorm.exists() << std::endl;
    }
    else
    {
      std::cout << "rwNorm does not exist" << std::endl;
      std::cout << "rwNorm.exists() returns: " << rwNorm.exists() << std::endl;
    }
std::cout << "file size is " << rwNorm.getSize() << std::endl;

// image button has its own place next to the other buttons
void DeckGUI::resized()
{
............
    rewindButton.setBounds(getWidth() / 2, 0, getWidth() / 2, rowH);
..........

// …the contradictory test results
rwNorm does not exist
rwNorm.exists() returns: 0
file size is 0
file format is JPEG

It says the file does not exist, supports that assertion with the file size, then correctly identifies the file extension as JPEG!

It’s not reading the path string, which is the argument, because JUCE spells jpg differently from me.

I get the same results with PNG files. I get the same results regardless of whether or not I use “const”, regardless of whether or not I test with the original file or an alias. I get the same results with a clean build. I get the same results whether I use the absolute path from root or from my home directory.

My ImageButton instantiation looks like this. “rwRef” just means I am passing the image file as a reference, as per the constructor instructions:

 rewindButton.setImages(false, true, true,
                         rwRef,
                        0.5f, Colours::red,
                         rwRef,
                         0.5f, Colours::blue,
                         rwDwnRef,
                         0.5f, Colours::green, 0.5f);

I am embarrassed to ask, but what am I doing wrong?

I assume JUCE must be able to read the file from my drive - proving the path is correct - then I must be missing something that keeps it from instantiating a File object. Am I perhaps missing a library, or a preprocessor definition?

The second issue is none of the colours come through either, the space for the button shows only the grey background colour. But when I click on the empty space I get:

  if (button == &rewindButton)
  {
    std::cout << "rewind button pressed" << std::endl;
  }

…a successful print-to-console

Instead of trying to load the image from disk, I’d recommend adding it to your Projucer project so it loads in as BinaryData. Then you can use the imported image like so:

rewindButton.setImages(false, true, true, ImageCache::getFromMemory(BinaryData::rewindImage_jpg, BinaryData::rewindImage_jpgSize), ...etc, etc...);

If you insist on loading it from disk though, then I’d double check that the file path you provided is accurate, and make sure permissions on the file and its parent directories are set to be readable.

It’s also possible that the error involves rwRef, can you post the code that instantiates it?

IT WORKED!!!

This is a relief! I have been working on this single problem from 6 am to midnite for two days.

You’re THE MAN, JoJo! Much thanks!

The code for my constructor:

DeckGUI::DeckGUI(DJAudioPlayer* _player, 
                  AudioFormatManager &  formatManagerToUse, 
                  AudioThumbnailCache &  cacheToUse)
                  : player{_player}, 
                  waveformDisplay(formatManagerToUse, cacheToUse)
{
    addAndMakeVisible(playButton);
    addAndMakeVisible(stopButton);
    addAndMakeVisible(loadButton);
    addAndMakeVisible(rewindButton);
    addAndMakeVisible(volSlider);
    addAndMakeVisible(speedSlider);
    addAndMakeVisible(posSlider);

    addAndMakeVisible(waveformDisplay);

    playButton.addListener(this);
    stopButton.addListener(this);
    loadButton.addListener(this);

    /**********************my working code for implementing image button********************/
    rewindButton.addListener(this);

    rewindButton.setImages(false, true, true, 
                            ImageCache::getFromMemory(BinaryData::rewind16Normal_png, 
                                                      BinaryData::rewind16Normal_pngSize), 
                            0.5f, Colours::red, 
                            ImageCache::getFromMemory(BinaryData::rewind16Normal_png, 
                                                      BinaryData::rewind16Normal_pngSize),
                            0.5f, Colours::blue, 
                            ImageCache::getFromMemory(BinaryData::rewind16Down_png, 
                                                      BinaryData::rewind16Down_pngSize), 
                            0.5f, Colours::green);

    /************************************************/

    volSlider.addListener(this);
    speedSlider.addListener(this);
    posSlider.addListener(this);

    volSlider.setRange(0.0, 1.0);
    speedSlider.setRange(0.0, 100.0);
    posSlider.setRange(0.0, 1.0);

    startTimer(500);
}

imageButton

Awesome! I’m glad that solved the problem. Hope you enjoy using JUCE!

is ‘rewindImage_jpg’ the path to the image?

Yes, IF the image file is in the same folder as your source code, which is what I did