I need to create a panel where I can put some rectangles and it automatically reorder just inserting a scrollbar and growing up vertically. Also this panel can be resizable and again the rectangles must to be reordered to correctly be displayed inside the panel.
If I understand the question you want components to wrap to the next line so that the panel grows vertically while the width remains fixed.
If so then check out the WrapLayout
Note: the FlowLayout already supports the wrapping of components to a new row on the panel. This issue is that the preferred size calculation assumes all components are placed on a single row. The WrapLayout overrides the preferred size calculation to support the wrapping of components on a new row.
Use a JScrollPane. If you never want a horizontal scroll bar you can add the following:
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
(By default the scroll pane will add horizontal and vertical scroll bars when required.)
The scroll pane itself will only be resizeable if you add it to a Container with the appropriate layout manager; e.g.
JFrame frm = new JFrame();
frm.setLayout(new BorderLayout());
JScrollPane sp = new JScrollPane();
frm.add(sp, BorderLayout.CENTER); // Adding a component to the CENTER will cause the component to grow as the frame is resized.
Related
I have a JScrollPane and a JPanel.
JScrollPane scrollPane_yst = new JScrollPane();
scrollPane_yst.setBorder(null);
scrollPane_yst.setViewportBorder(null);
panel.add(scrollPane_yst);
JPanel panel_yst = new JPanel();
panel_yst.setPreferredSize(new Dimension(150, 1000));
panel_yst.setBorder(null);
panel_yst.setBackground(Color.DARK_GRAY);
scrollPane_yst.setViewportView(panel_yst);
panel_yst.setLayout(new BoxLayout(panel_yst, BoxLayout.Y_AXIS));
During runtime, I add other components to panel_yst, but it doesn't get bigger when the components exceed its size.
(Same problem with and without setting preferred size)
ANSWER:
I found the solution. The problem was, that I set the preferred size of the panels that I lateron added onto the panel inside the scrollpane.
Because of that, the size of those panels was messed up. Just dont set the PreferredSize of the components that you add onto the panel.
I found the solution. The problem was, that I set the preferred size of the panels that I lateron added onto the panel inside the scrollpane.
Because of that, the size of those panels was messed up. Just dont set the PreferredSize of the components that you add onto the panel.
I am opening a window with the following:
JFrame clientFrame = new JFrame("Frame");
clientFrame.setLayout(new BorderLayout());
final JPanel client_panel = new JPanel();
client_panel.setLayout(new BorderLayout());
client_panel.add(new Applet());
client_panel.setPreferredSize(new Dimension(765, 555));
clientFrame.getContentPane().add(client_panel, "Center");
clientFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
clientFrame.pack();
clientFrame.setVisible(true);
the frame has a random picture on it.
By default when you drag the bottom border upwards, it will naturally remove from the image from the bottom of the image.
The same if you drag the top border downwards it will again remove incrementally from the bottom of the picture.
How do I swap it around so instead it removes form the top of the picture instead of from the bottom?
clientFrame.getContentPane().add(client_panel, "Center");
Don't use magic values. People don't know where "Center" comes form. Use variables provided by the API:
clientFrame.getContentPane().add(client_panel, BorderLayout.CENTER);
What you are asking is not possible with any layout manager that I am aware of. The problem is that the layout manager only knows about size available to the component. It does not know why the size changed (ie, drag up or down). So the layout manager can only define rules based on the space available.
As a simple test use a JPanel with a BorderLayout. Then create a JLabel with containing an ImageIcon. Add the label to this panel and then add the panel to the content pane of the frame.
If you add the label to the BorderLayout.CENTER, then the image is centered in the space available so you lose part of the top and bottom.
If you add the label to the BorderLayout.PAGE_START then space is always taken from (or given to) the bottom of the component.
If you add the label to the BorderLayout.PAGE_END then space is always taken from (or given to) the top of the component.
If you want to consider the drag up or down of the frame then the solution gets much more complicated because you will need to add a ComponentListener to the frame and handle the componentResized and componentMoved methods. You will then need to track the previous state of the frame and then determine which properties have changed and then you will need to do custom painting of the image based on the property changes or you will need to write a custom layout manager that is aware of the property changes.
I'm looking to wrap a JPanel when it reaches the 'edge' of the screen using MigLayout. At the moment I have a JScrollPane (which I only want to be enabled vertically). The JScrollPane contains any number of JPanels which are arranged horizontally - when a panel is added so that the JPanel would go off the edge I want it to add to the next line. Is this possible?
This is the code:
public void setupPanels(){
JScrollPane scrollPane = new JScrollPane();
JPanel mainPanel = new JPanel(new MigLayout("insets 2"));
for (Object object : objects){
JPanel subPanel = new JPanel(new MigLayout("insets 0"));
mainPanel.add(subPanel, "alignx left, gapx 2px 5px, gapy 2px 2px, top");
}
scrollPane.setViewportView(mainPanel);
}
Also, to add an extra factor, every time it reaches the edge I need to add a new/different panel (a timeline) - so is there a way of finding out when it is going to wrap onto a new line?
Thanks
MigLayout does not have such a feature. It is based on a grid and while you can use the nogrid option to flow components horizontally or vertically in a cell span, you cannot make them flow into the next row or column.
The java.awt.FlowLayout contained in the JDK wraps the contained components automatically:
JPanel mainPanel = new JPanel(new FlowLayout());
mainPanel.add(subPanel1);
mainPanel.add(subPanel2);
mainPanel.add(subPanel3);
...
The preferred height is off, but there are ways to fix this, see WrapLayout.
As for the second requirement:
Also, to add an extra factor, everytime it reaches the edge I need to
add a new/different panel (A timeline) - so is there a way of finding
out when it is going to wrap onto a new line?
A layout manager should layout components that have already been added to a container, not add new components based on the results of the layout. Adding invisible placeholder components for the timeline after each subpanel that are made visible by the layout manager on demand might work.
You definitely need a custom layout manager to do this. To get started I would recommend to take the source of FlowLayout. In the layoutContainer implementation there is a loop that iterates over all components. After a line wrap, check if the next component is a timeline placeholder component, make it visible and wrap again.
I have a JFrame window, and I'd like to add a scrollable JTable towards the middle of it. I have a method, called collectionTableScrollPane() that generates the JScrollPane (and I know this is guaranteed to work).
I then proceed to add it to my mainPanel panel. However, I'd like there to be some forced 30px padding on the left and right of the JScrollPane. Logically, I would create a holding JPanel with a centred FlowLayout, and add Box.createHorizontalStrut(30) either side of the JScrollPane.
JPanel tableHolderPanel = new JPanel(new FlowLayout());
mainPanel.add(tableHolderPanel);
tableHolderPanel.add(Box.createHorizontalStrut(30));
tableHolderPanel.add(collectionTableScrollPane());
tableHolderPanel.add(Box.createHorizontalStrut(30));
However, I'm getting a strange result, where the JScrollPane in the middle of the window (denoted by the arrows) sort of becomes ineffectual.
Does anyone know what the problem is?
Note that the JTable contains four rows, of which only two are visible.
I had some issues in the past when i used a JScrollPane inside a panel with a FlowLayout. The behaviour could be tricky, when the content grow, the horizontal scrollbar may appear or the FlowLayout should add a new line.
In your case, i will replace the FlowLayout by a BorderLayout :
JPanel tableHolderPanel = new JPanel(new BorderLayout());
mainPanel.add(tableHolderPanel);
tableHolderPanel.add(Box.createHorizontalStrut(30), BorderLayout.WEST);
tableHolderPanel.add(collectionTableScrollPane(), BorderLayout.CENTER);
tableHolderPanel.add(Box.createHorizontalStrut(30), BorderLayout.EAST);
As far as I'm aware, Box is suppose to be used with the BoxLayout, this may be causing you some issues. Instead, why not use a EmptyBorder on the tableHolderPane
BoxLayout accepting size that came from JComponents, the same issue with default FlowLayout pre_implemented for JPanel
you have to returns PreferredSize by overrode JPanel nested JScrollPane,
use another LayoutManager, e.g. GridBagLayout or todays MigLayout
use NestedLayout, by using BorderLayout where you put two JLabels (e.i. that returns PreferredSize) to the EAST and WEST area
everything depends if you really to want to create the empty area and if shoud be resiziable or not
I want to add different buttons, vertically stacked, to a JPanel at run-time and use a JScrollPane so that all buttons will be visible (with some scrolling).
In order to do this, I have added my JPanel to a JScrollPane, after which I add buttons to my JPanel.
However, when I do this the vertical scrollbar does not allow me to see all images. For example when I add 7 buttons I can only scroll to see 5 full images and half of the 6 images.
Why doesn't my scrollbar allow me to display all 7 buttons?
Create the panel and scrollpane like:
JPanel panel = new JPanel();
JScrollPane scrollPane = new JScrollPane( panel );
When you add buttons to the panel at run time the code should be:
panel.add( button );
panel.revalidate();
As long as you are using a layout manager the preferred size will be recalculated and the scrollbar will appear.
Make scroll pane a wrapper over your panel - new JScrollPane (myPanel) and add it instead of naked panel in your panel's container.
You also may want to play with its setPreferredSize() method.