You know in MS Word, you can write text and draw&put shapes anywhere you want.. in the text when you hit enter and get to a new line, the shapes below your cursor also moves down one line? I want to implement that property in Java on a pane, using components as the shapes and text. How can I provide absolute positioning for shapes but at the same time preserve the space between them? I'll appreciate any idea, cause I'm almost out of ideas.
Maybe you could use SpringLayout?
Spring layouts do their job by defining directional relationships, or constraints, between the edges of components. For example, you might define that the left edge of one component is a fixed distance (5 pixels, say) from the right edge of another component.
Related
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.
I am working on a bubble graph issue where the graph is distorted whenever the Y-axis labels are long
Ideally the graph should appear like the Normal.gif.
But if the labels are long, it is appearing like distorted.gif.
Hence , I tried to show only the first 15 characters of the labels followed by 3 ellipses (3 dots ...). But still there is so much space between the label names and the plot area.
Is there any way to reduce this space. Any idea which property of the graph controls this space. Also whenever the labels are concatenated to show only the first 15 characters, we need to show the full name when we hover the mouse over the name. How do we achieve this? Please let me know if you have any pointers on this.
<dvt:x1MajorTick lineWidth="0" tickStyle="GS_NONE"/>
<dvt:x1Title text="#{HcmGoalTopGenBundle['MenuItem.Performance.AddtoPerformanceGoal']}"
rendered="true">
<dvt:graphFont bold="true"/>
</dvt:x1Title>
<dvt:y1Axis majorTickStepAutomatic="false"
majorTickStep="#{bindings.YMinorTick.inputValue}"
axisMinAutoScaled="false" axisMaxAutoScaled="false"
axisMinValue="#{bindings.YLowerBoundary.inputValue}"
axisMaxValue="#{bindings.YUpperBoundary.inputValue}"></dvt:y1Axis>
<dvt:y1TickLabel>
<af:convertNumber pattern="#{applCorePrefs.numberFormatPattern}"/>
</dvt:y1TickLabel>
<dvt:y1MajorTick lineWidth="0" tickStyle="GS_NONE"/>
<dvt:y1Title text="#{hcmperformancedocspublicuiBundle1['OText.Potential.PotentialRating']}"
rendered="true">
<dvt:graphFont bold="true"/>
</dvt:y1Title>
<dvt:seriesSet defaultMarkerShape="MS_HUMAN"/>
<dvt:shapeAttributesSet>
<dvt:shapeAttributes component="GRAPH_DATAMARKER"/>
</dvt:shapeAttributesSet>
<dvt:legendArea position="LAP_RIGHT" rendered="false"/>
</dvt:graph>
I worked on this too..and found out that this is a framework issue. the same has been reported to the framework team
I'm perplexed by the "snapping" behavior of NetBeans GUI Builder - those dotted lines (and the magnetic force they exert) as I move components about within a container. Is it determined by the Layout Manager? Or by container properties such as Insets? I wouldn't have expected the Absolute Layout to have any "preference" about alignment, yet even it seems to have some notion of a "grid" toward which it pulls my components. How or where does one change this?
You have to use a work around to do this.
If you do...
...setLayout(null);
Then you will reduce the snapping to 10 by 10 pixels.
If you want to get better than that, you have to do something like this:
http://forums.netbeans.org/post-37209.html
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.