I have a GUI setup that looks like this:
It displays a document and enables user to edit it by adding/removing JTextAreas and text in them.
I have a problem when trying to open the document. Document itself is made up of layers of JPanels on top of each other. There are never more than 6 layers of JPanels at a single point in the GUI.
Since I don't know what the height of the JTextArea will be, I have to make it relative to the parent (in other words, not specify it).
Because the layout manager (MigLayout) doesn't know the exact size of the component (it's relative to the parent), it first asks its parent for the parent's size. That size is again unknown and the parent's parent is asked and so on (until a level 1 or 2 JPanel). In the end it has to ask a lot of components for their size (a method checkParent(Container) within MigLayout was called over 100 000 times just for the example above).
What I need to do is set the height of the JTextArea (or the JPanel that it resides in) only when the document is being opened, so the layout manager doesn't have to ask JTextAreas parent, causing a recursive hell.
After the document is opened I have to reset the height to default (so the height adjusts when the text is added/removed).
I have absolutley no idea how to do this, or if this is the way to go, I'm only sure that the thing I described above is the problem.
Several notes:
this is not a MigLayout bug, I have been to the forums(link below)
check this out (the last post)
I can't put a JScrollPane into the JTextArea as its task isn't only to hold the information, but to display exactly how much room it takes
I can easily get the heights of the JTextAreas when saving the document, thus having them at my disposal when opening it again
EDIT:
The document referenced in this question is not "the document" as thingy used in JTextAreas and similar, but "a document" as in custom class in my program (which I didn't mention because it is irrelevant, unless it's understood as "the document").
Because your Document models a hierarchical structure, you need a tree. Because your interface requires both a control and a view for each node, you need a table. Outline, seen here, might be a suitable choice. Your DocumentTreeModel would hold a reference to the document's root Element, just as the example's FileTreeModel holds a reference to the root File. Your RowModel would include a JLabel, a JCheckBox and a JTextArea.
Related
I´m building a simple word-editor in java. Currently, everything´s working fine. Now I want to create "Pages", like in word. The JTextPane representing a Page is supposed to check if it´s full and then create a new JTextpane under it. With a scrollbar I would be able to scroll between them. So far this wouldn't be problematic. However, all the pages should belong to a single document, and if I were to delete a line on let´s say page 2, every line on every other page will be moved up. (For example) Is there an easy way to do this, or will I have to create DocumentListeners for each JTextPane, changing everything on each change? Also, is there a way to extend selections over multiple pages?
Personally I havn't tried anything as of yet, since I want some tips before writing myself into a corner. I thought that I could make the pages uneditable, and instead use a caretListener to check the position the user clicks on, to edit an invisible infinite JTextPane containing the actual document, which would write it´s content to the visible pages.
Lots of unknowns, but maybe the following will give you something to think about.
all the pages should belong to a single document,
Agreed.
The JTextPane representing a Page is supposed to check if it´s full and then create a new JTextpane under it
Maybe add each text pane to a JScrollPane, but don't display the scrollbars or Border of the scroll pane.
if I were to delete a line on let´s say page 2, every line on every other page will be moved up
You would need to manually control the viewport of each scroll pane. The first page would position the viewport at offset 0. The next page would position the viewport at the offset that represents your page height.
Then any changes to the Document should be automatically reflected in all the text panes.
You would also probably need to use setAutoScrolls(false) to prevent the viewport from scrolling as you drag the mouse.
is there a way to extend selections over multiple pages?
Selection is a property of the text pane, not the Document.
Not sure what will happen as you try to drag the mouse from one text pane to another.
I'm guessing you might need some special logic. Maybe using mouseEntered/Exited events to trigger this type of processing.
My goal is to have a program with 3 panes. A mulitfactor Auth. The first pane will have the user type in a passphrase, while the second pain will allow the user to pick a image from a drop down list. But I want the 3rd pane to launch just to the right of the 2nd pane after the use selects a image in the same "Main" stage.
Not looking for someone to code a program just point me in the right direction to what im trying to do. My searching skills are failing, either im not explaining it right or theres another word for this.
Edit:
This is my idea of how i want it to work. Now that i look at it using a border pane probably makes since, But im still stuck with, How can I launch each section of the border at a different time, i.e when something is clicked.
I would go about it by having 3 panes side by side and just blank for the first FXML file you load in. I would then have another FXML file with the same layout that contains what you want to show up in those panes.
Then with that, you can have the controller on request (like when a user hits submit or however you are wanting these to show up) grab the content inside of the pane on the second FXML file by ID and load it into the pane.
I've done something similar with changing anchor panes and keeping the toolbar from the original so I can add more on this when I get home and should be able to supply some code that is modified to fit your issue.
Edit 1: Sorry I was in a hurry to submit that dive I had to go but I am on mobile now so I can edit but not able to add a lot, just felt I needed to say, there are different options for what you can use to do this which is why I just said a pane instead of anything specific. Just wanted to submit something so you can start looking in the right direction till I am able to update.
Edit 2: Alright now that I am home I tried this out and was able to get this working. Here is how I did it.
So I had two FXML files. One with the 3 areas that you have your items, however, only the box that you want to show when it starts is shown. Each area is enclosed by an AnchorPane. I used the AnchorPane as a container so I can swap out what is inside of it. I then had a second FXML file that had all of the boxes you want to show all of which enclosed in AnchorPanes. Here are pictures explaining what I mean.
I have the first pane named initial.fxml and the second named grabfrom.fxml. For the pane names, I just have it as pane1, pane2, and pane3. Lastly, the methods I have are show2() and show3() and call them from the FXML when the respective buttons are clicked inside of the AnchorePanes.
With initial, I just load that up as normal from the start method in my main class and that is all that is needed to be done with that. We only had it so we could display something that does not have the boxes showing before needed.
Now for the important part
With what I have in show2(), which is called when the button inside of the first pane (which is there from the start) is pressed.
public void show2() throws IOException{
AnchorPane toSetPane2=(AnchorPane) FXMLLoader.load(getClass().getResource("grabfrom.fxml"));
toSetPane2=(AnchorPane) toSetPane2.lookup("#pane2");
pane2.getChildren().setAll(toSetPane2);
}
What this is doing is loading the grabfrom.fxml into a temp var that we cast to an anchor pane. (Do note that this works since as you can see in the screenshot the whole FXML file is an anchor pane. If you're not using it that way you can take out the casting and cast to something you are using or not even cast depending on what it is.)
It then set the var we just made to just the AnchorPane we need, which is the second one since that's the one we are adding. It does this with the .lookup("#ID"); method to get just the pane we need.
Lastly, it sets everything inside of the current pane2 to toSetPane2.
This could all be compressed down into one line, however, I have left it as is for easier reading.
You should be able to use this method of loading in a portion of your application for loading in the third one and for that matter any other parts you want to in any situation.
Edit 3:
Also as #Swatarianess had said, there are stackpanes, this method will work with anything that you can set an ID to so they would work just as well. I used AnchorPanes because I have done a fair bit with them and had some code I could recycle whilst making a test for it so it was easier. All you would do if you were using those though is just cast to a StackPane instead of an AnchorPane like this:
public void show2() throws IOException{
StackPane toSetPane2=(StackPane) FXMLLoader.load(getClass().getResource("grabfrom.fxml"));
toSetPane2=(StackPane) toSetPane2.lookup("#pane2");
pane2.getChildren().setAll(toSetPane2);
}
The transition between panes could be done with a stackpane.
I'm developing a small GUI using JavaFX for an assignment. Having never used JavaFX before, most of what I've used or learned I've research myself. Most of my application runs smoothly, animations included.
I have a small user input section:
I'm trying to allow it to swipe left prior to loading the next scene, to give the user the impression of sequence. I achieved this using a ParallelTransition populated by TranslationTransitions in which I load all of these Nodes.
However, just slightly before it animates, it appears to align everything right.
I have a feeling this is something to do with the container (AnchorPane) in which I'm placing these objects, or some undefined attribute which I'm not setting. As I'm learning this all on the fly, it's a bit difficult to narrow down. Can anyone give me an idea as to what is causing this and how I can retain the alignment? Each Node moves in the following way:
translateTransition.setFromX(node.getLayoutX());
translateTransition.setToX(node.getLayoutX()-500.00);
If I've left out any pertinent information, please let me know!
So, my issue turned out to be the way I'm laying out my objects. Placing them in an arbitrary AnchorPane with only specific attributes to locate those items means that, upon animation, it will group those objects and animate them accordingly. It was the incorrect way to layout those nodes.
Instead, I've placed them in a VBox which has two advantages.
I can align the contents of that VBox centre, so I need not specify the exact layout attributes of the elements.
I can animate using the single VBox, as opposed to the all the elements in a ParallelTransition. As a result, a single TranslateTransition on the VBox node will suffice!
Iam studying about JTree right now.
But i don´t know how to render content of choosen JTrees node in e.g. bottom part of my application.
Lets say i would make application with content - see my picture.
I know how to make JTree, but how to manage - if i click on e.g. SUV just bottom part of my application will change the content, JTree remains and upper part as well. still just bottom part changes its content. e.g. suv - info about SUV, CABRIO - info abou cabrio.
Do I need another JPanels for upper part which will be stable?
Do I need another JPanels for botton part which will not be stable?
I really need help with this issue, or some link, where can i find answer on my question
Thanks
You need two separate components:
A JTree
A separate JPanel
You need to add a TreeSelectionListener to the JTree. That will let you know when the user has selected one of the values in the JTree, and you can use that selection to change the contents of the JPanel.
You'll need another JPanel for your area labeled, "This part remains the same". You will probably want to put the two JPanels in a JSplitPane with a VERTICAL_SPLIT.
I'm intentionally leaving out some of the implementation details because it looks like you're completing a homework assignment.
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