I have gone through lots of tutorials which teach about layouts in Java Swing, but they don't seem to suffice my need. I am creating a solar system GUI using Java Swing, and i want to place the planets in the GUI according to the values i fetch from my micro controller, which are usually float point values. I cannot use the Grid Bag Layout, as to position a label i have to specify grid x and grid y, which cannot be the case since I receive float point values from the micro controller. The best resource i found is to use absolute layout where i can specify the position of the planet by giving mere X and Y Co-ordinates, which will be fetched from the micro controller. The problem I am facing now is that the absolute layout does not have auto re-size feature.
What would be the best possible option to adopt the auto re-size feature in absolute layout?
Swing tutorials were not generally meant for situations like this -- they were meant for people who want to write more normal GUI applications, using buttons, drop-down boxes, check boxes, radio buttons, menus, and have layout that follows currently accepted practices in terms of positioning those on the screens. If any of that applies to the part of your program that is not displaying planets, I encourage you to use what they have to say about it.
But you want to place things according to calculations of your own. I recommend doing that in a panel, calculating the size and position of your objects according to the size of the panel at the point of drawing. When the panel resizes, you will need to trap the event that says it is resizing and redraw. You will need to deal with your own minimums and maximums, etc.
I don't recommend the custom layout manager suggested elsewhere for a couple of reasons. Firstly, it won't save you any work at all -- you are still going to have to write the code that determines positions of things, if you just then draw your own graphic instead of attempting to position a UI element, I think it will actually be less work. And that's the second reason -- layout managers' purpose is to position UI elements within the panel, and the pieces of your solar system don't really have any need to be UI elements, just graphics on the screen.
Good luck.
Related
Just began GUI programming a few days ago and I am wondering how I know what dimensions to give my window and the objects inside of it. I know in my head what I want them to look like but I am just not sure how to know the measurements. Any tips?
Modern UI programming does not normally involve setting exact measurements of components in a window. You need to read a basic tutorial on Java Layout Managers; the basic idea is that you use the layout manager to arrange things so that they are lined up the way you want and stretch the way you want when the window's size is changed by the user. You put the components in the places that achieves the overall topological shape that you want, and you don't set a specific size.
Good luck.
I'm trying to develop a Java program that does the following:
uses a background picture of a network diagram of clients
positions an image of a bandwidth graph to respective client
refreshes the image of graph every 5 seconds which it fetches from another program that constantly produces snapshots of bandwidth
Now, I can set the background picture and I'm pretty confident that I will be able to refresh the images by using a timer. What I am trying to plan out is how I am going to position these images to the respective clients which is displayed in the background picture. I did some research and it appears that I have several options but I want to make sure I am choosing the right one before I run into problems further down the line.
It seems to me that using a GridBagLayout would be the choice for me, however I would like a second opinion for a more experienced population. If using a GridBagLayout is the correct choice, could you recommend any good tutorials that would help me understand this Layout Manager? Please keep in mind that I have limited experience with Java, especially with GUI oriented Java.
EDIT: If I am not explaining the concept well enough please let me know.
check this out-
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
GridLayout is likely to meet your needs and it is easy to use - the assumption I make is that image of bandwidth graph is the same/fixed ...
Look for an example here
http://www.roseindia.net/tutorialsearch/?t=java+gridlayout+color
Try Google the keyword "GridLayout" - there are plenty of hits ...
If you want to do advanced layouts, you should take a look at MigLayout.
It's an extremely flexible layout manager that can pretty much act as a replacement for any/all of the existing Swing layout managers. It's worth using if you want to do difficult / complex layouts.
It feels more like a HTML table layout tool, enabling multi-column spans etc. and arbitrary scaling rules.
The "Quick Start Guide" is very good with lots of examples - I'd suggest taking a look at that if you want to evaluate MigLayout for your project.
If the 'bandwidth graph' image(s) is on top of the BG image, look to OverlayLayout
A layout manager to arrange components over the top of each other. ..
OTOH I would not use a layout strategy for this, instead..
Create a BufferedImage the size of the BG.
Paint the BG to the image.
Display the image in a label.
When it comes time to paint the graphs, get a Graphics instance for the image in the label, and paint them to that. If the graphs are always the same size and shape and do not have transparency, you can simply paint them. Otherwise, draw the BG first.
I have just completed an application for my final year project and I need to create the interface for it now. The application will not include many different screens, just one introduction screen with a simple tutorial and the main screen with 5 JPanel and a JMenu. I have each part of the application providing its own JPanel, and the GUI I am about to make should put all those panels together and provide the intro.
What I want to ask is how I can properly set the sizes of different
components so that they are displayed the same on different screen sizes.(not getting really close to each other on small screens / big blank spaces on larger screens)
Should I manually set their preferred sized based on some percentage of the screen dimensions ?(e.g. 20% * width,40% * height) Or there is some other way to do it ?
Also, having one week ahead to complete this part, would it be any benefit to try and learn some library like MigLayout? I read a lot that is easier to use than standard Swing.
p.s
The JPanels include trees,textAreas,toolBar, buttons,checkboxes,comboboxes and textfields. Each one of those panels are quite simple to make.
The answer to this type of question is pretty application dependent, simply because what is 'reasonable' depends on the application and user expectations, but...
If you want the content of the frame to dictate the size of each frame, you can just call frame.pack() and an appropriate size will be guessed at based on the size requirements of the frame's children.
However, if it makes more sense to let the screen size dictate the frame dimensions, you can use Toolkit.getScreenSize() to get the screen size and do your positioning based on what you find.
I am working on a project for an online class I made the mistake of taking this summer and I need to build a gui to show how the huffman code algorithm works. The algorithm part is easy, its not very complicated. However im unsure what the best way to draw the tree(forrest) at each step. It would have to start out as just n nodes (with chars in them) on the screen and then you would press a "next" button and it would pick the two lowest nodes weighted (based on character frequency) characters and make them children of a new node (with just a weight - no char) and then update the screen/panel.
I have made swing gui before, my skills are nothing special but I know my way around. However im stuck on this implementation. I have a couple hundred lines of code written right now, but it doesnt work and I think its bad anyway, so I want to "start over" and plan it out better. So Id just like some advice on the data structure to keep track of the nodes and how to draw them on the screen.
I was using an ArrayList of JPanels as nodes and trying to draw them to a null layout. Im sure this is awful and id like to know a better way. Possibly GridBagLayout?
NOTE: don't say JTree.
A good option is to just use a library for drawing trees/graphs. I've had good success with Visual Library in the past.
Another possibility is Prefuse
Instead of wrestling with the different Swing layouts you could just do custom 2D drawing. See for a simple enter link description hereexample here on how to get started.
Use an image of a tree (only one instance) and an array or other data structure to contain the "data" that the algorithm uses. Think about how you can use the data to determine where the image should be painted. Use the repaint() after the algorithm runs.
[Next] --> Algorithm runs --> Update using repaint();
So you have a single frame, a single panel and a single BufferedImage object.
The trick will come in when you have to get slightly mathematical to know at what co-ordinates a node should be painted.
The layout of your components are insignificant, as you're not adding any components to the container, just painting image data onto it.
We all had that what you have once ;-)
First of all, never use Null layout because then you make sizes static and your application will not work on other resolutions like desired.
Best layoutmanager to use: GridBagLayout !
Why ? very flexible and you can get all components exactly on the place you want, discarding the resolution. Its harder to set up but better result eventually.
I have a large component (say width=4000px, height=200px) and would like to be able to see it entirely even on a small screen.
I don't see any easy way to do a wrapping component, my idea is the following :
given a factor (for example 4), the component would be of size 1000x800, by wrapping the child to 4 lines. The size requests would be translated in reverse to reshape the child, and so on. On painting, the component would call the paint(Graphics) of the child 4 times with a correct Graphics argument that would map the wrapped space to the child's space.
However, I can't see how to handle all the events : should I set eventlisteners for every children-generated event (PropertyChange) and for every parent-generated event (Mouse, Key, Resize, ....) ? This seems quite a lot of mapping, and I'd be happy to ear of an easier way of doing that...
I haven't looked too much at the JViewport implementation, but maybe this could help me don't you think?
thanks for your suggestions!
Frederic.
Edited to answer some of the comments that suggest to redesign the component :
Allow me to disagree here : making a component is one job, showing it is another. If I want to show it with scroll bars, I use a Scroll-Pane, whereas if I want to show it split in 4 lines, I want to use a similar solution.
I am the designer of the component in question (and had sharp words with myself, as suggested, but it lead me nowhere :-) ). I actually added "line-wrapping code" in it but it appears (really quickly!) that adding point space conversion, painting management in the codes of the component itself makes it really really messy, which is the reason why I imagine that a specialized component is a really a better solution.
Furthermore, making a custom component lets me reuse it far more easily as a "wrapper" for any other component.
Imagine if you had to recreate a JScollPane-like functionality every-time you use a JScollPane, dealing with scroll position, buffered painting and everything inside your own components : hopefully you don't have to!
You're approaching this the wrong way. It's the contents of the component, not the component itself you should be thinking about. If you want it to be 1000x800, make it that size. If the component has content - e.g. text or other components - calculate their positions appropriately. (You probably won't be able to use the standard layouts, and may end up writing your own). You'll probablky need to recalculate the layout if the component's width changes.
Don't call paint 4 times. If you've calculated the layout of the component, it's children or text, correctly then paint should just work.
In response to the comment: wrapping a histogram, in the sense of inserting arbitrary line breaks, is not likely to be useful. With graphical components the 'breaker' won't know exactly where to insert the breaks; you will also lose any information attached to the Y axis. Much better solutions would be to simply shrink the histogram in the horizontal direction until it fits the screen width, or to draw four histograms one under the other, duplicating the Y axis information for each. Alternatively allow horizontal scrolling over the whole histogram; or change the axes so the histogram is drawn horizontally. If none of the above work, perhaps because you have many hundreds of histogram bars, maybe a more interactive approach where you amalgamate some of your histogram bars together to give an overview, and allow the user to 'drill down' into the plot to get at the more detailed information.
If the issue is that you can't modify the original component, and it draws a fixed size image, then your best bet may be to call 'paint(Graphics)' on it four times with appropriate transforms and clipRects on the Graphics to draw the four parts 'stacked'. But frankly you may be as well off throwing away the original component. Histograms are not that hard to draw, and there are plenty of free plotting packages to help you. And be very rude to the designer of the original component if you meet them.
You don't mention scrolling. Put it on it's own pane and then put that pane into a scrolling panel.