This write up on JPanel seems to focus on this container as a means of setting a background color. Oracle on how to use JPanel Should I infer that if I am happy with the default grey background in ubuntu/gnome/Java programs, there is no need to use this object? Is there an object-oriented programming reason to use this object?
JPanels are a way to create a logical "division" of space if that makes any sense. For example, if you think about HTML, you could just put elements one after another on the page (how some old HTML pages look in fact) but it's much more aesthetically pleasing to use a container like a table, or some CSS styled DIV tags to create divisions on the page, and place elements relative to one another in a much more defined manner.
JPanels fill this function in Swing, where each JPanel has a Layout Manager that defines how it's inner elements are laid out. It's not unusual to nest JPanels, for example, using a JPanel with a border layout for the menus/status bar, etc, a JPanel at the center of that with further elements, and then additional JPanels inside of that central "content panel" area that further divides the space, for example, creating an input form on one part of the central panel.
In this sense, JPanels are quite comparable to how Tables and Divs are used in HTML, and you should think of them in a similar manner when creating your layout. The most important thing about JPanels is their ability to dynamically resize, pushing the contained components around. If you just used, say, one JPanel and absolutely positioned everything, then you'd lose the main appeal of Swing, and this container methodology.
It's quite possible you perceived the authors angle to be one slanted towards color and drawing, but I think if you give the blog a second read you will find that he was indeed trying to be more expansive than that. JPanel's can and are used as content panes for a variety of other widgets in a typical Swing application.
Also I'm not sure why you reference Ubuntu/Gnome, as the L&F of a platform is quite divorced from the utility of JPanel.
Related
If one has the choice between doing all rendering in a single JPanel or rendering across multiple JPanels (with override paintComponent) and one is not using any other Swing component such as JButtons, JTextBoxes, JComboBoxes, etc (other than the JFrame that the panel or panels reside in). If one is only drawing using drawLine, drawRectangle, fillRect, etc. Is it more efficient to draw everything in one panel or spread the drawing out over multiple panels? Assume that the code complexity is the same either way and reducing lag / improving response time is important.
It is slightly more efficient.
However, consider using several panels and rely on the layout managers to handle sizing etc. It will most likely simplify your code. If you are using one panel only you will have to handle resizing yourself.
In programming, don't optimise before you know performance is a problem. Measure!
Swing will only paint a component when it needs to.
If the entire frame is repainted every time a property changes, then keep the logic together in a single place for ease of maintenance.
If it is logical to break the panel down into sub components, then you can repaint individual sub components as necessary.
For example, this is the way a JTable works. You can have a hundred row in the table, but if you only change the data in one row, then only that row is repainted.
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).
Not sure if what I need is possible.
I have a container (JPanel) that contains some internal elements.
I was wondering if it is possible to force internal elements to fit into the container's size.
I need them to be fully visible i.e., resize to fit inside the Panel's size and not cut some parts of the internal elements.
Scrolling is not an option.
Is this possible by using a Layout or something?
EDIT: Important clarification:
The thing is that I do not have access to the internal elements neither to their properties so I would say that a Layoutmanager capable of resizing child elements to fit to its size is needed. I tested BorderLayout and GridBagLayout but the result is always the same, the internal elements are cut out.
It's for exactly that reason that LayoutManagers exist. All the LayoutManagers work for simple containers directly, excluding GridBagLayout which is to able to handle most complete GUIs directly.
For most complete GUI's you have some choices as follows:
Look for a 3rd party layout such as MigLayout or here
Use GridBagLayout
Very easy way is use nested layout, where there is more than one JPanel and each has child JPanels with the same or different LayoutManager
Or custom layout, should be hard..., but same as using GridBagLayout
You could set the JPanel layout to border layout, then add the single child to the center. If there are multiple children, this approach becomes less useful since components added to the the NORTH, SOUTH, EAST, and WEST will remain statically sized while the centre resizes to fill the remainder.
In short, this isn't an ideal solution. All layouting in Swing is made all the more complex by the fact that different components behave in different ways, so you really need to provide further details of the child components you wish to add to your panel, and any behaviour that has been overridden on those components.
The best way is to try a couple of simple examples to see what mileage you get and whether subtle redesign of your child component nesting could help.
you can use a layout, like GridBagLayout, or BorderLayout depending on the situation. With proper weights it is possible.
this sounds to me like you should just peek an appropriate layout manager and use it. For example, look at BorderLayout - put your component in the CENTER and it will occupy all the area. Its up to each concrete layout manager to decide what will be the size of the components.
Mark
I was using a JInternalFrame inside JDesktopPane. I wanted the internal_frame to auto resize as desktop pane is resized, so I had to implement the AncestorResized event for the internal frame where I placed the following code:
this.setPreferredSize(this.getParent().getPreferredSize());
this.pack();
I am working on an app which when used for loading a file and drawing the contained components, may result into painting of overlapping components. For example, consider a big rectangle box containing text line inside it.
Now because these components are overlapping, it is difficult for the user to select the inner text box in this case as it has been overlapped by the rectangle box.
We were thinking of solving this with allowing the users to actually move any component to a layer below the current one. But this has its own limitations on the usability side, as then for every such case the user will have to move the bigger or the most recently painted component to a layer below and then do the other processing on the inner components like dragging etc. There can be more than 2 components at the same 2d (x & y position) in this app.
I am sure that there should be a better solution for this and could someone please provide some pointers on the implemention part of it.
I am not sure, whether i understand your question. Do you have problems, with the action listeners or because of drawing the components?
This How to Use Root Panes may be helps.
You can create a Glasspane in Java
Here's a simple example of an object drawing program that supports click and drag for multiple selections. More advanced programs often implement z-order functionality (Move Forward, Move Backward, Move to Front, Move to Back) by simply re-ordering the node list.
As an alternative to the layered pane approach, also consider JInternalFrame. This example shows How to Use Actions to manage a menu from which hidden windows may be brought to the fore.
I am creating an application which has a scrollable and scalable (zoomable) view. Inside this view I want to place other components (most of them customized JPanels and JInternalFrames).
Things such as fonts and borders, and sub-elements such as buttons don't need to be scalable. Only dimensions and position of container components should be.
What do you think, what is a good way to implement scalable components?
EDIT: I'm talking about resizing the entire layout including all
components. Please think of something such as a visual UML editor with zoom functionality.
My alternatives are:
Create a custom layout manager;
Create custom resizeable sub-components;
Create a custom container which would take care of resizing its sub-components;
Do something else?
Possible problems:
Boilerplate code;
Necessity to provide access to additional custom properties of components;
Not straightforward (inconsistent) representation of components in code.
Something else?
This is why layout managers exist: they tell contained components where and how large they should be.
Since you're talking about a UML editor, are you using contained Swing components to represent the various objects in the diagram (eg, a component for a class)? If yes, then you've got a lot of work ahead of you (although it's not necessarily a bad approach). I'd recommend creating a constraints object that identifies the object's location on a "unit space," then multiplying by the current size.
I've done that by creating a custom layout manager. Every component (or rather component class) on the frame has a marker whether or not it shall be resized when the container is resized (e.g. tables are resized, buttons are not). Those which are not resized are moved when the container is resized.
This is used to make resizeable forms without any manual setup, i.e. forms are defined by just specifying x/y/length/width for each component (no further alignment info).
If I look at this problem as visual UML editor then I had to think about single "canvas" component drawing each element as graphical object with base aspect ration and zooming in/out. I can't see reason for list of components aligned within parent container.
I started a similar solution that works fine without touching the original layout.
It's as easy as this:
// Install scalable layout and CTRL+/CTRL- keys for scaling operations
ScalableLayoutUtils.installScalableLayoutAndKeys(new DefaultScalableLayoutRegistry(), frame, 0.1);
It's still under work but It will be soon available as part of the next "utils4swing" version.