CSDGN Tale of the Lazy Programmer.

20Aug/100

Custom Java Look and Feel

I wanted to create a custom Java Look and Feel for a game I was working on. Of course I could have created my own windowing system (Again), however I didn’t feel up to this. Java already has a very use able and very complete windowing system, all I cared about was changing how it looked.

Of course my first thought was to just overwrite the paintComponent of everything I wanted to change…. but what about text? How do I get rid of those borders, the amount of work to get even simple functionality for the simplest of tools is annoying, just think if you made overwrote a list. Very painful!

Well of course I realized this and stopped to look for a better alternative. I know Java has pluggable Look and Feel. But I had never put much leg work into figuring out how to make my own, and all the other releases out in the wild looked monstrous and complex.

So I googled around, finding nothing on the actual ‘how’ of creating a custom theme. I decided to look at the Runtimes Environments own Look and Feels. This was a great idea. After only a bit of intense searching I found what I was looking for.

javax.swing.plaf.basic.BasicLookAndFeel

Well, I thought to myself. That looks mightly useful, but there is to much there. I need to cut things down some. A little googling I found a rather minimal if old custom look and feel and that helped me on making my own. Of course they use many things that are rendered unneeded in the latest JRE. Basically, override the obvious stuff. getDescription, getID, getName, isNativeLookAndFeel, and isSupportedLookAndFeel. Then hit the guts by overriding the initClassDefaults, this will put you well on your way to a custom UI. Of course then make your own versions of the XXYYUI.java classes, say BasicButtonUI is an example.

I recommended using the Basic as the parent classes for your L&F. It becomes somewhat difficult if you do not do so. Since it covers most of the basic events and such Java covers.

8Jun/102

Why art is frustrating

I was asked this by a friend. Why is art so frustrating? Good question.

It didn’t take me long to find an answer however. I have been over this question several times with myself already. I am the sort of personal perfectionist that given any task, I can master it very quickly. That is, if I put my full mind to it. However this only applies to left brain tasks, or logical step by step tasks. Perhaps being able to add or remove steps here and there, but all point a, to b, to c, to d.

Art, isn’t a simple step by step process. However much one wishes it could be. In fact it does not really have ‘steps’ at all except for the levels of build up (skeleton -> sketch -> re-sketch -> ink -> color). But this helps little with the actual process of doing each of those steps. Logical thinking is all step to step thinking. Sort of like a computer. You do this, then this, and then this. Creative thinking is more of a big picture, creating connections, and the like. Needless, we would be lost without either side. However the right (creative) brain rarely gets exercised as much as the left.

Because of this we are usually left with childlike ability in drawing, since that is usually when we ‘stop’ to goto school. Not to say schools don’t have art classes. But they do little to actually develop the creative right brain, instead focusing on much less frustrating left brain ‘artistic tasks’. Such as paper-mache, or other crafts.

The only way to get around this is to exercise the right brain. Drawing aimlessly and losing track of time in the process usually involves this. Its hard work, and you need to do it daily to ‘catch’ up. Even if it is non-sensual drawings. Other types usually involve visualizing objects in 3D and drawing them. Drawing what you see. Coming up with creative designs for whatever your interest is (cars, bikes, planes, birds, clothing, computers, etc).

P.S. There are other things that are also frustrating to learn, but not because of creativity requirements, but due to the scope of knowledge required. Such as language learning, and other areas you know little in (this is also another reason for art, studying anatomy helps, but isn’t as beneficial as observation).

Tagged as: 2 Comments
17Mar/100

Oct 10 is Binary Day

I here by designate October 10th to be binary day.

Why, follows are some reasons

1010 together create in decimal the number 10, this forms if you want to be extra geeky 101010 which produces the decimal number 42. This year it will already be 10-10-10, which would produce 42 all by itself.

Most people like to think of a binary day as all ones, but binary consists of both ones and zeros. But a 1 by it self, say in January, does not normally explicitly define the 0. I say 1-10-10, not 01-10-10. Which is no good, we need zeros!

So 1010 is perfect since it produces a binary number in decimal form, and the answer to everything when that 10 is added onto the original two.

Filed under: Informative No Comments
9Mar/100

Scrollbars revisited

Awhile ago I made a post on the behind the scenes scrollbar mechanics. I decided to type up a short Java class using my implementation. It is not ready to be put into anything in this form, but consider this another ‘example’ for how to put it together.

I have placed the example in the more section. :)

23Nov/093

Scrollbar Math and Mechanics

Well I found out very annoyingly there is not very much information on the Internet about the actual mathematics behind a scrollbar. What a scrollbar really, how hard could a scrollbar really be anyway. Surprisingly, pretty hard, if you do not take the time to think about it anyway. Explaining the actual math behind a scrollbar may take a little work so I am going to provide pictures!

Scrollbar

First off lets get some terminology out of the way, here I have a image explaining some of it, I realize not entirely perfect, but its enough for an explanation on scrollbars. The grip rides within the track. The track plus the grip is called a slider, the combined buttons plus the slider compose the scrollbar.

Now that we have that out of the way, now to time to discuss the actual mathematics. There are a few ways to handle the math involved, however most of them require the use of floating point numbers, which can be problematic on some systems without FPUs. Luckily most systems that require the use of scrollbars have fpus. But if it is a problem you can use fixed point decimals just as easily (but there is more work involved in converting to and from on a programmers part).

First off the size of the grip is determined based on the relative size of the window compared to the content that it slides over. This is very simple, it uses the same ratio, but in comparison to the track instead. You must keep in mind that a scrollbar has a minimum and a maximum size however. Luckily at this point, it is very easy deal with the size of the grip by just limiting the maximum size to the size of the track, and the minimum size to some convenient number specific to your implementation, I will use 24.

Note I am only using floats, this code can easily be optimized!
This is for demonstration purposes only!

Here is some psudo-code for your enjoyment:

float trackSize = 180;
float windowSize = 200;
float contentSize = 520;

float minGripSize = 24;
float maxGripSize = trackSize;

//0.4
float gripRatio = windowSize / contentSize;

//72
float gripSize = trackSize * gripRatio;

if(gripSize < minGripSize) {
        gripSize = minGripSize;
}
if(gripSize > maxGripSize) gripSize = maxGripSize;

Now that we have the grip size out of the way, things start to get a bit harder. We must now determine the position of the grip in the track. This is more complicated then it sounds. Because of the minimum and maximum size of the grip, and the fact that the grip is positioned based off its center, not off its top. Otherwise to scroll to the bottom of the content the scrollbar would fly right off the track! The region the scrollbar actually ‘scrolls’ is a subset of the area of the track, not the entirety of the track itself! Its actually trackSize-gripSize. This is the optimized form of trackSize – (gripSize/2 + gripSize/2), since each side of the grip cuts off scrollable area on the track. But since we will work with the top position of the scrollbar, we can ignore this and use the optimized value.

The positioning again requires a ration of the window and content, but in this case we determine how far down the content the window is displaying. I visualize it as a window overlooking the content, which is sorta the idea, and why windows are called windows. Just how you define how the window displays over your content is left up to you. For a list it could be for each item in the list, or for say a web browser it could be for every pixel down from the top of the content it is. In the end it doesn’t matter, the math is the same for any given unit.

Now for more psudo-code, please note I am carrying over variables from the previous set of code:

float windowPosition = 40;

//108
float scrollSize = trackSize - gripSize;

//0.08
float scrollRatio = windowPosition / contentSize;

//Take Note: This is for the top of the grip
//8.64
float gripPosition = scrollSize * scrollRatio;

Now that we have both the Grip Position and the Grip Size, we can easily render it without problems, and because it was limited above in the first bit of code, we do not have to worry about figuring out what if its at the bottom of the scrollbar and also the minimum size, and other special cases, since that has already been covered! It looks fairly simple now that I have the code down right, but just trying figuring it out the first time yourself, its not as simple, especially if your new to working with hand made user interfaces.

There is obviously more to this, for reference the buttons normally move the scroll position up and down by a single unit. Clicking above or below the grip in the track causes the window to move up by the size of the window, or alternatively by the size of the window minus some magic number. This is so it is easier for people to keep track of where they are and the like.

Also keep in mind when a mouse clicks the grip, it rarely clicks the exact top of the grip or the exact center, or the very bottom, remember this when calculating the moved distance for the grip drag. For these cases I supply you with some code to help you out with grip dragging. Generally we take the movement the mouse moved along the axis of dragging. Then we do the reverse of what we did before to get the new window position.

Even more psudo-code:

//This is the distance between the last mouse position and the new one.
//This only matters along the axis of the slider.
float mouseDelta = newMousePosition - oldMousePosition;

float newGripPosition = gripPosition + mouseDelta;

//Limit it so it is not out of bounds
if(newGripPosition < 0) newGripPosition = 0;
if(newGripPosition > scrollSize) newGripPosition = scrollSize;

//Just reverse the algorithms we did before to get back
//to the windowPosition
float newScrollRatio = newGripPosition / scrollSize;
windowPosition = newScrollRatio * contentSize;

I hope you enjoyed my first informative posting here on CSDGN! Feel free to comment.