I've heard that putting the same-level component on top of another same-level component is bad practice.
I'm talking about JPanels in this case. I currently divide everything into separate JPanels where each has its own layout, and then I add them to the main content pane (JPanel). I feel like this way is much easier than having to configure a layout that will work for all my components that can be all over the place. Is my logic flawed?
There is nothing wrong with having panels inside of panels. However, if you are doing a lot of that, you may want to consider a layout manager (my favorite is MiGLayout) that supports fairly complex arrangement of controls without using tons of nested panels.
At the end of the day, use a composition that makes it easier for you to maintain your code. If you have groupings of controls that are independent of each other, then having them in separate panels is good design - it allows you to split that panel out (for testing, or even for creative windowing in the UI). If the sets of controls are intrinsically tied to each other, consider a single panel with an advanced layout manager.
In some cases, you'll have a small amount of binding between two panels (classic example is one panel with a list and another panel with a detail view for the selected item in the list). In this case, I generally use two separate panels, and two separate presentation models, then bind the current selected item in one model to the parent of the inspector panel. But if you find that you are using values from multiple panels for things like validation, data storage, etc... then you may have things split into too many panels.
I've done a lot of this over the years, and the position I've settled on is to compose my UIs along logical lines of the underlying presentation models that back the views. Very rarely do I let the layout of the UI drive how many panels I use, etc... - MigLayout (and I'm sure there are others) make even complex UI layouts fairly straightforward, and it's much better to design the classes for the view and model in a way that make the code easier to test and maintain.
Related
I'm working on a POS system for a fast food restaurant. I've developed Adding, updating and deleting products using a MySQL Database. Now I need to create the POS GUI (using SWING) which the cashier uses to create the bill. The interface I have in mind is like what MacDonald's uses, there's a set of buttons with the product images. (I have stored BLOBS of products successfully)
example image :
I have no idea on how to accomplish this, it would be awesome if its possible to generate a set of dynamic Jbuttons which gets the image of a product along with the name and price. Is this the best way to accomplish this? and how do I achieve this? A few details to put me on the correct path will be greatly appreciated!
Thanks.
You have at least four containers, the top row, the bottom row and each row containing a separate container in the middle (for the buttons).
The basic layout for the rows might be a GridLayout, each row would probably use a BorderLayout with the nav buttons in the WEST and EAST positions. CENTER container could use a GridLayout, but won't give you the look you're after. You could use a FlowLayout and even a GridBagLayout, but you'd need to ensure the size of the buttons where correct for your needs
On the left I see a JTable and two JPanels, containing the buttons, held together with a GridBagLayout.
On the right I see a JList. See How to Use Lists for more details. You'll probably also want to have a look at Concepts: Editors and Renderers and Writing a Custom Cell Renderer for details about how you could customise the look of the cells and How to Write a List Selection Listener for details about how to determine when the user changes the selection
Together, they are probably maintained by a GridBagLayout within a single container for ease of use
Along the button is probably another container using a GridBagLayout.
Altogether, they are probably held together by a GridBagLayout
Have a look at Laying Out Components Within a Container, How to Use GridBagLayout, How to Use BorderLayout and How to Use FlowLayout for more details
You will need to look into the GridLayout.
In your case, it might be a little bit more complex since you have multiple grids, some of which seem to be nested within each other.
You should be able to allocate the grid dynamically and then leave it to the layout manager to distribute things evenly over the page.
Depending on the complexity of your layout, it might also be a good idea to look into the GridPane provided by JavaFX.
Hi I look for you this problem and I find this solution ;
http://www.javasrilankansupport.com/2012/06/create-dynamic-jbutton-with-image-and.html
I have written many simple GUIs, they worked fine. However as a beginner I always think that my way of writing user interfaces is not very good practice.
Is it proper practice if one uses more panels to get the desired interface? Also is the use of the setBounds() method good?
The less sub-components you use, the more responsive your UI is going to be. Simply because it has less things to deal with.
I would not recommend using 'setBounds` as it is creates inflexible UI in most cases. I would encourage you to start using layouts such as BorderLayout, FlowLayout etc. The most versatile of them is MigLayout
Here is more general information about Swing layouts: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
I have a fairly large (6000 lines) java application with over 40 buttons etc. and fixed window size.
This is creating problem for people who wants to use it for some it is too small for others it is too large with no scrolling! How can I retroactively make it fit different screens?
Thanks
If yours is a Swing GUI (you have not mentioned this yet)
Don't use fixed size anything.
Use layout managers and nested JPanels to do the heavy work for you.
One comment to your question mentions using GridBagLayout, but I suggest that you avoid using this, that you instead use nested JPanels that use simpler layout managers, or use MigLayout.
To fill the Screen, set the extended state appropriately: setExtendedState(JFrame.MAXIMIZE_BOTH)
I'm trying to figure out how to manage this layout in order for it to work. I have some ideas, but rehauling the whole thing is quite a bit of work to do.
This is how it looks like (in JTextAreas: "component name (parent (parent))"):
I have explaind the structure at the end of the question, if you feel the need to know.
This GUI is supposed to be very dynamic. You should be able to add and remove chapters, pages, questions and answers.
The GUI in the image above is made using nested JPanels (up to six layers on the thickest parts!) which most don't have thier size specified so they can adjust to the changes in the document. However, a lot of time is consumed (about a second per page) when drawing the document because the program keeps recalculating sizes of all the JPanels until they fit. So, unless I can specify the initial size (MigLayout) of a component, this method won't cut it for me.
Only alternative I have come up with is trying to put it all in one layer using MigLayout, which is doable, but I don't know how well does it work with the dynamic part of the whole thing. Removing and readding all the components (document could have over a hundred pages!) doesn't really seem as an option. Since most of the components are nested one onto another and are to move as one, this makes this solution even more difficult.
Also, all widths are fixed, while all of the heights within a page are flexible.
I really don't know how to go about this. Should I modify one of the existing ideas to work, or are there maybe libraries which are used in this type of situations? Is there another way?
Any ideas?
Also, as promised, this is the structure explained:
So, the thing important here is the JPanel inside a tab. It contains the DOCUMENT.
Document itself is made up out of random number of CHAPTERS. Each CHAPTER contains random number of PAGES. PAGES have MARINGS and CONTENT. On the image, pink and red parts are the MARGNIS, while everything within is CONTENT(green). CONTENT contains a single TITLE(blue). TITLE is made out ofa single JTextArea. After the TITLE, CONTENT can contain a random number of QUESTION(orange). QUESTION contains a JLabel(number) and JTextArea in one row, and below is a it's ANSWER PANEL. ANSWER PANEL contains up to five ANSWERS(yellow). Each ANSWER has a JCheckBox, JLabel (letter) and a JTextArea all in the same row.
Here I have some things marked out:
You seem to have the design you need. Break down each section and apply the required layout to achieve that section. Each section should be a self contained component.
So to my mind, start by modelling the data. You need a Document model, which contains a list of Chapters, which contains a list of Pages, which is made up of a list of Titles, which is is made up of a list of questions.
I would then provide a view for each level of the model. This will allow you to concentrate on the individual needs of each view, in isolation and reuse the code logic. It also means if you need to make changes, they will be more easy to make and reflected through the entire program
You seem to have the right idea for the Document/Chapters, being laid out within tabs.
I'd follow through. Each Page would be a self contained component, possibly using something like a GridLayout.
Each Content section would be its own component, consisting of the title editor and then the questions.
Here I'd use a BorderLyout, placing the title editor at the north position and the question panel in the center. You could then use something like a GridLayout for the questions pane.
As for the margins, you can achieve hese through the use EmptyBorders
I'm using Java Swing and I have the following problem:
I have a class TnaiPanel that extends JPanel. In this class I am creating 3 components and then lay them out in a horizontal line using a BoxLayout.
Also, I have a class TnaimDinamimPanel that also extends JPanel. This class contains multiple occurances of TnaiPanel, layed out vertically using a BoxLayout.
Also, I have a class MainFrame that extends JFrame. This frame contains a menu-bar and one main panel. The main panel can change (when choosing a certain menu-item, I create a new panel and set it to show as the main panel of the frame).
Now, for some reason I get "BoxLayout can't be shared" when I add the newly created TnaimDinamimPanel to the components of the frame.
I don't mind using different layout objects.
The result I want to get is a sort of "table" of components, where each TnaiPanel will have fixed component sizes and spacing, essentially serving the role os a "row" in the "table".
Thanks,
Malki.
You probably create only a single BoxLayout instance. Create a new one each time you need one (i.e. one per TnaiPanel, one per TnaimDinamimPanel and probably one per MainFrame).
To answer the second part of your question, ie "having a table of components", I would say that you can't do it with different panels, except if you start setting the individual min, pref and max sizes of components and panels, which is highly unadvised.
If you need to have correct alignment as in a table of components, then you need to put all your components in one panel, which also means you need to use only one layout. However, the only default swing layout that can allow you to do what you want is the GridBagLayout. Actually the GroupLayout (java 6) would also fit the bill but it absolutely requires a graphical designer (eg the one within netbeans).
If, like me, you are allergic to builders, then you'd better use one 3rd-party LayoutManager that is intended to be use programmatically (I would not consider GridBagLayout to be in this category although I have already used it that way in the past).
MigLayout (as suggested by Skeptic) is one option. Another option is DesignGridLayout which might fit your purpose better and is easier to use than MigLayout.
Try MiGLayout instead.