I am using a ChartPanel from JFreeChart (1.0.14) to display some plots. The Layout is handled by MigLayout and all works well. However, I have strange behaviour from time to time. The minimal size of the panel changes sometimes when the plots change. I am not setting it in my code but leave everything to MigLayout.
Unfortunately I am unable to reproduce this behaviour in an SSCCE, especially the first S. But in my application it also occurs when I am just changing the renderer to display a thicker line for one of the XYSeries.
So my question:
Is it possible that the layout parameters are changed within the code of JFreeChart depending on the displayed content?
If so, is it possible to turn off this behaviour? Because I don't want anything else than MigLayout to lay hands on the layout parameters...
Ok, I figured out the problem. My ChartPanel is in a TabbedPane with other tabs. One of those other tabs also contains charts. And one of those charts has a logarithmic range axis. Now I put in data that contained negative values, which can not be displayed logarithmically and the reaction of the axis was to just zoom out in both directions as much as possible. This resulted in extremly long axis labels (0.0000000[..]00001 and 10000[..]0000). This resulted in MigLayout giving more space to this panel and recursively also demanding more space from the tabbed pane. So the tabbed pane grew also for my other tabs.
Quiet strange and hard to figure out... ;) Thanks to trashgod for your willingness to help. :)
Related
I'm working on my first Swing application and I'm having a layout problem concerning a dialog window I created for my users to enter values in certain fields. Because the number of fields displayed varies based on a user choice, I use a JScrollPane in my dialog, setting its viewport to a panel to which I add my field components.
For every field to be displayed, I create and add three components:
"field name" label
Field component (usually a JTextField, but it also could be a JComboBox or a JDateChooser control)
"field type" label
i.e.
namelabel: |____| (String)
name2label: |__| (Number)
All three of these components can be of varying lengths, so my challenge has been to find a tidy way to layout these components. What I've been doing is setting the layout manager for the main pane to be a BoxLayout that uses the y-axis (i.e. it lays out components vertically). I then create a pane for each field, set the layout manager for that pane then add all three field components to that pane. I've tried both a FlowLayout and BoxLayout for the individual panes, and I've had issues with both of those layout managers.
I set the FlowLayout manager to use a left justification, but due to the varying lengths of the components, this led to a crooked-column layout. I set the BoxLayout to use the X-axis (i.e. lay things out horizontally) but the consequent centering of the components resulted in a vast spacing between each component. And prior to using individual panes, I tried to use GridLayout but I was never able to get it to honour my three-column requirement, causing the fields to be split across rows. I also looked briefly at an article about the GroupLayout manager but it seemed intimidating :)
Does anyone have any suggestions on how to layout a varying number of rows of three components of varying length within a JScrollPane in a neat, compact way? Thanks in advance...
Sheldon R.
It's a common problem: MiGLayout is a good choice. Alternatively, BoxLayout is illustrated here, and Group Layout is shown here.
Also take a look at SpringLayout.
Update: My three-column idea didn't work out for the same reason most of my other ideas didn't work i.e. BoxLayout, like most of the layout managers, tends to expand the component to fill as much space as it can, so my fields were being rendered as enormous :)
So I bit the bullet and tried to figure out GroupLayout, based on the example shown by #trashgod being similar to what I was trying to achieve. After figuring out how to do what I wanted in the GroupLayout way, I initially ran into the same expanding-field issue. Then the Oracle GroupLayout tutorial showed me how to keep the components from being resized i.e. using the four-argument version of the addcomponent method: addComponent(field, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) I tried that and it worked like a charm. Thanks again, #trashcan for pointing me in the right direction, and thanks to everyone else who chimed in with ideas...
Sheldon R.
I'm trying to place a component on the corner of the window. However, my window has a scrollbar and the scrollbar is placed on top of the component.
So I'm trying to change the position of the component so that it is adjacent to the scrollbar rather than have it be under it.
Thus, I need the standard width of a scrollbar (vertical) and the standard height of a scrollbar (horizontal).
I could try getVerticalScrollBar.getWidth() at runtime, but unfortunately I need to place the coordinates before I create the scrollbar themselves.
Also, creating an empty JScrollBar and calling getWidth() is returning 0.
Thanks for your help.
Not sure if it helps you right now after a year ago, but:
int scrollBarSize = ((Integer)UIManager.get("ScrollBar.width")).intValue();
I found it here on this discusion: http://www.coderanch.com/t/341287/GUI/java/Calculating-width-JList-vertical-scrollbar
Don't get the size or set the size but rather let the layout managers do the work for you. Consider
adding the scrollbars by default to the JScrollPane via the setVerticalScrollBarPolicy(...) and setHorizontalScrollBarPolicy(...) method pair so that the layout managers take the scrollbars into consideration when laying everything out from the get go.
Avoid null layouts at all costs as this will take away one of the most powerful tools for creating flexible workable Swing GUI's.
If these recommendations don't help, then consider creating and posting an sscce.
I'm not sure about other OS's, but on windows XP it is 17 pixels.
What I would do is temporarily include this line in your program:
System.out.println(jScrollPane.getVerticalScrollBar().getWidth())
then use the value printed.
I am trying to create a GUI for a program with an undefined number of rows but stay with two columns. Currently the only way I can get it to look how I want is using FlowLayout but the window of course needs to be smaller than desired. It needs to happen within one panel as well because it is being added to a tabbed pane.
What would be the best layout manager to solve the problem that is in the JDK? Or would just kind of brute forcing it with AbsoluteLayout be the best approach (as the user shouldn't really be resizing the window)?
I have attached the desired appearance.
Thanks for any help in advance.
Several layouts can do what you want. I'd suggest GridLayout (easy to use, but columns will be equal width) or GridBagLayout (harder to use, but you have lots of control). You could also use a BorderLayout and put all the fields in a sub-panel on the WEST and all the drop-downs in a sub-panel on the EAST. The difficulty with that is ensuring that the rows have the same height, since they won't be constrained by the layout itself.
The best thing to do would be to go through the Java tutorial on layouts and get up to speed on what the various layout managers can do.
Also, since you're using Swing, you could just use a JTable (as Gilbert Le Blanc suggests in his comment).
I'm trying to provide a progress report for a slow operation, in the form of text scrolling up from the bottom of the screen with details on what's going on - it's an effect you may have seen a few times in video games when they're loading maps, making network connections and suchlike.
Glass pane seems to be the way to get the text overlay, that much I have working. My problem is exactly what component to use for the actual text display.
JTextArea can display text, but as far as I can see, it can only do it from the top of the screen down - is there a way to make it scroll text up from the bottom of the screen?
JLabel by contrast can align the first line of text to the bottom of the screen, and even take appended text on that line, but when I add more lines separated by newline characters, it just seems to swallow them up even after calling repaint and validate. Is there a way to make it scroll up with the new text?
Or is there another component I should be using instead?
I really like JXLayer for effects layered over Swing components. JXLayer was at one point scheduled to be included in Java 7. Unfortunately the moving around that has been going on Java.net lost all the good content that the author had. There are still some other great resources around (Java 7 required for this one) on the web. I use JXLayer to provide panels with a busy state having a web-like spinner and greyed out appearance.
Another alternative (not as capable as JXLayer IMHO) is MigLayout has absolute positioning, which is maybe easier than the GlassPane.
JLabel would be the easiest. Otherwise you will have to override paintComponent to do anything fancy like animating the text movement.
I'd like to make a login bar for an application and I can't figure out how to organize a series of JLabels and JTextFields such that they are organized in a horizontal grid without these same components being resized to fit each cell. I also want to make sure that the group of components isn't resized below a certain width. How can this be achieved?
Edit: Thanks for the answers everyone. I'll have a look at MigLayout and SpringLayout later. Due to time constraints I'm going to have to make do with Visual Editor and use a null layout. The component placement and dimensions have to be adjusted by hand but at least they stay put. Here's a picture showing what I wanted to do.
bar http://img145.imageshack.us/img145/7356/bargw.png
Use MigLayout as your layout manager, it's extremely flexible, and supports what you're asking quite easily. You can set size constraints. If you need any further help, post some example code using Swing and MigLayout which shows what you're trying to do, and then I'll advise you on how to do what you want to achieve.
You probably want some additional cells which 'grow' to fill the remaining space. This can be achieved with column constraints, by inserting 'push' between the columns (specified by [..]) to expand the gap. You don't need any placeholder components in this case. (i.e., [pref!]10px[40px::]push[pref!]10px[40px::])
You have to use different layout. FlowLayout or BoxLayout will work in your case, but I would suggest MigLayout simply because it will cover all your needs and replace all others .
Check out the section from the Swing tutorial on Using Layout Managers.
The SpringLayout has an example that does exaclty this.
The GridBagLayout is more difficult to use but also support row/column type layout.
Finally, you can still use a GridLayout. Just add the text fields to a JPanel first, then the panel will grow but the text field won't.