wood burning stoves*
The moose likes Beginning Java and the fly likes how graphics are coded Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "how graphics are coded" Watch "how graphics are coded" New topic
Author

how graphics are coded

T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
As I've said elsewhere, before Java the only programming language I had any real success in learning was BASIC, and thus I'm constantly getting tripped up trying to adjust to the flow of an object oriented language. In BASIC, if I ever wanted to animate something I had to create a loop that would constantly rewrite the pixels. If I wanted this animation to cycle while simultaneously running other processes, the only thing I could think of to do this was to mash the elements of both processes into one loop which tried to do both at the same time. This was confusing and ultimately prevented me from getting most of my projects from working properly.

As I spent today reading and rereading and rerereading Oracle's tutorials I got the distinct impression that object oriented graphics programming does not operate in this way, which leaves me with, on the one hand, hope that I can simply code the separate elements which I desire to run separately without mashing them together, and, on the other hand, a complete confusion as to how one is supposed to achieve this. I am left with the distinct impression that the Swing documentation was written by people who already understand how to write an object oriented GUI for people who already know how to write an object oriented GUI. I suppose I have a couple of questions. I'll start with just this one for now:

Is it possible to write what would basically amount to separate programs, one of which to control the graphical output which is capable of running on its own indefinitely if need be, and another which does the thinking for the program and only loosely tells the former program what to do? I've been writing part of the AI for sprites I want to move around the screen. I want these sprites to fidget on a regular timetable. I somehow feel it would be problematic when my AI is running methods nested within methods nested within methods if all of these methods have to have code within them that keeps a counter and triggers a fidget on the screen.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18153
    
    8

T Shaw wrote:I am left with the distinct impression that the Swing documentation was written by people who already understand how to write an object oriented GUI for people who already know how to write an object oriented GUI.


Yes, your impression is right, the documentation is targeted at people who will understand that documentation. But on the other hand attempting to learn Swing by reading the documentation was never a good strategy anyway. That's what tutorials are for, and Oracle's tutorial is very good. So instead of inventing your own wheel I would strongly recommend working your way through it. Here's a link: Trail: Creating a GUI With JFC/Swing.

Personally, every time I have wanted to learn about some part of Swing I have started with the Oracle tutorial, taken the example code, and worked with it to change it into what I needed.
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
think along the lines that the GUI is simply the 'view'.
it will display what it's told to display.

there may be some controls e.g. left/right arrow keys to determine which direction etc.

all of the processing of what goes where, or how long it's there etc., is done separate
from the GUI, via a separate thread, a timer or a SwingWorker. Swing is single threaded
and if you put any long running task in that thread (the EDT) then all painting and
listening will be blocked, and you GUI will not work properly.

also, from your separate processing method/s, if you need to update your GUI, update
it in the EDT via SwingUtilities.invokeLater(...)

you can also run into problems if you don't start your GUI in the EDT
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
I suppose this leads to my second question. If the basic code structure I'm supposed to use goes like this:

Make a GUI
Run a function {
do stuff
write the results of that stuff to the screen}

How does one best code that? Do I have to pass the JFrame object and all the objects being written into it into each function I run which changes the output so that they have something to change? Or can the methods I call be told to write straight to the screen once I've created the environment I'm drawing to? In the former case it seems I'm going to end up passing a lot of parameters to a lot of functions. I've already been told once that I write too tightly coupled code, and so this seems like less than ideal coding practice. In the latter case, don't I end up writing methods that will crash my program if I don't initialize them right? It strikes me that this will make my methods difficult to call in other contexts. In either case, going back to what I asked the first time, is there no way to get around mashing together bits of multiple routines if I want to code them to run at the same time?

For example, take all the functions that are running right now on my computer. this page I'm typing in right now has to check to see if I'm making keystrokes, and if I am, it writes data into memory which it then displays in this text box I'm typing into (or something like that, I assume). At the same time, it has to check to see where I'm moving my mouse, and if I click on something, it has to run some function based on what exactly it was my mouse did. All the while, there's this little fly buzzing around the moose head in the upper left hand corner of the page. Is this page really written such that there isn't one process for the text, another for the mouse, and yet another for the moose? Does the programming really have just one keyboard-mouse-moose management function? And how does Java function like this or not like this?

Also, I have taken a look at the examples given in those tutorials, but my learning style makes it difficult for me to just glance over a page of code and move on to something else. To really feel like I understand something to the point of being able to apply that knowledge to another lesson, I need to get the hang of manipulating the commands myself - changing some parameters and seeing how things come out differently. That hasn't been working out for me very well. Looking at their hello world example, I grasp that JFrame frame = new JFrame("String") makes a window of name string, and that setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ends the program when the window is closed, but .pack() and .invokelater() are totally unexplained to me. And NetBeans got positively irked at me when I tried moving the createAndShowGUI() method to a separate class. The example program declared this as a private static void for reasons it didn't explain (well, I suppose I understand why void) and apparently I can't run it as that from a separate class file.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7081
    
  16

T Shaw wrote:I suppose this leads to my second question. If the basic code structure I'm supposed to use goes like this:
Make a GUI
Run a function {
do stuff
write the results of that stuff to the screen}
How does one best code that?

OK, well here's my take on it:
You have a problem (your 'do stuff'). What is it? Is it a game of chess, an automatic teller, a shopping basket, or a system for stocking shelves?
Work that out first and forget the GUI. In order to test it, you may have to write a rudimentary user interface, but my advice would be to stick to the keyboard and console if you possibly can. There are some problems which are difficult to implement without a GUI of some kind, but they're relatively rare (thank God) and usually highly specialized.

When (and only when) you have the problem part of your code designed and working (at least in principle), start thinking about the GUI. And furthermore, do everything you can to keep the two things (the problem and the GUI) separate.

GUI design is a bit of a black art, because it involves different parts of the brain. I'm constantly amazed at how good some people are at it, because I'm totally useless.
First: I don't like it; I find it tedious, fiddly and verbose - I'd much rather be designing an inventory system, or a CuckooHashMap, than mucking about with frames and sliders and buttons and colour schemes - but I understand enough to be able to be able to write a decent mock-up, and also enough to know the kind of information that a GUI is going to need to do it's job.

Once again: keep the problem and the GUI separate. It's the best advice I can think of.

HIH

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Artlicles by Winston can be found here
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
How would that separation impact functionality? Say I have a button on the screen and I want it to do something when I press it. Do I have to keep writing code at every step in my problem to catch if the button's been pressed so that the computer stops thinking about the problem and pays attention to the button? If so, wouldn't limiting interaction between the GUI and the problem by trying to strip out bits of that button checking function so that they're not ubiquitous in my problem potentially cause the program to become unresponsive if my non-gui part of the program is in the middle of running a long process which doesn't constantly call the check input?

I suppose I'm still fuzzy on what the ideal architecture is for managing input/output and running the part of the program that analyzes the input to produce an output.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18153
    
    8

T Shaw wrote:Say I have a button on the screen and I want it to do something when I press it. Do I have to keep writing code at every step in my problem to catch if the button's been pressed so that the computer stops thinking about the problem and pays attention to the button?


Short answer: No.

Long answer: No, read the tutorial and it explains how Swing works.

Really. What you said there is about as far from being right as possible. But that's normal, if you've only ever written code in which you control what happens all the time, then writing GUI-based code is completely unintuitive. So asking questions like that is fruitless. Put away your preconceptions and go through the tutorial.
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
-edited to remove snippyness-

I have already tried reading those and do not find in them the answers for the questions I have.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60072
    
  65

Getting snippy with people who are trying to help you is hardly a winning strategy. I suggest a different approach.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
Apologies, but I bristle easily at being told to go read something when I'm trying to say that that's not working.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18153
    
    8

Well, I'm sorry, but if you can't learn from those tutorials then I think you're out of luck. It's true that your questions so far indicate that you aren't getting it, but they also indicate that you are burdened with a lot of incorrect assumptions. So stop asking those questions. The only way to get rid of your assumptions is to look at good programs.

So did you get to the second page? (Hint: You don't need to pass an exam on the first page.) Did you download and run the HelloWorld.java code?
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24168
    
  30

T Shaw wrote:-edited to remove snippyness-

I have already tried reading those and do not find in them the answers for the questions I have.


Let me suggest this, then. Choose a simple graphics tutorial that's not from Oracle (man, I still hate saying "Oracle" instead of "Sun"!) -- for example, here's one: http://profs.etsmtl.ca/mmcguffin/learn/java/01-drawingLines/ . In fact, this is the first in a series of a dozen simple graphics tutorials that should put you in a good place to strike out on your own -- the entry page is at http://profs.etsmtl.ca/mmcguffin/learn/java/ .

Why don't you work through it, and come here and ask us any specific questions that come up: how does it work, why does it work, "I expected X but Y happened instead," etc. We can fill in the missing information, and I guarantee by the time you've gone through these, you will be writing games like an old pro.


[Jess in Action][AskingGoodQuestions]
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
here's a very simple example of what you'll face if you don't follow all the advice given so far.

compile this code
before running it, make sure you know how to kill it other than the 'X'


when you run it, follow these steps
1) move the frame around the screen
2) minimize it, then restore it
3) click 'Stop' button, one or more times

when you've seen what happens, now click 'Start' button,
and try to repeat (1) to (3)
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
I don't have any dear attachment to assumptions of any kind. The questions which I am asking represent how I would go about guessing how to run a GUI if I had to use the kind of programming I grew up doing. I understand perfectly well that Java can't be coded that way - the programs would be monstrous and unmanageable. I am thus putting these questions out there so as to show how I am thinking so that someone can tell me how to think differently.

I typed out the HelloWorld.java code and got it to compile. The tutorial for it taught me that this code makes a frame that says hello world. It didn't teach me why this code makes a frame that says hello world. And that is a critical problem for me. There are elements I do not understand in it which it did not explain.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18153
    
    8

I do have one gripe with the Oracle tutorial, now that I look at it: it suggests you develop your GUI code in Netbeans. First of all having to install and learn how to use Netbeans is a major diversion from the goal of learning Swing programming, and second, developing Swing GUI code with Netbeans doesn't teach you how to develop Swing GUI code.

So I suggest skipping that whole section and going on to the part headed "Using Swing Components".
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
Ernest Friedman-Hill wrote:

Let me suggest this, then. Choose a simple graphics tutorial that's not from Oracle (man, I still hate saying "Oracle" instead of "Sun"!) -- for example, here's one: http://profs.etsmtl.ca/mmcguffin/learn/java/01-drawingLines/ . In fact, this is the first in a series of a dozen simple graphics tutorials that should put you in a good place to strike out on your own -- the entry page is at http://profs.etsmtl.ca/mmcguffin/learn/java/ .

Why don't you work through it, and come here and ask us any specific questions that come up: how does it work, why does it work, "I expected X but Y happened instead," etc. We can fill in the missing information, and I guarantee by the time you've gone through these, you will be writing games like an old pro.


All right, I've worked around with exercise 1 and these are the questions I'm running into.

1) I see this is an applet, and I'm not sure how the flow of an applet program works as distinct from a program with a Main(). There are two methods, but these aren't being called from somewhere else. Does the applet simply run both methods one after the other automatically? If so, what is the advantage to writing the code inside a method? I know that if this class were called from some other program, it would be good to separate the part that creates the screen from the part that fills the screen, but insofar as it pertains just to this one applet, would it make any difference if the text inside init() and paint() were on the same footing as the int width, heigth; line?

2) Say I wanted to use these functions in a standalone program with a main, not as part of an applet. I have a copy of the frame demo from here: http://docs.oracle.com/javase/tutorial/uiswing/examples/components/FrameDemoProject/src/components/FrameDemo.java. If I try using setBackground() or getSize() exactly as the example used them, I get errors: Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous sym type: setBackground
at frametest.Frametest.main(Frametest.java:38). Public void paint () takes a Graphics g object, methods of which are used to draw the lines. But I can't create a graphics object using Graphics g = new Graphics() because "java.awt.Graphics is abstract; cannot be instantiated".
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
the difference between the two is that applet is already a container (extends Applet) so setBackground(...) on its own overrides the applet one,
whereas in the frame demo, the container/window is a created one:
JFrame frame = new JFrame("FrameDemo");
so you must use that reference:
frame.setBackground(...)

but don't get involved in that just yet because you really don't want to do anything with a JFrame except size, closeOperation, location, visibility,
and to add to it (normally) a JPanel that holds the majority of your GUI stuff.

paint() - do not override this is Swing, always use a JPanel and override paintComponent(...) <---this is where java will provide your Graphics object,
you don't create it yourself, and if you see examples that use getGraphics(), generally not a good idea.
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
Where precisely would you put frame.setBackground in the frametest in question? The frame variable is defined in createAndShowGUI(), so when I try to cite it in main to change the background color, the editor is telling me it doesn't know what frame is. Can I even edit my JFrame from main?
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
> so when I try to cite it in main...

use main() *only* to start the program.

you can't do what you're trying because of the 'scope' of the 'frame' variable
JFrame frame = new JFrame("FrameDemo");
is local to createAndShowGUI()
it cannot be referenced outside of that method

you would need to have the declaration as a class field,
say, immediately beneath
public class FrameDemo {
then main() can 'see' it,but that will create another problem,
so try it and see the problem

T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
Ah, the non-static variable in a static context error. This one I have come to know fairly well.

So drawing to the GUI takes place only within the class I define the JFrame in? Now this is where I got tripped up earlier. If nearly everything my program does has to write to the GUI, or at least has to tell the GUI to rewrite itself, do I have to subordinate all the rest of my program to createAndShowGUI? Or is the proper way to go about this to keep the logic of my program in some other class which runs in tandem with my GUI process (through principles I don't yet understand)?
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
> Or is the proper way to go about this to keep the logic of my program in some other class which runs in tandem with my GUI process (through principles I don't yet understand)?

that's basically what all the earlier suggestions are.

here's a simple demo (quick and dirty!), just to give you something top play around with

I've used the FrameDemo code from your earlier posted link, but stripped it to just the frame.
then the separate class, BouncyBall, has been added to the frame.

in BouncyBall, normally a Timer would be used for the animation, but I've used a separate Thread to show you how it works.
change a few things, see what happens



for simplicity, it's all in one file
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
Threading strikes me as if it's going to be difficult to grasp. But that does explain a little more to me about how processes are managed.

Now, say I want a hundred things on screen, and I want to save the parameters about them to a bunch of objects. So far these programs have consisted of a main() method that calls a createAndShowGUI() method which includes a class which is an expansion of JPanel which has a public method of the same name as the class, which I take it is the class that more or less automatically runs the code inside it whenever the JPanel is called in the createAndShowGUI(). So I figure, I'll make a class called tile which holds my x and y values, and I'll make an array of them. Then I'll write a method to assign them x and y values based on where they are in the array, and then I'll use those values to paint them to the screen. So thus far I've written



but the paint component doesn't know what the array is which I defined earlier. Originally, I defined that array outside of public TilesPanel(), much as Bouncy Ball defines its variables directly into the class (which as I understand it would make the data visible to the paintComponent, just like it can see the x and y defined before the methods in that program. Am I mistaken?), however the compiler has a fit if I try to use a for loop outside of a method.

Second, when do I use @Override? You have it in Bouncy Ball, but when I stick it before my paintComponent, the compiler says this method doesn't override anything. What did your program do to need an override that mine doesn't?

And I suppose third, is the above typically considered good form at all? I have another program I'm writing that already initializes an array of tiles for the logic to use to perform calculations about where to move other objects over these objects. It seems redundant to create the data twice in different places.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18153
    
    8

T Shaw wrote:Second, when do I use @Override? You have it in Bouncy Ball, but when I stick it before my paintComponent, the compiler says this method doesn't override anything. What did your program do to need an override that mine doesn't?


No, you have it inside out. Your code DOES need to be overriding the paintComponent(Graphics) method, but it isn't. And using the @Override annotation tells you that, so that you don't spend days of frustration trying to figure out why it never gets called.

And since the compiler says your method doesn't override anything, that's a problem which you need to fix. You need to look at the declaration of that method and figure out how it differs from "public paintComponent(Graphics)".
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
when I rewrote some code using another program as template, I ended up rewriting it as public void paintComponent() and then the compiler told me to stick in an override, so I did. But then what's special about the code starting at line 68 in Michael Dunn's example, such that it needs an override, but if I use the same format, protected void paintComponent(), it says it doesn't override anything?
T Shaw
Greenhorn

Joined: Jul 29, 2012
Posts: 27
Oh. The typo. Well that was dumb.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18153
    
    8

T Shaw wrote:Oh. The typo. Well that was dumb.


Everybody does that from time to time. The point is, using @Override tells you there was something un-kosher about it. If you hadn't used that, then the program would have compiled fine and you would then have had to figure out why your misspelled method never got called. This typically takes the form of using more and more debugging statements and using harsher and harsher language as none of them do anything. At least in my experience it does...
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7081
    
  16

T Shaw wrote:Now, say I want a hundred things on screen, and I want to save the parameters about them to a bunch of objects...

I'm certainly no great expert on GUIs, but I am (these days) a competent Java programmer; and as someone who started out with COBOL and C, I've had a long, hard road to "get over the hump" of thinking procedurally.

Trying to think of GUI components in a "first this happens and then this..." or "what's the sequence of events when I do this?" is likely to drive you mad; and the best advice I can give you is to step back and try and look at it as a set of independent components (mouse, buttons, sliders, etc) that interact with each other. It is hard (believe me, I know), but all I can tell you is that when it finally clicks and you 'get it', the satisfaction is amazing.

One old problem I remember that may help to illustrate what I'm talking about is what I call the "traffic light problem":
You have a crossroads controlled by a set of traffic lights and sensors in the road that detect traffic flow. Write a program that delivers a reasonable flow of traffic through the crossroad in both directions.

It is possible to work it out in procedural terms ("car A comes alone lane a, I do such-and-such unless car B comes along lane b at the same time..."), but it's quite messy and probably maps to a huge and complex nested 'if' statement.
An OO programmer, on the other hand, will look at this as simply a set of 4 TrafficLight objects, probably working in pairs, that interact with Sensor objects, and work out what it needs to do when it receives a 'hit' from a particular Sensor. It might also have a Timer that dictates what it does if it hasn't received any Sensor input for a while, or that governs a "phase" of operation.

Now add in a left-turn lane (or right, if you're in the UK) for each direction. The 'procedural' approach now balloons in complexity; but for the OO programmer, it's just another 4 TrafficLights and possibly some new rules to be added. In fact, the OO solution is likely to mirror the actual engineering solution in terms of traffic lights, sensors and timers much more closely than a "do this, then do this" one.

Hope it helps; as I say, I've been through what (I think) you're going through.

Winston
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: how graphics are coded
 
Similar Threads
Graphics/Sprites Protection
Questions regarding to using applets and JComponents
assembling a complex structure
Most efficient way to use a spritesheet?
Use of threads in games