I would like to implement the page turn effect in Swing/AWT. The theory is pretty much explained here. My question is that since the page is to contain text, which is the correct swing/awt component to use? Also, to get a little deeper, how should I approach this problem? I mean I have the theory laid out before me, I know the tool I need to use, but I have never done anything like this with Swing/AWT, do I need to master all the minutiae of Swing/AWT to be able to do this?
Whatever you do, you will have to implement your own drawing routines. As the text you intend to draw is going to not share most characteristics of the text drawn with other components (it will be angled, rotating over time, and clipped at a moving visible "edge" of the page), you will also have to draw the text.
In SWING, and in all non-console programs the text is drawn to the screen as would any graphics primitive. It takes a bit of learning; especially in the details of line spacing, letter spacing, word wrapping, etc.
That means I'd consider a new swing UI component. Here's how to write custom painting for one. Depending on the details, you may want to reuse a model. Generally it is easier to only write a view than a view and a model at the same time; however, you must balance the needs of the view with the suitability of the existing model.
If you choose an existing model, the Document interface is what you should code your view against. You can take your lead from the JTextPane or JTextArea view components, depeding on if you want the ability to "add style" to your text.
Don't forget that the view actually doesn't do the painting in a well structured Swing component. If it did, then it would not be able to be skinned (to follow the platform's theme). This means that while you will provide a Swing view (typically with a name pattern like JPagedBook), that view will have to be coupled to a UIDelegate which does the actual drawing of the view. This allows multiple UIDelegates for each view, with each UIDelegate containing the instructions of how to render (draw) the view in a manner that is consistent with the look-and-feel of the platform.
The biggest issues around this is typically the extra work involved to properly support look-and-feel, and the lack of knowledge of proper UIDelegate registration (so when the view draws, it finds something that will draw it). It's worth the extra few hours (or couple of days if GUI component programming is sort of new to you) to make it work like the rest of Swing. In the end you'll have a component that doesn't feel like a "separate" part of the library.
Related
I want to make an app, which will work as interface to several servers.
Why: In web iface provided by default (and we cannot change it) are few things we miss, few could be done better and for sure automation of some stuff would make the job easier.
What do I have: almost finished classes for communication with web interface of a server app.
GUI description:
For some kind of version 0.1: text field for username, radio button to select server and one "go" button. Then several (4-12) action buttons to operate on data, 2x text area with results, one label with some text data - I can manage this.
Then I need to view the data - grid MxN which will load the data, expected size: 7-15 columns, usually 10 rows or less, but rarely it can go over 1k (or even more, but I don't need all to be visible to the user in that case).
What I need: simply an advice.
I wish to start with a simple version (and I'm working on that already, but I'm stuck on too many things - 95% cos and absolutely new to GUI and 5% cos I'm new to java).
I've checked many tutorials, but they're all simple.
Real questions:
1) Verify. In MVC controller should handle all user actions - is it done by view's method which is something like button.addActionListener(param); anotherButton.addActionListener(paramp; ...?
1b) I've seen all implemented via one (nested) class, which was then checking source or smth - is that ok? There will be a lots of buttons etc.
2) How to implement the data grid, when I need to take actions on click / dbl click?
4) First row is header, the rest should be scroll able - should it be in the grid or outside (its own grid):
4a) How to make sure header's size (width) will be the same as in data (I don't want to set up straight size)
4b) I failed to create anything scrollable so far, but thats my bad I guess. How to ensure header will hold on a place and the rest can be scrolled?
5) How should be "data update" implemented? I've got JPanel from which I remove grid component and then I make new one and add data into it (simple, but perhapss there is another way). One of first enhancements will be sorting - use the same way I used for new content?
Thanks a lot for any answer, I know this is not very specific, but example I've found are too simple.
I plan a lots of enhancements, but thats in the future and I don't mind to rework GUI/Controller several times, at least, I'll practise, but I don't want to finish one part of the code and realise I've got to rewrite half of a controller and 1/4 of a view to make it possible.
Note: I plan to use this at work as my tool (if things go right, I could make 25-50% of my work by few clicks :-)
So I really mean this).
Note#2: I'm not new to programing, but I've never created GUI (which is why I've got GUI with menu bar with 2 items and 3 components and almost done web-iface connections).
Note#:3 dragable data header, tabbed data view - thats the plan for the future :-)
MVC in Swing is examined here; use nested classes for ease in prototyping and creating an mcve for future questions; as the need arises, nested classes can be promoted to separate classes having package-private access.
Use JTable; its flyweight implementation of renderers is good for organizing data by row and column.
Item three does not exist, but "always remember to translate cell coordinates" if you plan to drag columns or sort rows.
Use a JScrollPane to keep the table header stationary.
Update the TableModel, and the listening view will update itself in response.
If you are interested not only from the event/messaging architecture, but also on handling mouse/keyboard input, hovering detection, widgets, temporary menus, form re-sizing with widget alignment, dragging and dropping etc. I can advice you to look at this question and my answer with helpful resources.
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've been tasked with making a GUI that essentially takes a bit of user input and does some folder/file manipulation on various drives accessible by the machine the program is being run on. While designing this GUI, I'm starting to realize that MVC will make my life much easier and anyone else who decides to modify code, but I can't really see how this can be done via NetBeans.
I've done a bit of reading up on this topic, and I can't really see any clear cut answers as to whether or not this can be done on NetBeans. Surely it can be done if I programmatically build the GUI, but that somewhat defeats the purpose of why I chose to use NetBeans.
Netbeans is fine to do this.
The key thing to realize is that while all of the basic Swing components are MVC, for the most part you don't interact with them that way. A simple text field has it internal model, but that model isn't your model, the text field is more a primitive.
Your model deals with higher level events (button actions and what not), rather than button presses and arrow moves and mouse clicks.
So, for high level MVC, the primary mechanism of communication is through PropertyChangeListeners. And the basic task of building your app up is wiring the PCLs of the assorted data elements along with their GUI components together.
For example, a simple case is you have a list of items. And that list is rendered on the screen via a JTable, and that table is on a JPanel.
Your list has it's own model, i.e. it's not simply a Java List. It's not a List because standard Java Lists don't support PCL notifications. But your Model would obviously wrap such a List.
Now, the next question is how do you wire up JTable to be associated with your List model.
One, you could subclass JTable and bind it to your Model. Or, more simply, you use the JTable as a primitive, and let the enclosing JPanel manage the interaction between your Model and the JTable.
That means having your JPanel implement PropertyChangeListener, and then, when wiring everything up, you do something like this:
ListModel myModel = new ListModel();
ListPanel myPanel = new ListPanel();
myModel.addPropertyChangeListener(myPanel);
Now, whenever your ListModel is changed, is will notify the ListPanel.
On your ListPanel you can having something like:
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(ListModel.CHANGED)) {
ListModel model = (ListModel) evt.getSource();
DefaultTableModel tm = (DefaultTableModel) listTable.getModel();
tm.setRowCount(0);
for (String s : model.getList()) {
tm.addRow(new Object[]{s});
}
}
}
Now, you can see this simply reloads the entire table model, but you can make your property changes as fine grained as you want. You can also see that if this was some other model (like a Person or something) you can populate individual text fields and whatnot on the panel.
This is a pretty simple GUI, but it shows the fundamentals of how this all wires together. I think a bit of this is lost in the Swing examples which are great for one panel screens but don't scale at all when you start adding other views.
Your JPanels basically become combined VC, as your GUI gains complexity you can factor those kinds of things out, but its works pretty well for reasonable amounts of screens and such.
There are two ways in which Netbeans can help you leverage its codebase: GUI Builder (1) and NB Platform (2).
(1) Netbeans had for a while one of the better drag-n-drop GUI builders in the Java world, codenamed Matisse.
That said, it's been a long time since I worked with it - and I never really liked the generated code, it wasn't very comprehensible (which of course is not the purpose of auto-generated code). For more complex UIs we hand-wrote the layout and the work was bearable, even if not the most pleasant. For simple UIs, I'd try GUI Builder again, for complex UIs with a lot of wired logic, I'd probably still would write it by hand.
To see how the GUI Builder works, take a look at one of the many tutorial videos, e.g. this one:
NetBeans GUI Builder: Adding Components
(2) Netbeans Platform is to Netbeans, what RCP is to Eclipse. A rich set of components developed for an IDE, that can be reused. I briefly looked into NB Platform and we would have used it, if the project didn't change course. Maybe this SO question can shed more light on this aspect: Which Rich Client Platform to use?.
Concerning MVC. There was JSR 296, a generic Swing Application Framework, that looked somewhat promising, but was withdrawn in 2011. That did not stop people to fork it and work on it, as this project shows: Better Swing Application Framework, with a release in mid 2012. Even if you do not use such a framework, please do not put all code in one class (as you mention in you comment), but create a simple model/controller and keep the UI components separate. It does not need to be fancy for a simple app, a minimal MVC-ish separation of concerns might suffice.
I also hit this problem and i found a link which gives a good example how to seperate the controller from the view using the NetBeans GUI builder.
Here is the link.
I thought it would be nice if I gave the user the ability to choose and switch between "themes" (L&Fs). I'd give him a choice between Java metal (default), System default, and maybe a couple more I'll download from the internet...
My application is also bilingual (you can pick between two languaes to be displayed).
However, it's important for my application to be fully translated. I can handle the simple stuff, naming JLabels, JButtons, titles of frames, etc...
But there are also some predefined components whoose string I cannot manage as easely (e.g. JFileChooser). I was told that I could change them using the UIManager, but that their strings are L&F specific.
Now, regardless to how much fun would be translating my application for each and every L&F, I hope there is some centralised way of controlling those strings.
After all, JFileChoose (e.g.) is the same component, no matter the L&F that is used, right?
It prints text on the same parts of itself, no?
So, there should be something I could access that would grant me "master" control over the text that is printed onto the predefined components, I assume...
Any ideas?
not easy job,
have to read Modifying the Look and Feel
most important is Changing the Look and Feel After Startup
have to accept that you have to override value for Keys into UIManeger too, NOTICE about one of Look and Feel
is possible that different L&F have got various Fonts and Colors for concrete JComponents, multiply by Native OS
in some cases is important if you'll to change Color or ColorUIResources (Font or FontUIResources)
JFileChooser is compound JComponents, you can to extract its members,
best place to start could be this idea,
Nimbus Look and Feel lives with own life
Does adding HTML tags to Swing components, for example JLabels, make rendering of JFrame slow?
I mean how is the performance of HTML rendering in Swing components?
Yes, depending on the complexity of your html.
Actually when you have html in your jlabel, the BasicLabelUI uses a View to paint the label instead of simple paint logic. Now you can check various different implementations of View class to check how it affects you.
You can read the code of BasicLabelUI.paint() for clarity.
But for simple decorated html, I don't think you need to worry at all.
Swing's HTML rendering support uses many classes, therefore users on older systems might notice a delay the first time a component with HTML formatting is shown. One way to avoid this delay is not to show the HTML-formatted component immediately and to create it (or another component that uses HTML) on a background thread.