I'm trying to make some components inside a JSrollPane unresizable, because content inside can grow dynamically and I must prevent it from growing over a predefined size.
My approach so far is this one:
scrollPane(constraints:BL.CENTER, size:[500,200], maximumSize:[500,200]){
panel(background:Color.WHITE, border:BF.createTitledBorder('Results')) {
gridBagLayout()
f0 = label(constraints:gbc(gridx:0, gridy:0))
fk = label(constraints:gbc(gridx:0, gridy:1))
}
}
(this is Groovy but objects are the same as Swing (eg label = JLabel, panel = JPanel..)
And it works but when inserting into the label a text that is long for example 2000px the first call to repaint in the frame that contains this scrollpane makes the whole scrollpane resize (until the scrollbar actually disappears).
I need to force to remain to the size I want!
Am I missing something? Or is it a bug of groovy? (it seems strange because this should just maps calls to normal swing components)
Why don't you just wrap the text? Anyway, Swing components have setMaximumSize(Dimension) method
Related
I would hide a JButton in a JApplet. I'm using setVisible() method but I've a problem: it works but my GUI is shifted because of the absence of the component. Is there a way to hide a component and make its space occupied???
I know that is possible in Android, but in Java?
ps. To insert component in my JPanel I'm using GridBagLayout!
There are several ways to achieve this in general.
Most proper way is to layout other components in a way that they remain correctly attached at their current positions.
Since for complex layouts the proper way can be hard to get and especially hard to change afterwards, you can apply some layout 'hacks'. For example, instead of adding the button to the panel directly, you could add the button to a separate panel of its own (let's name it buttonPanel), and then add that panel together with the button to the panel containing the other components. That way when you remove the button, buttonPanel will stay to fill the gap.
However, depending on the way how you specified constraints, buttonPanel may shrink when you remove the button. To prevent this, just before removing the button, take the buttonPanel's width and set it as its minimum/preferred width; most LayoutManagers will respect this property.
Of course, you can always resort to hardcoding dimensions to avoid dynamic size calculations, but keep in mind issues with L&F and i18n.
Try using the setOpaque() method. Just do button.setOpaque(false); and that should do the trick. Does that work?
I have a JScrollPane whose client is a Container with layout BoxLayout.
Within the BoxLayout are multiple (dynamically generated) JPanels. However, the JScrollPane doesn't scroll (the scrollbars show and resize, but you can't actually move them), and I also can't interact with the contents of the JScrollPane.
Here's the code:
public static void setupOrderTable(){
orderTable = new Container();
scroller = new JScrollPane(orderTable ,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroller.setPreferredSize(new Dimension(810,500));
orderTable.setLayout(new BoxLayout(orderTable,BoxLayout.Y_AXIS));
if (orderTable!=null)
mainContainer.remove(orderTable);
for (Order o: OrderManager.getList()){
orderTable.add(new ControlRowItem(o));
}
mainContainer.add(scroller,BorderLayout.CENTER);
frame.pack();
}
It works fine if I just replace the line
mainContainer.add(scroller,BorderLayout.CENTER);
with
mainContainer.add(orderTable,BorderLayout.CENTER);
But then it obviously doesn't scroll. Otherwise, as I said, the scrollbars don't work and I can't interact with any of the JPanels within the orderTable.
Don't mix heavy weight (Container) components with lightweight (JScrollPane) components, they just don't mix well. Change orderTable to be a JPanel instead
While it's suppose to have been fixed in Java 6, I've seen too many weird things with trying this to make it worth any effort at all. Simply rule, don't mix heavy weight components (AWT) in Swing containers
I have a problem when I try to resize a JLabel. In my application appears the next strucutre. Understand every list item like something inside the previous list item.
JFrame (Layout null, fixed size, not resizeable, used by different people).
JPanel (Layout null, with a size of all the window, the place were I put my work).
various JPanel with different Layouts (the areas of content inside the main panel, you can think about it like html divs...).
Inside one of this "divs" with Layout null there are extended Classes of JPanel with Flow Layout.
Inside every one of this extedend Classes are labels with preferredSizes.
The thing is that when after create all of this i call theFrame.setVisible(true); and all works propertly.
But in a moment of the flow of my application I have to change the size of one of the labels. Then, I simply call label.setPreferredSize(d) and the change doesn't change. The function works propertly if I call it before set visible the frame, but not after.
I have the feeling that the problem is that I don't use nothing like pack(), validate(), repaint(), etc. Because I don't know what it works. I try call repaint and validate to the jlabel, and repaint the main panel, but doesn't works.
I'm relative new with awt and swing, and this is for homework. Sorry for my bad use of English language, and thank you for your help.
After you change the size of your JLabel, call revalidate(). This will cause the JLabel to be resized without waiting for an event that triggers a re-layout (such as resizing the parent Frame, etc...).
JLabel lbl_test;
lbl_test.setPreferredSize(new Dimension(100, 100) );
lbl_test.revalidate();
One other thing to keep in mind, as I'm not certain which class you're having problems with. Null layouts (absolute positioning) mixed with layout managers are going to cause some strange things to happen.
I am trying to figure out why my JComponent refreshes when I manually drag my window, but it doesn't refresh when I call repaint or revalidate. The data is ready to be displayed, but it just won't show until I manually resize. Can anybody give some suggestions about what I can do or does this sound like it isn't a Swing problem since I tried repaint and revalidate?
One weird things I've noticed is that if I have this code:
sp.setSize(sp.getSize().width, sp.getSize().height+1);
sp.setSize(sp.getSize().width, sp.getSize().height-1);
If the first line is used, then the JComponent will refresh itself. If I use none or both of these lines it will not, which seems bizarre to me.
I am basically just putting a JPanel in a JInternalFrame in a JDesktopPane. There are two main functions for what I am trying to do. One adds the new JPanel and the other tries to refresh it so the new data will show:
public void addNewSP()
{
sp = new JInternalFrame("SP");
sp.setClosable(true);
sp.setLocation(700, 400); //this should be changed to something based on screen size
sp.setResizable(true);
sp.add(popUp);
this.parentContainer.add(sp, JLayeredPane.DRAG_LAYER);
sp.pack();
sp.show();
sp.setSize(500, 500);
sp.setPreferredSize(new Dimension(500, 500));
}
public void refreshSP()
{
sp.repaint();
sp.validate();
sp.repaint();
sp.validate();
parentContainer.validate();
parentContainer.repaint();
sp.setSize(sp.getSize().width, sp.getSize().height+1);
sp.setSize(sp.getSize().width, sp.getSize().height-1);
}
}
BTW parentContainer is the JDesktopPane
When changing the container's content, you have to call both:
revalidate() to make it recompute the layout for its content
repaint() to request a repaint for this container
but it just won't show until I manually resize.
We don't know the context of your question, which is why a SSCCE should always be posted as suggested earlier.
In general a JComponent, does not have a preferred size, so I'm guessing Swing doesn't think it needs to paint the component. When you resize the frame, chances are the component was added to the center of a BorderLayout so it automatically gets sized to fill the entire space of the frame.
The solution is to give your component a "preferred size" so that any layout manager can use this information to display the component properly.
if your are modifying container's subcomponents you should call jcomponent.validate();
I assume parentContainer is the JDesktopPane?
What kind of changes are you making to sp that are not showing up?
Changing the size of sp will cause Swing to repaint from scratch. That's why the setSize() is fixing the display.
Most likely, the changes you are making are either not happening on the EDT, or are not invalidating the right container. For example, if you change the visibility of a component in sp, you'll need to call sp.invalidate() to rerun the layout manager.
Have you checked that you're only changing components (or their models) on the EDT?
A quick test for that is to run with the Substance LAF as it will complain if you change things on another thread.
I have a JScrollpane which contains a scrollable client that changes its size dynamically while using the application. I want the JScrollPane to be aware of the changes without moving the viewport when the client size changes.
To clarify what I mean:
Refer to the Java Webstart example ScrollDemo2 from the article How to use scroll panes by Sun. When clicking at the bottom of the window, a circle appears partly outside the window and the scrollbars move. It's the latter behavior I want to avoid.
My guess is that it's just a matter of setting a simple flag in one of the many components that are involved in a scroll pane solution, but I just can't find where it is. Does anyone know?
I managed to solve this problem by overriding the standard behavior of the viewport in my JScrollPane. This might be a solution that is not suitable for all, but in my GUI this works like a charm.
JScrollPane pane = new JScrollPane();
pane.setViewport(
new JViewport(){
/**
* An empty override implementation to prevent undesired scrolling on
* size changes of the client.
*/
#Override
public void scrollRectToVisible(Rectangle rect){}
});
I would try something like:
Point p = scrollPane.getViewport().getViewportPosition();
revalidate();
scrollPane.getViewport().setViewportPosition(p);
You may need to wrap the last line of code in a SwingUtilities.invokeLater.
If that doesn't work then maybe you can disable/enable the viewport before and after the revalidate()?