Confused about Java Layouts - java

I'm not very experienced with Java Swing Layouts. I'd like to make a layout looking like the one in the picture. Is there any easy way to understand and create layouts?

There are tutorials on the oracle website and there are wysiwyg layout-building tools that show you interactively what you are building. One of them I have personally used in the past is the Window Builder you can get as an eclipse plugin but it is by no means the only one.
In the end though what it comes down to is experience. Fool around with them, try them out, get to know them. If you dont code with them yourself it is difficult to understand them properly.

Is there any easy way to understand and create layouts?
I cannot judge what others would find easy, but my approach to laying out containers is to look for sub-sections of the GUI that would be easily done with a particular layout, then working outwards from that.
For example, it seems a single row GridLayout might be well suited to displaying the top two text panes. Then the rest of the GUI can be created by placing the panel with the two text panes into the PAGE_START constraint of a BorderLayout, with the third text pane in the CENTER and the text field in the PAGE_END.
Done.

Related

Layout Manger to Freely place your objects

I am a self-taught java developer and I use IntelliJ IDEA for Java. Recently I saw a video on youtube in which the guy was using NetBeans and in his JFrame form, he was able to freely place his objects like JButton, JTextFeild, JLabel, etc. I am not able to figure out how to do that. In IntelliJ IDEA I found several layout managers such as Border, Card, Grid, Bag, etc. but none of them gave the desired result. can somebody please tell me how can I get a layout manager in which I can freely place all my objects and also freely resize them without any restrictions? Thank you in advance for any help.
In swing every component extends Container. That means that every component can have nested components (they all have add(Component) method). However, not all of them support the layout-ing of nested components.
What I want to say is, that you can add a component to a JButton, but a JButton is not capable of showing its nested components.
So, in order to have nesting, we use the components - containers that support the orientation of their nested components.
These components are all windows (JFrame, JDialog, etc...) and JPanels. There some others that support layout-ing a specific type of nested components. For example a JMenu is capable of showing JMenuItems properly.
Now, these "top-level"/empty containers are using Layout Managers in order to align-show their nested components. Based on the container's layout manager, the components are shown.
This is why you can't "freely" place the components into a JFrame. Because its Layout Manager is taking care of the components will be placed. So, what you are looking for, is to change its LayoutManager (use setLayout method) to one that allows you to freely place the components.
Guess what? There is no such layout manager. Simply because, it would have nothing to do/calculate since you are taking care the layout of the components. So, in order to achieve the "free" component layout, you must use jframe.setLayout(null);. In order to layout the components after it, you will have to use componentInsideJFrame.setBounds(...) and give it constant coordinates /dimension.
This is bad practice. A very bad one when it comes to UI. Giving a component static coordinates and dimension is bad. There are some questions you have to ask yourself.
What if user resizes the window? If the window is 301x301, the center of it, is at (150,150). So you place a component at (150,150). Ok it works. Now user resizes the window and makes it 501x501. The center is now standing at (250,250). But the component is staying at (150,150). There is the solution of setResizable(false), to this kind of problems, but how often have you used "uncapable of resizing" applications? What if user wants to resize it?
I hope you get it and understood what I am trying to say.
By using layout managers, you are solving this kind of problems easily, since the layout manager will take care of the resize and calculate the new center.
Yes. I know it feels weird, but all these youtube tutorials are not teaching you the correct way to make Swing GUIs. (This is a conversation for another day, I guess)
I truly suggest you read the tutorials of Swing documentation in order to get some ideas of how layout managers work. You will really benefit from those.
Finally, I suggest you to leave outside the whole "gui-builder-tool" thing. They seem to help you building your GUI, but they are adding so much additional/useless code and most of the times they are "bad UI creation" prone. Try to code the GUI by yourself.
At first, this sounds a bit harsh, but you can always run your application and see the result of the GUI. After some mistakes, you will finally be able to imagine the GUI result by only seeing the container.setLayout(..) and container.add(...) lines.

Creating a fully dynamic GUI

I'm currently trying to learn JavaFX and FXML (and Java) and decided to write a textbased RPG. The basis for this was already written quite some time ago, but now I wanted to do the whole thing better. Including the visuals, that is, the GUI.
First of all: I'd like to do this using FXML. That does not mean however that I'm not interested in seeing a way using basic Java.
What I want to build is a fully dynamic GUI. No Matter how it is resized, the components (and ideally the text as well) would be at the same location, relative to the other components / window border.
The window would have some kind of top line with several buttons for saving, the menu, overview and whatnot. Below that, on the left side, would be Character information: Health, Experience, Money etc. On the right side would be the text output (using a Scrollpane) plus a text field, for user input. Below the text input/output I'd place the buttons used for actions and decisions. Bottom left corner does not contain anything, though it should be a separate area.
At first I tried using Splitpanes, not knowing that they can be resized anytime and have visible Dividers. Now I'm not sure what to do.
A Gridpane would give some of the functionality I need (separate the areas), but also does not give the flexibility I want (unless I just don't know how to do it). I couldn't get it to work. So I tried using simple Panels. But with them I couldn't figure out how to keep the panels keep their relative position and size, and how to make the Buttons stick to the borders.
So what would be the best way to go about this? GridPane? Panel? Something else I'm missing? Since I don't really know how to achieve this, any help in any direction would be highly appreciated.
Have you read the layout tutorial?
From your description, it sounds like a BorderPane might be best for the overall layout (i.e. the root of your scene graph): I'm not quite sure if you could easily make this give you the empty bottom left corner you want. Alternatively you could use a GridPane as you suggested, with appropriate ColumnConstraints and RowConstraints applied to size the cells in the pane.

How to auto resize java swing elements?

I'm trying to auto resize the left side of my application. I have a JTextField and a JTree on the left and 3 JButtons on the right. But I just don't know how to make the left side auto resizeable.
I did it with the Netbeans GUI Creator (or whatever it is called) but I don't know how to to it without Netbeans. (I usually don't program with Netbeans, this was just an exception to see if it's even possible to do so with Swing.
Here is the code Netbeans created: http://pastebin.com/ERwY4rBC
It's not that the code is completely unusable but I wanted to try it manually.
The GroupLayout looks nice, but the Oracle site says it's mainly for the use for GUI tools. So, using GroupLayout would be not "Java like" or how do I have to understand it? Or is there even a better way to achieve this without GroupLayout?
Thanks!
So, using GroupLayout would be not "Java like" or how do I have to understand it
GroupLayout is to put it simply really hard to hand-code, and results mostly in a lot of code. But it is not "not Java like", it is just not something you want to do by hand, and the code afterwards is hard to read as it is rather verbose.
What you try to achieve (according to the screenshot) is easily achievable using some 'nested layouts'. If your main panel uses a BorderLayout where you put the left, resizable panel in the BorderLayout.CENTER and the other, non-resizable panel in the BorderLayout.EAST you will obtain the desired resize behavior.
Then you just have to decide which LayoutManager to use for those individual panels. I think that both the BoxLayout as well as the FlowLayout will do just fine.
Do yourself a favour and use MigLayout for all your layout needs. It is especially convenient for coding UI by hand.
There is a WebStart application on their site that demos different layout situations with code samples provided.

Is there a LayoutManager in the Java API that would allow me to do like this?

I'm programming this level creator for a game me and a few of my friends are doing but as of right now the GUI is using a null layout, which I don't want to. It works fine for now, but I'm still against it and I know everyone else also encourages you to ALWAYS use a LayoutManager. I'm not really willing to compromise the design as it is right now, so I pretty much want to know if there's a LayoutManager that allows me to create a GUI that looks like this:
IT HAS TO BE IN THE STANDARD JAVA API! :)
This looks like a good job for a BorderLayout. Put the buttons inside a nested container as the NORTH element. Add the JScrollPane as the CENTER component. The grid itself looks like it is a good candidate for a GridBagLayout or perhaps a GridLayout.
Short answer, yes: GridBagLayout. But that'll be a pain to work out and debug.
Long answer: It looks to me like you could do this best with a BorderLayout, a JPanel for the JButtons, and a JTable with custom TableCellRenderers and TableCellEditors.
Check the excellent documentation available for Java by Sun itself:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
Can you spot the GridLayout and GridBagLayout? If you put it into a scrollable container, that should do the trick.
Use GroupLayout for the overall panel and a custom paint method for the map.
I don't think many people here would recommend GroupLayout because it's more complicated than the other layout managers. I like it because it produces great scalable results, so I invested the time in understanding it. Now, I hardly use anything else - especially for user interaction panels with buttons and text fields.
For the map, though, I would create a custom MapPanel and overwrite paintComponent(). Sure you have to write your own custom scrolling algorithm, but I think that's a small benefit for not having to deal with scroll bars. You could make it so someone could just drag the mouse around and move the map. Use the mouse wheel to zoom, and make the interface very intuituve. If you want to paint scrollbars, you can do that too.
I've built several interfaces using models like this. I've built several maps for games using this model, as well as a financial market charting package. It makes it very easy to add custom functionality to do some great things that would be a nightmare to try to do in a JTable.

Why is it frowned upon to use a null layout in Swing?

Recently, I started creating a program for the company I work for. Just as background info, I'm still a student and a beginner programmer, so my solution is probably not recommended and I didn't know how to do it otherwise, but it works and I'm not going to be judged for it because it's a student job totally unrelated to programming.
The thing about the program is, it's going to be run on multiple different computer with different screen sizes and resolutions (800x600 and up). To make sure it takes as much of the screen as possible without losing any part of the program, I set the layout to null and hard-coded everything using relative values.
The program is kiosk-style and I first get the screen size values and go from there (for example, off the top of my head, the left-side menu takes an eighth of the screen, the top bar 2%, etc.). I also use font metrics to make sure the components are sized correctly and that everything gets displayed nicely.
My question is: why is it so frowned upon to make the layout null instead of using the layout managers? (I was told on some forums that this is a horrible way of doing things) I know how the layout manager works and know how to use the different layouts, but for the requirements of this program (multiple different resolutions, custom button shapes and placements, text changing on the components when you change language, etc.), I couldn't see myself using the layout managers to do it all.
How do you more experienced programmers use the layout managers in a situation like this? And what do you do when you want a button to be somewhere specific and other components somewhere else specific that don't really match any of the predefined layouts?
If you layer the layout managers correctly the screen will re-flow to different sizes for you, the idea is to use a single set of layout managers on ALL screen sizes.
If you use null you will have to do each screen size yourself. Not only that but if the app can be windowed you have to support every possible size they might scroll to.
That's kind of difficult to do, but the layout mangers are designed to do just that.
There are some common tricks. BorderLayout is a great layout to start with. Sometimes you might use it at multiple levels--often with just 2 or 3 components in it. That's because it's really good at giving all but one area the minimum required area and giving everything else to the CENTER.
FlowLayout can be useful but it's tricky if your components are different sizes.
I wouldn't try GridBagLayout unless you are planning to write code to feed your layout manager (an excellent solution at that!).
I also wouldn't use GUI builders, they don't know the overall way you want to reflow your layout.
In a nutshell: because all the work that you explain above is done (or at least: should be done) by the layout manager.
More often than not, when a null layout is used, it also implies that all positions and sizes are hardcoded to a single value, so no flexibility at all is given. This means that changes in window size, language, font size, display density or any other related parameter have no effect on the layout and you get the usual ugly effects: empty parts of the window; tiny, unresizable lists; buttons with their labels cut off; ...
It sounds like the work you do should really be done by the Layout Manager. Either find one that does that (my personal suggestion would be MiGLayout, which does a lot and is easy to use) or write your own.
You are practically using a layout - your own, with all your sophisticated calculations of positions.
You can move these logic to a custom layout manager class to pacify the critics.
hmmm trick should be by mixing LayoutMangers and by usage of numbers of nested JPanels that each could have diferrent Layout or not, really depends of number of JComponents, that allows you to create GUI that looks like as layed by using AbsoluteLayout but with same look/output to the GUI for every screen resolutions and ratio (4:3, 16:9, 16:10)

Categories