• Media Player 08.10.2008

    Maybe the most important part of a good media player is how usable it is and how good it looks when minimized. Ultimately you should be able to do everything you can do with the full interface yet the real estate should be as small as possible and never be in the way. Obviously there is a lot of hard decisions to make since we don’t live in the ultimate world. Yet.

    Currently I have two smaller versions of the GUI. Mini and micro. They should both be dockable to a side of the screen where only a “tab” will be visible when it is semi-hidden. Not sure if that tab will show any info or expose any functionality though. This might even have to differ depending on the platform. There are also the mini-icons available in almost all OS and I don’t want to make a special case for using this media player, so it should play nice with that too.

    In the screenshots both versions have the bottom attached see-through pulldown panel. They’re there for the time being but I am unsure if they will make it to the final version. I’m worried that it will look a bit too cluttered, especially for the micro version. Opinions are appreciated.

    I have made some smaller changes to the main window as well. Nothing much but I post a screenshot anyway. Changes are mostly around the scrollbars, media add buttons, and I have added a new, or possibly alternative, left panel in the tracks tab. It is a filter panel and only what’s selected will be visible in the tracks list. Normally the user shouldn’t have to be bothered by the actual physical location of the media files, what’s playable is there, but power users and more curious normal users must have an easy way to know what’s where. The acute reader might notice that there seems to be no obvious way to once you have started filtering go back and “show all”. This is something that needs to be resolved. Possibly with a button that is only visible when there’s some filtering applied.

    I have now finished the first round of designs and I have actually started coding. Wohoo! I haven’t come that far yet but many parts of the main window is there. Some might say that I am approaching this from the wrong end, starting with the GUI, but I think it’s the only way to do a really good UI. When you have no backing services, other than a home made demo collection of songs, it is easy to get the GUI right and you won’t be tempted to model the GUI after the data, which is by far the most common mistake when you see a crappy UI.

    I have shadows, buttons, button glow and fast gradings done already through my already made Decorator implementation, which I have borrowed from migcalendar.com. With it, it is easy to create such effects and they are of course cached in intermediate images when needed. For shadows and glow this means always since they are created with a Gaussian blur filter. I have not yet implemented the fast version of that algorithm that Romain Guy and Chet Hasse introduced in the excellent book Filthy Rich Clients, but I will.

    Talking about speed I made a very interesting discovery when I made the tracks TreeTable component. If I overrode validate() to do nothing in my JComponent subclass (used as a TableCellRenderer) the performance of resizing + repainting the JTable was increased 30 times (yes times!). Before that resizing of the window was slow as Java 1.0, but now it is actually pretty fast. This is on Leopard with Java 1.6 and I haven’t tested if the speed increase is the same on the uglier platforms. πŸ˜‰

    Next week I aim for having a WebStarted demo of the GUI. Lets see how that goes. Currently I am struggling with customizing row selection in the JTable. Looks like I have to write my own ListSelectionModel. So Swing..

    Posted by mikaelgrev @ 17:37


  • 11 Responses

    • wismax says:

      Hi, I can’t wait to test your WebStart demo. Keep up the good work ! Your GUI is very nice. Are you gonna release it with an open-source license ?

    • Mikael Grev says:


      It won’t be Open Source, at least not from the start.

    • mats says:

      All renderers that are used as a “rubber stamp” like table/list/tree renderers should override validate, invalidate, revalidate, repaint, and firePropertyChange to do nothing.

      The reason you have to do this is because none of the usual jcomponents were created to be used this way and not overriding these methods will cause a lot of extra repainting. This hurts performance A LOT when invalidate is called on the component because it then (by default) checks the whole hierarchy the component is part of to check if other components also need to be invalidated.

      This is also the reason you should never use JLabel as a TableCellRenderer (or any other type of renderer) because Sun created default renderers (DefaultTableCellRenderer) that are optimized for this purpose. To learn more, read the javadoc on these default renderers:


      However, if you create very special type of renderers (that change structure for every row/node) you might have to call revalidate/invalidate yourself on these components before they are actually used to paint anything. I have created renderers that do this. For instance if you want to create a ITunes style album table πŸ™‚

      By the way if you want to try a demo of my player app, you can get it here:

      A couple of things about this demo:
      1. It is not finished by far so it contains bugs and unfinished functionality
      2. You need the very latest Java version (Java 6 Update 10 RC2)
      3. It is windows only (support for linux almost done though)
      4. Right click on library to add songs πŸ™‚

    • forum says:

      Hello, very interesting blog, can’t wait for the next posts.

      About the gui, I always maximize the applications I use; how will the expandable tabs behave in that case? Will it shrink the main part when clicked?

    • […] Grev promises imminent availability of WebStart version of his media player. Currently hehas no plans to […]

    • Mikael Grev says:


      Thanks for the info. I will look at your player for sure. I just need to boot into Vista… And it always takes an effort to do it since there’s always some new problem surfacing when i do. πŸ˜‰


      I elaborated a bit around that in an answer to the second part: http://miginfocom.com/blog/?p=16

    • wambo says:

      looks cool, eager for the webstart version. I hope you’ll include last.fm support.

    • Mikael Grev says:


      Yes, that’s the plan. Though I have not looked at the legals around that yet.

      The Web Started version I am referring to is just parts of the GUI though. A more functional version will take a lot longer than one week to develop. πŸ™‚

    • Bill says:

      Looks very polished. I know you are targeting everyday users with the application – but have you considered making it open source so to serve as an example app for Swing developers?


    • Mikael Grev says:


      There are a few comments about this in the earlier parts and here: http://www.pushing-pixels.org/?p=596

    • Tbee says:

      “All renderers that are used as a β€œrubber stamp” like table/list/tree renderers should override validate, invalidate, revalidate, repaint, and firePropertyChange to do nothing.”

      Hm. This was quite a revelation for me. However, I’m having troubles implementing it. I have complex cell renderers… To be exact: I have complex cell editors, containing two textfields and two buttons (key & description textfields plus zoom & search buttons) inside a JPanel. The JPanel is the cell editor component.

      Because you want the buttons on exactly the same location in the renderer as in the editor, I have a editor-to-renderer wrapper. I cannot disable the mentioned methods on the wrapping JPanel, then it isn’t painted anymore. Invalidate and validate must stay.

      Are there any good guides on how to build complex cell renderers?