I'm working on a simple app that has:
2 TextFields with Labels: name and description
Add button
Panel that is filled with name/description labels and with radio buttons to select records and manipulate with them (edit / delete -> these buttons appear when radio button is selected).
I tried the following layouts composition:
2 Panels with BoxLayout (YAXIS) which contain text field and their labels
Panel with GridBagLayout to have 2 panels with text fields and a button to add data.
Panel with BoxLayout (YAXIS) to be filled with records after button press
Panel with GridBagLayout that contains radio button and 2 labels with results of name and description text fields.
Here is a screenshot of what I came to:
As you can see there's a problem - Labels have no word wrap. If I use JTextArea for word wraping, then white background appears (setBackground(null) doesn't help).
I think that GridBagLayout is not good choice here or even there are too many inner panels. In fact it seems this task is common enough. What are good practices for apps UI building like that one?
The Problem you got with your JLabel is easy to handle. Because JLabels accept HTML Tags you can use this mechanic to automaticly wrap your text:
label.SetText(String.format("<html><div WIDTH=%d>%s</div><html>", width, text));
For the general Layout I prefer the GridbagLayout. With the GridbagLayout you only need on Layout-Typ. GridBagLayout is flexible and easy to use for your case.
If the Layout will get more complex you will probably need to stack different Layouts, to get the best handling.
Related
I have written a Swing UI that has a JPanel with numerous controls and on the right hand side a few columns of JCheckBoxes. This is all handled by making the JPanel use a GridLayout. The problem I am having is that a given checkbox toggles it's selection status no matter where in it's grid "cell" you click in. Note, I am not using a JTable approach. The "cell" is just the rectangular area of the screen the GridLayout gave to the checkbox. It can be much bigger than the checkbox. I can't figure out how to make sure the checkboxes are only selectable when you click in the tiny box of the drawn control (not the big box of the "cell" that the checkbox is basically centered in). I've googled a lot and everyone talks about JTables. Again, I am not using a JTable. This issue is causing headaches for my users as they click on the application window and accidentally select an option!
The GridLayout forces all UI components to fill their cell completely, so the actual checkbox only gives the illusion that it's smaller than the cell it occupies. The solution here, as with many other more complex UI designs, is to use multiple layouts nested inside one another.
In your case, try putting all your check boxes inside a BoxLayout and using glue to space them as needed. This BoxLayout should be placed side by side with your GridLayout in another enclosing container (either a JPanel or your ContentPane -- I can't say for sure because you only gave a brief description of your UI with no code or illustration).
Play around with the idea of nesting layouts until you get something you like, and don't forget to try resizing your window to see what the layout manager does under the circumstances. The final appearance isn't always exactly what you imagine it will be.
I'm pretty new to programming Java based GUI applications. Here's what I have in mind, I want to divide the window into two areas.
The first are contains buttons (or a list), and based on which button was clicked, or which item was selected, the second area changes. (finite number of buttons)
Something like this:
I can think of many ways to do this, but I am not sure what is the best practice. Do I have several invisible panels and make only 1 panel visible at a time, or do I change the ordering (bring panel x to front), or is there some other way?
Appreciate any help I receive!! Thanks in advance!
Although this is a primarily opinion-based answer I'd go with a Nested Layout approach:
Main panel with BorderLayout. Or you can use the frame's content pane which already has BorderLayout as default layout manager.
Left panel with BoxLayout (or GridBagLayout).
Right panel with CardLayout.
Note: Buttons in the left panel should switch right panels cards.
See Lesson: Layoing Out Components within a Container tutorial.
For complex GUIs you have also third-party layout managers available, listed in this answer:
MiG Layout
DesignGridLayout
FormLayout
I want to make an account screen for a project, but I'm still new to GUI's. This is my first time working with a JComboBox and I'm having a bit of trouble. I want to basically place the JComboBox inside a box, which will be part of my background image. I tried using BorderLayout, but that just made a giant combobox that took up my entire screen. I have my code here and a drawing which illustrates my goal below:
See this answer for 2 layouts that can easily center the panel containing the combo box.
Use borders and layout padding within that panel for the white space required.
I have to build a rather large form with many controls. The controls are divided in basic controls/settings and extended controls/settings. The user can decide if he wants to see only the basic or both basic and extended controls.
I've dropped all extended controls onto their own JPanel so that I can easily switch between the two views by showing or hiding this panel.
Currently I'm using GroupLayout and what happens is that the controls on different panels are not aligned:
Label aaa: Text field
Label a: Text field
Label aaaaaa: Text field
----------------------------
Label b: Text field
Label bbb: Text field
Label bb: Text field
Unfortunatly I found now way to "synchronize" the layouts of the two panels (except using AbsoluteLayout and fixed control coordinates)
Is there any way to achive this?
Is my whole design flawed?
EDIT: If it is possible I would like to keep the GroupLayout manager.
As far as I know, no Swing LayoutManager (from JRE or open source) can span several panels.
I am currently working on such a feature (which I called "layouts synchronization") for my DesignGridLayout project, but it is not something easy to implements (I have started about 2 weeks ago and I still don't see exactly if and when I will get to something interesting, but I still have high hope for it;-))
One option you could check would be to add all components to the same panel (with just one GroupLayout then) and hide/show them based on user's selection. Hopefully, GroupLayout will adapt the size to the situation (after calling pack()).
If GroupLayout behaves well, then it would just be a matter of calling pack() each time after user changes his selection to show/hide extended fields.
Else you would have to manually set the size of your panel every time the user changes his selection.
Probably the easiest (good) way to do it is to add all the components to the main panel. Set the subpanels to non-opaque, and add the also to the main panel. The main panel the needs optimised drawing to be switched off.
Another technique is to add a spacer component. To the bottom panel add a component in the same column as the labels which dynamically takes the width component of its various size methods from the top labels. Do the same in reverse to the top panel.
I think there is no way to do it with the standard layout managers. You'll probably have to write your own layout manager, but it shouldn't be too hard if you subclass GroupLayout.
You could use GridLayout instead of GroupLayout which will give you uniform spacing between the columns
If you want to keep them in separate panels with separate layouts:
Iterate over all of the labels that you add, and find the maximum preferred width of each.
Iterate a second time, and set the preferred size to that each label's preferred height, but the maximum width.
This is the explanation of th GridLayout. This will set every component to the size, you expect it. With the GridData object you can specify how the components are ordere.
Examples
(source: sun.com)
Trying to build a GUI application in Java/Swing. I'm mainly used to "painting" GUIs on the Windows side with tools like VB (or to be more precise, Gupta SQLWindows... wonder how many people know what that is ;-)).
I can't find an equivalent of a Group Box in Swing...
With a group box, you have a square box (usually with a title) around a couple of related widgets. One example is a group box around a few radio buttons (with the title explaining what the radio buttons are about, e.g. Group Box entitled "Sex" with "Male" and "Female" radio buttons).
I've searched around a bit... the only way I found was to add a sub-pane, set the border on the sub-pane and then add all the widgets in the "group" to the sub-pane. Is there a more elegant way to do that?
Create a JPanel, and add your radiobuttons to it. Don't forget to set the layout of the JPanel to something appropriate.
Then call panel.setBorder(BorderFactory.createTitledBorder(name));
Others have already commetned about JPanel and using a TitledBorder, that's fine.
However, when playing with Swing LayoutManagers, you may find it annoying that components in different JPanels cannot align correctly (each panel has its own LayoutManager).
For this reason, it is a good practice (check "JGoodies" on the web for more details) in Swing GUIs to NOT use TitledBorders but rather separate groups of components in a JPanel by a JLabel followed by a horizontal JSeparator.
Ref. "First Aid for Swing"
A Group box is just a set of 'logically grouped widgets'.
This in the swing world is a JPanel.
Add your widgets to a JPanel.
Set its border type to 'Titled Border' and give the title, same as the name of the VB6 'frame'.
Voila. You have your group box.
Here's a quote from the JRadioButton javadocs since you brought up radio buttons.
An implementation of a radio button -- an item that can be selected or deselected, and which displays its state to the user. Used with a ButtonGroup object to create a group of buttons in which only one button at a time can be selected. (Create a ButtonGroup object and use its add method to include the JRadioButton objects in the group.)
Note: The ButtonGroup object is a logical grouping -- not a physical grouping. To create a button panel, you should still create a JPanel or similar container-object and add a Border to it to set it off from surrounding components.
Not AFAIK, at least not with standard swing widgets.
In VB you have a group widget, which is essentially a panel + border.
In Swing you have a JPanel which is the container widget, and you create and set a border object on it only if you need one. One can argue that in a way that is more elegant since you don't pay for something you don't use (e.g., border)
As David Koelle mentioned about setting up border through java code, you can also achieve similar result in designer mode.
I'm responding based on the Uri's comment which explaind what the OP meant by Group Box:
Uri: I think he means the control group you see in many dialog boxes, where you have a square around a bunch of widgets such as radio buttons, for example.
As far as I know, every JComponent can set a border for itself, so you don't need a second panel.