In my Java Swing app there is a JSplitPane that splits vertically, top part is a JLabel which may change size when I click a button to update some info, bottom part is a JPanel that shows some results.
My code looks like this :
JLabel Top_Label=new JLabel();
Top_Label.setPreferredSize(new Dimension(1420,355));
JPanel Bottom_Panel=new JPanel();
Bottom_Panel.setPreferredSize(new Dimension(1420,445));
JSplitPane Results_Split_Pane=new JSplitPane(JSplitPane.VERTICAL_SPLIT,Top_Label,Bottom_Panel);
Top_Label contains an html table in it. When I click a button to update data, the Top_Label sometimes contain fewer lines of data in the html table and shows a lot of empty space.
Right now, when the Top_Label shows a small html table, it will remain its original size, and leave a lot of empty space, but after I adjust it to smaller space and click the button to update data to have a large html table, it won't enlarge the area to fit that larger html table, and yet when I manually move the split bar, it's intelligent enough to not go smaller than the html table's height, but if there is empty space, it will let me shrink the area.
How to let Results_Split_Pane auto adjust itself according to the height of Top_Label, so that when there is less content, the split bar will go higher to the height of the html table in Top_Label, when Top_Label contains more data, the Results_Split_Pane's split bar will go lower ?
A JSplitPane doesn't have an automatic adjustment feature.
I would suggest you could:
add a PropertyChangeListener to your JLabel
and listen for the text event
get the preferred size of the label
use the setDividerLocation(...) method of the JSplitPane to be the preferred height of the label.
Thanks to "camickr", I got the perfect answer for it, skip step 3 and use "-1" so that the JSplitPane will auto adjust to it's size, works great. Here is the listener :
Results_Top_Label.addPropertyChangeListener(Property_Change_Listener);
...
PropertyChangeListener propertyChangeListener=new PropertyChangeListener()
{
#Override
public void propertyChange(PropertyChangeEvent event)
{
// Out("[x] : "+event.getPropertyName());
if (event.getSource() instanceof JLabel && event.getPropertyName().equals("html"))
{
// Out(((JLabel)event.getSource()).getName()+" : Height = "+Results_Top_Label.getPreferredSize().height);
Results_Split_Pane.setDividerLocation(-1);
}
}
};
Related
I hope I did not miss some duplicate question, I feel like this should be trivial!
Anyway, I have a JTextArea with text in it, with automatic line wraps:
public PleaseResize(){
super();
Container cp = this.getContentPane();
JTextArea area = new JTextArea();
area.setColumns(20);
area.setLineWrap(true);
area.setEditable(false);
area.setWrapStyleWord(true);
area.setText("Once upon a midnight dreary, while I pondered, weak and weary, over many a quaint an curious volume of forgotten lore.");
cp.add(area, BorderLayout.CENTER);
cp.add(new JButton("Hallo"), BorderLayout.SOUTH);
this.pack();
}
I want the text area to resize vertically to display the whole text... but it does not. It resizes happily if I choose the line breaks via pushing in \n, but with automatic wrapping, it just remains the size it is.
I somehow feel like I am missing something totally obvious...
Edit: for clarification:
On creation-time, I do not know how many lines the text will have (due to the automatic linebreaks happening). I am receiving Text via an XML-file, and it can vary between 0 and about 30 lines after wrapping. I have the vertical space to display everything, but I do not want to scroll or to have a huge, white area when there is no or only a little text to display.
Edit 2:
After rephrasing the question, they key to the problem I was facing was apparently not resizing the JTextArea, but making sure the dialog knows how big it is!
So, here is the link back to the solution I ended up using: An automatic resizing Text above a button?
You need to wrap JTeatArea with JScrollPane like next new JScrollPane(area); and then add JScrollPane to your JFrame.
Also you create JTextArea with empty constructor, use JTextArea(int rows, int cols) to specify count of rows and columns.
I am having a hard time to properly set the way my swing components behave on resize.
I have two problems with that interface:
A: The toggle button at the beginning of each row is here to collapse/expand the text. All the elements are contained in a JLayeredPane. On the button click, I edit the pane's height to expand or collapse the content (either 31 or 310). Expand works fine an pushes the elements below. On the other hand, collapse does hide the text but leaves all the elements in position. Here is my code:
private void expandText(java.awt.event.ActionEvent evt) {
JToggleButton button = (JToggleButton) evt.getSource();
Container parent = button.getParent();
Dimension size = parent.getSize();
String icon;
if (button.isSelected()) {
size.height = 310;
icon = "/org/cytoscape/ocsana/resources/images/minus.png";
} else {
size.height = 31;
icon = "/org/cytoscape/ocsana/resources/images/plus.png";
}
parent.setSize(size);
try {
button.setIcon(new ImageIcon(ImageIO.read(getClass().getResource(icon)).getScaledInstance(-1, 15, Image.SCALE_SMOOTH)));
} catch (IOException ex) {
}
backgroundPane.revalidate();
backgroundPane.repaint();
}
B: The screenshot above is the minimum size of the window. When I resize the window horizontally, the inner pane only resize to the value of min + (frame.width - min) / 2 meaning my right scrollbar does not stick to the right side of the frame.
See below a demonstration of the both problems:
Well, you could add a listener to the frame so have an action on event when the frame is being resized. And then pack() the frame.
public final class TestFrame extends JFrame {
(...)
this.getRootPane().addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
this.pack();
this.revalidate();
}
});
}
It you are using the paint graphic method, you should as well repaint() your frame.
In that method you can also manyally set the preferred size of the window by computing it based on e.getWidth()
How does your expand/collapse code work? Do you just make component visible/invisible, or do you add remove components from the panel?
On the other hand, collapse does hide the text but leaves all the elements in position.
If you add/remove components then the basic code is:
panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint();
meaning my right scrollbar does not stick to the right side of the frame.
It depends on the layout manager you are using. I would guess the easiest would be to use a GrigBagLayout. It allows you to "fill" the space available. Read the section from the Swing tutorial on How to Use GridBagLayout for more information and examples.
All the elements are contained in a JLayeredPane.
Not sure why you are using a layered pane. By default a layered pane doesn't use a layout manager.
According to camickr answer and comments, see how I solved it:
Point A is due to my free layout used in NetBeans. I did not succeed to fix my code so I changed the structure of my elements. It is probably not optimal and does not use all the swing concepts right, but it works the way I want.
I have a JLayeredPane in the background that uses a GridBagLayout. This background pane contains one column of JPanel of height 30 and 260, one for the summary line, the other one for the details.
The expand/collapse function controlled by the JToggleButton works by hiding the below panel belowPanel.setVisibility(false). No need for repack or anything, just that. Here is how the code looks like without changing the button's icon:
private void inverseVisibility(JToggleButton expand, JPanel target) {
if (expand.isSelected()) {
target.setVisible(true);
} else {
target.setVisible(false);
}
}
As I only wanted the elements to resize horizontally, all my panels have Horizontal as Fill value and Northwest as Anchor. I've set the weightX = 1; weightY = 0. Finally I added a panel in the bottom with a Southwest anchor and fill both along with both weights to 1 (not sure it changes anything but this way I am certain that it will fill all the blank space at the bottom it the window is resized at a bigger size than its content).
Point B has been solved by taking my background panel, that fit in my Frame, and putting it into a JScrollPane. The error I had was due to the Netbeans editor that did not properly stick the scroll pane to the side of the frame, due to incoherences in the sizes defined in both the frame and the scroll pane. My advise to you if you are using this tool is to set the fewest values as possible as a lot of values are heavily interconnected by the gui designer.
Get the full code (95,864 bytes)
I have a String[] with 115 names. Now of course, i cannot fit all these names at once on a screen that i've set to be 1280 x 720.
I would like to display let's say 15-20 of these as buttons from the top of the screen until they hit the bottom, and the right side of the screen is an image, so we're lookin for a GridLayout(115, 1);
How would i go about to create this so that i can see a few names, and the rest of the are further down in the list and i access them with a scrollbar? My program extends JFrame and the item to the right is a 720 x 720 JLabel that is one big picture.
Did not add my code since there is no specific questions asked here, merely what classes i'd be using and how i would go about to proceed and use them. I've done some research on JScrollPane , JList and such.
Start by taking a look at
How to use scroll panes
How to use lists
Basically, a scroll pane controls a single component which acts as the view. The scroll pane acts like a window, allowing you to see a position of the view if it is larger then the scroll panes viewable size...
JList iist = new JList();
List.setModel(...);
JScrollPane sp = new JScrollPane(list);
// add sp to something ...
Using a JScrollBar, you can add a class with myScrollBar.addAdjustmentListener(this) so it will call your AdjustmentListener's adjustmentValueChanged(AdjustmentEvent e) method. In this method, use e.getValue() to get the value of the scroll bar. Interpret this value (with some good 'ol mathematics) to update the visibility/invisibility and x/y positions of your buttons!
For more, read up a tutorial on JScrollBar's.
Don't forget to set the orientation, min and max values, etc.
I am writing a code in Java Swing in which a label is added in frame on the click of the button. And the Labels are added such that it overlap each other to create a stack like view.
I am creating my own layout using label.setbouds(x,y,100,100) function.
And each time button is clicked in its action listener a new label is added.
For example
if(e.getSource()==button){
label.setBounds(x+5,y+5,100,100);
frame.add(label);
frame.repaint();
}
Now the problem is when these labels are painted the first label added always remain on the top and newly add Labels are overshadowed by odd label.
I need a help if someone could explain how i can paint the frame such that newly added frames comes on the top and old labels get overlapped.Any suggestion is appreciated
Regards
ACoder
Insert your labels in a JLayeredPane with the proper index. Also make sure to set your JLabel as opaque (setOpaque(true)) so that it will actually obscure the content of the labels below. However, if a label below is bigger than the label on top, you will still see some part of it
I want my JTextArea to resize itself (expand vertically) when the last line (that the text area's height can offer) is reached and the user wants to start a new line. You know, like the textbox in MSWord.
I have an idea to use getLineCount() and determine (if necessary) the new height of the JTextArea. Do you have, or know of better approaches for implementing this?
Actually, the JTextArea always has the correct size so all lines of text are visible. What you experience is probably that you wrapped the text area in a JScrollPane. Just omit the scroll pane and make the text area a direct child of the container.
Another solution is to listen to resize events of the text area and size the scroll pane accordingly. This way, you can grow to a certain size and then start to display scroll bars (for example, when someone pastes 500KB of text into the text area).
I had the same problem. From my tests, I do not believe that the JTextArea sets its size dynamically. Instead, its size seems to be limited by its container (a JPanel in my case). However, the JTextArea does change its preferred size based on the text it contains. From the documentation:
java.awt.TextArea has two properties rows and columns that are used to determine the preferred size. JTextArea uses these properties to indicate the preferred size of the viewport when placed inside a JScrollPane to match the functionality provided by java.awt.TextArea. JTextArea has a preferred size of what is needed to display all of the text, so that it functions properly inside of a JScrollPane. If the value for rows or columns is equal to zero, the preferred size along that axis is used for the viewport preferred size along the same axis.
Go to JTextArea "Properties" - checklist "lineWrap".
I had the same problem,I put the JTextArea into a JScrollPane and set the preferred size of JTextArea, and I believe that's the cause of the problem.
So the right solution is to put the JTextArea into a JScrollPane, and don't touch the preferred size of JTextArea, set JScrollPane's instead.