I have a Swing application that shows a list of complex objects to the user. These are nicely rendered using a ListCellRender, which fills a JPanel with more UI controls. Obviously editing does not work and the components are not enabled to accept input.
Now I want the user to be able to edit the entries. Basically you could think of in-place editing. I tried to simply enable the panel that renders the list entries - but it does not work. What else could/should I do to have an editable list?
So basically the answer is to favour JTable over JList. For anyone questioning that, the JTable can be configured to show one column only, and the difference would not be visible to the user.
Programming wise JTable is more complex and thus justifies that JList is used in simple cases (only one columne, no editing required).
Related
I have list of objects which I want to display in GUI.
Each object is:
1) complex (it has a number of fields), thus I need several widgets to be used in GUI component which corresponds to 1 model object,
2) editable. Its properties can be changed by user via GUI (buttons, input fields and checkboxes which lay within component which corresponds to 1 model object).
How conceptually can I do this? Which UI framework and which widget to use?
Coming from android development, I have no experience in java desktop applications (by the way, in android this task can be easily accomplished by means of standart instruments (listview + its adapter)).
I have tried swing framework with its JList and JTable. But it turned out that elements within JList's cells are not editable (say, I cannot press buttons if there are a few inside Jlist's cell). The same applies to JTable.
I have googled for swing, swt, javafx etc, but didn't find direct answer how this task can be accomplished.
Any help is appreciated.
P.S. It is not an option to use JTable with several columns. In fact, I want to have list of JForms or JPanels (in swing terms).
I'm developing a new application where I'll have some windows opened at the same time.
I'm currently trying to design the GUI and I'm struggling with two choices:
I could use a side navigation panel and using the center of the page to display the content of each panel. These panels would be stored according flyweight pattern and I would just hide/show them when navigation buttons are clicked (in order to save the content as is was when hidden, for example a user registration form).
I could use a front page displaying the menu all over it and use popups/new windows to show the content. These could be closed/minimized etc).
My problem is: What if all the panels are stored in my flyweight pattern? will it have a huge performance hit or will it still run smoothly with like 15 JPanels stored? (of course those JPanels will have sometimes lots of content in it such as forms etc).
What do you think would be the best easy-to-use/performance choice ?
Thank you :)
JTable rendering already uses the flyweight pattern, so a one column table is ideal for selection. A custom renderer can display an arbitrary thumbnail representation, while a ListSelectionListener can display arbitrary detail in an adjacent container. In the TableModel, consider an LRU cache if the individual data records are consuming too much memory.
As always with performance questions, prototype and profile.
As long as you don't attempt to hold more data than fits the heap reasonably, performance will be a non-issue nowadays (unless you do something exceptionally bad you will not notice any performance difference from the user perspective).
That said, unless you have pressing reason to hold on to GUI's you currently don't need - just let them get GC'd and recreate them as needed. The create-throw-away after one use approach is more flexible when the application needs to be modified and bears less opportunities for memory leaks.
As for the GUI design aspect, many people absolutely hate popups. They can also interfere with focus management/keyboard usage. But it still depends on which kind of control flow you need. Side menu bar is fine for many purposes.
I'd like to point out that the side menu is just a fancy reinvention of Tabbed Pane (which is a standard component you wouldn't need to implement yourself). Also, if things need to be done in a specific order - a Wizard like approach can also be a good choice (one Window that changes contents with each step completed).
I have this kind of progamming task without JavaFx, instead it's Java Swing. I realized my knowledge is still limited.
I have one single JTable.
But, within this JTable I need a custome Cell Renderer.
The goal is to make this kind of JTable: Example image
My current solutions are: Example Image
Create a Single JTable:
get each Column and set its CellRenderer with a custom Renderer (below).
Create a new Class implements TableCellRenderer:
return different JPanel inside getTableCellRendererComponent
method using switch case (as column counted).
After hours, and hours, I think my current solutions is quite daunting tasks. Thus, My question is:
What are the simplest method of creating this Custom JTable to achieve the main goal as mentioned above?
you have two options
1) JPanel nested another JComponents and solve that by using standard LayoutManagers note scrolling isn't natural nor nice
2) JTable with JPanel can solve that, notice about scrolling inner JScrollPane inside another JScrollPane
I've been facing this problem for a while, and I decided to do it myself. Extending the existing implementation of a table, adding some concepts for what I expect from a table, and writting some editors/listeners for that. All the same, but with a treetable.
I'm working on this project called SUMI.
It contains a java package (ar.com.tellapic.sumi.treetable) that is an extension of a JXTreeTable from SwingLabs.
The project is being developed and I didn't provide any documentation yet. You can do what you want by creating a renderer and if needed, an editor, for lastly attaching actions to each object.
If you decide to use it and you need help, email me, I'll help you without any problem.
Or, you could read the source by your own.
Regards,
EDITED (again):
To clear a little bit this answer, I've just created a wiki page in the project wiki and put the relevant code there. If someone feels that the code should be inserted here, please let me know.
Basically, I try to explain how to find a straight solution to the renderer/editor problems you may find using JTable with your specifics needs by using part of my project, in order to get something like this:
Note that the screenshot was taken after clicking on the respective tick-button.
Once you create a nested panel for one row, as suggested by #mKorbel, you can add any number of them to a GridLayout(0, 1) in a JScrollPane. If rendering many rows becomes an issue, you can adopt the same approach used by JTable, illustrated here.
Even though, JTable can be customized to whatever you desire through cell renderer and cell editors, it is never preferred because you have to do a lot of messy codings for that. Instead, for your problem, I suggest to use JScrollPane and add your component (view panel as your sample jTable ) to its viewPort.
For this implementation, represent each rows with your custom class that extends JPanel. And add the required row components (that may be any components like jlabel, jtextfields or even jpanel too) in it. For the simplicity, you can use null layout for the row panel and add the components at any location you want.
I hope this will help you workout with your problem. If you got any problem in this implementation, feel free you ask again.
Sorry for the odd choice of words for the title, however, "border" seems to be the inappropriate term. While it is true that the visible line surrounding an icon in a JToggleButton can be made invisible by using setBorderPainted(false), the same is not true for JCheckBox and JRadioButton.
I can not use the JToggleButton and therefore need to use either the JCheckBox or JRadioButton (or some derivative of JToggleButton I am not aware of), but need the square or circle, respectively, to be non-visible when there is no icon on the button. Also, using setVisible(false) eliminates the button from the layout, however, I need the space to be reserved and not have the component layout change (using GroupLayout).
Any suggestions? Am I going to have to create a custom renderer? I will be looking at that in the mean time.
The route into this would be through customising the look at feel by changing some of the UI properties in the UImanager (the sort of thing that allows you to make simple tweaks with fonts and colours and presumably the images used for the checkboxes or radiobuttons) -- but it's many years since I last did that sort of thing and can't remember the details.
A little Googling turned up this project to inspect current property values, so might at least help with indicating the right part of the APIs to be looking at.
You have to choices here:
1) Customize Look and Feel as described in previous entry.
2) Create your own custom controls by inheriting from existing ones and overriding component painting.
I found a cheap and easy (read hack) for this. I created an empty transparent icon and used it when I didn't want any item to be displayed.
We have implemented a table-based editor with an SWT tree table. It pretty much does what we want it to, except that we can't find a way to ensure that the first few columns remain at their position when the user scrolls horizontally (so that one can identify the row being edited).
There are a number of third-party table controls in various degrees of being incomplete or abandoned, and a snippet that shows how to use two tables (which get out of sync when they're being scrolled vertically).
What's the best way to solve this?
This 'official' SWT snippet does what you want to do, at least on my machine - it does not get out of sync on vertical scroll. But the price is a second scrollbar - way ugly. To prevent this, you can add the style SWT.NO_SCROLL in the constructor of the left table.
To improve the thing you will have to add a Listener on SWT.Traverse to both Tables, which syncs them if the user navigated using keys, something like this:
leftTable.addListener(SWT.Traverse, new Listener() {
public void handleEvent( Event event ) {
rightTable.setTopIndex(leftTable.getTopIndex());
}
});
I wouldn't go with another Table implementation, since you lose the biggest advantage you have with SWT: using a native widget, which looks and feels 'right' in each OS. If you want to do that anyway, Grid from the Nebula project is much more mature than the alpha tag implies. Don't know if it can do what you want, though.
the "syncing problem" only appears on MacOs based SWT. If your target platform is windows you should have no problem with the given SWT-Snippet. There will be more listeners to register on both tables to synchronise all occuring events (collapse, expand, mouse scroll, etc.)