How to create a modular UI using MigLayout without nesting multiple panels? - java

MigLayout is a highly versatile layout manager for Swing, SWT and JavaFX.
As per the documentation, it should be possible to (re-)create any given layout with just a single instance of that layout manager.
However, I could never figure out how to create a modular application with decentralized control over layouting with that single instance:
I have a parent panel that controls where individual components contributed by submodules go.
Aiming for decoupled and independent submodules, those components are free to choose whether they do their layout with MigLayout or with any given layout manager. Thus, they hand out an instance of Node (or JComponent), and I end up with nested layout managers.
Are there any emergent/good/best practices for achieving both decoupled architecture and adhering to MigLayout's single-instance paradigm?

I understand what you want to do and have tried similar approaches. I found no generic solution; either you nest the layouts or you come to some kind of agreement between modules on usages of ranges of cells (this is what I usually end up with when for example generating search screens).
I ended up with one conclusion; having totally independent modules putting stuff on a screen works fine technically, and if you can make a high degree of separation part of the layout style, it might also work for the user. But I found that the resulting screens usually are not very user friendly, especially if there are multiple layers of construction. So I stopped trying to dynamically construct screens and just build a screen to match the task at hand; there is the end user screen, some custom controls, and maybe the occasional task specific panel (/ pane).

Related

Why use CustomComponent for Layouts in Vaadin 7?

Both the Book of Vaadin and the Vaadin training course recommend using acom.vaadin.ui.CustomComponent to contain a Layout.
I can understand this in pure theory, to encapsulate the contents without needlessly exposing a specific layout such as GridLayout or HorizontalLayout. Encapsulating has benefits of:
Encouraging de-coupling between classes
Makes it easier to change the layout without having to change the declarations in the outer class.
But in terms of practicality, I assume the rendering of a CustomComponent means extra HTML/CSS layout instructions such as perhaps an another div. The last thing Vaadin rendering needs is yet another layering of HTML structure.
I wonder if this might be old folklore. Perhaps using the visual composing tool in Eclipse accepts only CustomComponent objects rather than Layout objects? (Just a wild guess, I have no knowledge)
➤ Alternatively, why not just declare in the outer class a reference variable of type com.vaadin.ui.Layout to get the same encapsulation?
➤ Am I exaggerating the impact of adding a CustomComponent to Vaadin rendering?
➤ Is there some other benefit of CustomComponent which I’ve failed to perceive?
You can compose the content of a CustomComponent with the Visual Designer. This saves a lot of time in the development process
The main advantage of the CustomLayout is, that you can place your components inside HTML code which you otherwise can't generate via vaadin means.
If this adds more div/html as with native Layouts depends on the specific case.
We ususally use it only when a clean Vaadin only solution would introduce more components/div's or is not possible to implement.
The second idea is the separation of layout and logic, which can be implemented partially with this Layout. You just specify which components you have and then a UI designer (in theorie) could make your HTML code, with the correct blocks where your components will be placed.
In real life I do not find this a real advantage, since the whole CSS, sizing etc. is anyway done with vaadin.

GWT CSS, Layout and LayoutPanel?

I'm trying to build a slick-looking GWT panel (my first one) and am stuck trying to decide how to handle its layout.
According to the Layout Javadoc:
Helper class for laying out a container element and its children.
And the LayoutPanel Javadoc:
A panel that lays its children out in arbitrary layers using the Layout class.
So it seems like you can:
Extend a ComplexPanel and use a Layout to manage its layout; or
Use a LayoutPanel which seems to have this functionality built-in; or
Just add elements to an HTMLPanel and use CSS to perform all the positioning/layout
I'm not 100% sure, but this feels like you have these options (and possibly others) because they offer benefits over each other in different circumstances, or because the GWT API has changed a lot and newer layout methods have been added over time.
If the former is the case, then security and performance are my only priorities, so I ask: is one method more performant and/or secure than the others? And if the latter is the case, then which method is GWT's newest and most encouraged? It would seem to me that the most control would be to leave everything for the CSS and not use Layout/LayoutPanel at all!
LayoutPanel uses absolute positioning, and it also provides size to its children. I like to use it for my outmost layout container, as it occupies the entire browser window and resizes its children when that browser window is resized.
For inside widgets (e.g. menus, main area) many people like to use VerticalPanel and HorizontalPanel (or, even LayoutPanel) for their simplicity. I avoid using these panels as they offer rigid, table-based layout. I prefer to use either HTMLPanel or FlowPanel, and achieve the desired layout through CSS.
Note that I would not use "old" or "new" attributes when discussing the pros and cons of different panels. They all translate into standard HTML. If you are comfortable with CSS (a lot of developers aren't), then you should use CSS as much as possible, because this is what browsers are optimized to do, and because you can build more fluid, consistent and future-proof (i.e. much easier to change) layouts with it.
What kind of app are you building?
Do you need 'user-positioned splitters' between panels?
Do you need separate scrolling panels?
If not, stick with CSS.
Start with an HTML/CSS mockup and then convert that to a GWT UiBinder file. Particularly when it comes to responsive web design, you can get a HUGE HEAD START by starting with an off-the-shelf CSS framework like Twitter Bootstrap.

Custom Swing component: questions on approach

I'm trying to build a new java swing component, I realise that I might be able to find one that does what I need on the web, but this is partly an exercise for me to learn ow to do this.
I want to build a swing component that represents a Gantt chart. it would be good (though not essential for people to be able to interact with it (e.g slide the the tasks around to adjust timings)
it feels like the best approach for this is to subclass JComponent, and override PaintComponent() to 'draw a picture' of what the chart should look like, as opposed to doing something like trying to jam everything into a custom JTable.
I've read a couple of books on the subject, and also looked at a few examples (most notably things like JXGraph) - but I'm curious about a few things
When do I have to switch to using UI delegates, and when can I stick to just fiddling around in paintcomponent() to render what I want?
if I want other swing components as sub-elements of my component (e.g I wanted a text box on my gantt chart)
can I no longer use paintComponent()?
can I arbitrarily position them within my Gantt chart, or do I have to use a normal swing layout manager
many thanks in advance.
-Ace
I think that the article i wrote a few years ago for java.net is still correct today. Doing everything in one monolithic class gets you going faster in the beginning, but becomes a mess quite fast. I highly recommend doing the separation between the model (in your main class) and the view (UI delegate). The view is responsible for:
interaction with the user - mouse, keyboard etc.
painting
creating "worker" subcomponents as necessary
In the medium and long run this is the approach that has been validated over and over again in the Flamingo component suite, which you can use as an extra reference point (in addition to how core Swing components are implemented).
Using UI delegates is a good idea if you think that your component should look different for different Look And Feels. Also it is generally a good idea from design point of view to separate you presentation from your component
Even when overrding paintComponent you can still put any sub components on it.
Using null layout you arbitrarey position your components. Alternatively you can use layouts too.
Here is a very good starting point for you.

What is the best way to manage application screens in SWT?

I'm creating a standalone SWT desktop application that has around 10 different screens (few wizards, help, forms, etc). Some elements on screen don't change at all (like header, background, etc) and there is a working area that changes depending on what is clicked, etc.
What is the best way to manage application screens? Do I need to create all screen at startup and then show/hide them depending on what is clicked? Or do I need to create those screens dynamically?
Also, I couldn't find any way to show/hide a Composite, do I need to dispose it and then create again?
What is the best practice? I'm new to SWT developing outside of Eclipse so any help would be beneficial.
Deciding whether to create screens up front or creating them the first time they need to be displayed is a decision that needs to be made on a per application basis. If there is a good chance that all the screens are going to need to be used on a particular application run and the number of screens is low (10 screens is relatively low) then you may want to create them at application startup so the UI is snappier once the application loads.
If you use bindings then you may need to come up with a dispose strategy (even if you only dispose the bindings) so you don't have too many events flying around.
Control has a setVisible(boolean) method (and Composite inherits from Control) which you can use to show and hide a component. Note this will only prevent the composite from being shown on the screen, the layout manager will still allocate a blank space for it. Many SWT layouts have a way to exclude a control from the layout which will get rid of the blank space. For example if you are using GridLayout then you would set the exclude variable on you GridData object to true when you hide that control.
Another option is to use StackLayout. This lets you stack a bunch of Composites on top of each other and then choose which on is on top. This might be a good fit for you if you have static areas plus a working area like you described. I would put the header, footer, and an empty composite with a StackLayout in a class file. I would then put each screen that will be displayed in the working area in their own classes. You can either have these screen classes extend Composite and then set up themselves in the constructor or you can use a factory method to setup the screen. Either one is a common and acceptable practice and comes down to a matter of taste.

NetBeans should be named "Mexican Jumping Beans"

I have been trying to set up a Java form in NetBeans with 15 - 20 visual components (buttons, textfields, etc.) and I have been using the Free Design layout paradigm on the MAC.
According to what I've read, the Free Design layout gives me various alignment guides, but does not try to force my alignments to specific row and column delimiters. However, I'm finding that when I do this, the width of my form may arbitrarily change, or some of the components I've already placed will move around radically when I make even small adjustments to other component positions.
Is there some way to anchor all these components, once placed, or is there a better layout paradigm that gives me the freedom to place components where I wish to?
IMHO, Matisse works best when you know what you want before you start. It doesn't seem to do so well with iterative changes.
Here are a few rules I follow when using Matisse in freeform mode. They don't make it wonderful, just less painful:
Build top-to-bottom and left-to-right. Most jumping happens when you go back an try to insert something.
Build it in one pass.
When you make progress, save it. There are conditions where Matisse will drop its undo list. Don't count on Ctrl-Z to bail you out. I use a local mercurial repo to track my changes.
Keep it small. The more elements, the more likely it is to blow up. Build it out of smaller components. For example, if you have a date field with a button to open a calendar
make that a component.
Add the component to the palette,
use that in the larger component.
Maybe it's time to look into other LayoutManagers, like GridBag or something else that will give you what you want. The built-in choice by NetBeans sounds like a poor one for your needs.
If you choose a null LayoutManager you'll get absolute positioning.
But along with it comes absolute responsibility: No help in repositioning any elements.
I've found Using GroupLayout directly works really well. It can be confusing at first because horizontal and vertical layout are done separately, but once you get used to it it's not that difficult. You can definitely get things to align, and stick together when resizing. It's far better then using nested panels, GridBags, and that kind of thing.
MigLayout might work too, but GroupLayout is included in the JDK.
You may want to look at the absolute layout. It allows you to put the component exactly where you want it, without all the jumping around.
GridBag Layout is my favorite, and specially in Matisse (Netbeans GUI). You have like a wizard to graphically manage all the properties.
Will take you few examples to get things perfect as you want, but when you do, you will never look back.
Take a look at Sun Tutorials GridBag Layout
I strongly, strongly recommend MigLayout (And getting away from GUI layout tools). Any time you think you are saving by using a GUI tool quickly evaporates the second you run into layout manager behavior. Real UI's are coded, not built with drag and drop.
I found that it took me about 3 hours of fiddling to get used to MigLayout - after that break in period, I found it to be incredibly intuitive and powerful.

Categories