Resizable scrollpane to an awt frame - java

I need to add a scrollable JPanel to a AWT frame that can scale when the frame is re-sized. The scrollpane appears when I set it a fixed size. But I need the panel to cover the whole frame and re-size automatically when I re-adjust the frame size.
Composite composite = new Composite(parent, SWT.EMBEDDED | SWT.NO_BACKGROUND);
Frame frame = SWT_AWT.new_Frame(composite);
SimulationPanel simPanel= new SimulationPanel(WIDTH,simPanelTotalHeight);
JScrollPane scrollPane = new JScrollPane(simPanel);
scrollPane.setSize(new Dimension(500,400));
JPanel contentPane = new JPanel(null);
contentPane.add(scrollPane);
frame.add(contentPane);

Don't set the JScrollPane's size or its preferredSize. Either can mess with its ability to re-size if needed.
Instead add it to a container using a layout that allows it to re-size with the container. BorderLayout comes to mind. Make sure that the container hierarchy also attaches to the top-level window in some decent way using a smart combination of layout managers. This is one of the key reasons to understand well and use the layout managers.
Don't use null layout, and in fact that is one thing that is messing up your code.
As a side issue: Why use AWT's Frame and not Swing's JFrame? This doesn't make much sense.

Related

How to set size of JScrollPane according to JFrame size?

I have been working on a JFrame, which contains a panel of multiple components. However, the frame cannot accommodate all components due to its size. I wish to use a scrollable frame, and came across a link where JScrollPane use is suggested. However, when the frame is resized, the scroll pane container does not take up the size of the resized frame.
Is there a way to achieve this?
By default a JFrame uses a BorderLayout. When you add a component to the CENTER of the BorderLayout the component will take all the available space of the frame.
So the basic logic is:
JPanel panel = new JPanel(...);
JScrollPane scrollPane = new JScrollPane( panel );
frame.add(scrollPane, BorderLayout.CENTER);
Set the frame to use grid layout. Gridlayout makes all of the components in the frame use up the entire size.
Container contentPane = frame.getContentPane();
contentPane.setLayout(new GridLayout(1,1));

JScrollpane does not autoresize when there is a JTable inside. Work around?

It has been identified as a possible duplicate of the question:
JPanel Window not scaling when resize the main frame
I do not agree, because at that topic the problem is that the JPanel does not resize. In my case, the JPanel has no problems, but the JScrollPane is not getting resized!
I have a JFrame, there is a JPanel inside, containing a JScrollpane, which contains a JTable.
The problem is, that if the JFrame is resized, the JScrollpane stays the same, doesn't matter if the JFrame is made really small, so that the scroll pane does not even fit in the window or really big.
I want to make the JScrollpane adjust itself according to its JPanel, which gets adjusted by resizing of the window.
If the same thing is done by using a JTextArea inside the JScrollPane, everything works just fine -- resizing the JPanel resizes the scroll pane.
Do you have any idea why the JTable ruins the automatic resizing of the JScrollPane, and how to get around it? It seems, that the LayoutManager somehow is not able to handle it properly... (I also tried to add images showing what's happening, but I still don't have enough of reputation...)
Here is the code:
JFrame tableFrame = new JFrame("Test Table");
editPanel vadEditPane;
vadEditPane = new editPanel(vadData);
vadEditPane.setOpaque(true); //content panes must be opaque
tableFrame.getContentPane().add(vadEditPane, BorderLayout.CENTER);
public class editPanel extends JPanel {
public editPanel(dataConv vadData){
JTable vadTable;
String[] columnNames = {---SOME COLUMN NAMES---};
Object[][] data = {---SOME DATA---};
vadTable = new JTable(data, columnNames);
vadTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
vadTable.setFillsViewportHeight(true);
vadTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane scrollPane = new JScrollPane(vadTable);
scrollPane.setBackground(Color.RED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollPane);
setBackground(Color.ORANGE);
}
}
I do not agree, because at that topic the problem is that the JPanel does not resize. In my case, the JPanel has no problems, but the JScrollPane is not getting resized!
If you read the comment in the first answer and take the time to understand the suggestion you will indeed find that the solution is the same.
The answer there states that a JPanel uses a FlowLayout (by default). The FlowLayout respects the preferred size of any component added to it. So the size of the table will never change even as the frame size changes.
So the solution suggests to change the layout manager of the panel so that the child components can be resized as the size of the panel changes. I would suggest using a BorderLayout.

Adding panel with without layout to the NORTH of BorderLayout

Colleagues.
I'm trying to construct simple GUI in Java, where JFrame has Border Layout. I want to put JScrollPane with JTable to CENTER, and JPanel without layout to NORTH.
The problem is that JPanel doesn't visible. There is simple examle of the problem:
JFrame frame = new JFrame("Test frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Test button");
button.setBounds(10, 10, 40, 20);
JPanel panelN = new JPanel(null); // layout = null, panelN without layout
panelN.add(button);
frame.add(panelN, BorderLayout.NORTH);
JTable table = new JTable(new DefaultTableModel(4, 4));
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(400, 400);
frame.setVisible(true);
You have to use a LayoutManager. It's totally discouraged not using layoutManager, but if you want this you have to set panel.setBounds(..) to the panel too.
By default JPanel has FlowLayout so if you put
JPanel panelN = new JPanel(); // FlowLayout used
panelN.add(button);
frame.add(panelN, BorderLayout.NORTH);
So your frame will look like this.
Layout Managers determines the size and position of the components within a container. Although components can provide size and alignment hints, a container's layout manager has the final say on the size and position of the components within the container.
It's strongly recommended cause for example if you have to resizes components or show in differentes resolutions you delegate this work to layout managers
I don't know the expected behavior of a null layout, but without further requirements you might as well just instantiate with the zero-arg constructor:
new JPanel();
If you didn't set any layout to the panel, when adding components the panel don't know where to put the component, so baisicly the component don't show until you set a specific location for components one by one by component.setBounds(x,y,width,hieght) method.
Note that it's not a good practice to remove the layout manager because of the different platformes, suppose that your program working on Window and MacOS and Linux, you'v better to use the layout managers instead.
Take a look at this post also and see #Andrew Thompson's comment on my answer:
Java GUIs might have to work on a number of platforms, on different
screen resolutions & using different PLAFs. As such they are not
conducive to exact placement of components. For a robust GUI, instead
use layout managers, or combinations of them, along with layout
padding & borders for white space, to organize the components.
After all:
If you have a requirement or an assignment telling you you must use absolute layout, then use it, otherwise avoid it.
It is OK to use containers with no layout manager because you actually CAN set container's layout to NULL. And it's a nice idea to position your components with setBounds(). But in this case, you just have to consider your container. What size it need to be? A layout manager would calculate this for you, and if you don't have one, you have to set the size of your panel by yourself, according to components you have added to it.
As pointed by others here, the case it that the border-layout manager of your frame needs the preferred size of your NORTH panel (actually, the preferred height). And you have to set it, or values will be zeros and the container will become invisible. Note that for the CENTER panel this is not needed as it gets all space possible.
I had a problem like yours before and have written a fast function to resize a container according to bounds of a given component. It will be as large as needed to show this component, so dimension (w,h) and position (x,y) are considered. There's an "auto-resize" version that can be used once, after all components are added.
public static void updatePreferredSize(Container cont, Component comp) {
int w = cont.getPreferredSize().width;
int h = cont.getPreferredSize().height;
int W = comp.getBounds().x + comp.getBounds().width;
int H = comp.getBounds().y + comp.getBounds().height;
if (W>w||H>h) cont.setPreferredSize(new Dimension(W>w?W:w, H>h?H:h));
}
public static void autoPreferredSize(Container cont) {
for (Component comp : cont.getComponents())
updatePreferredSize(cont, comp);
}
You can use updatePreferredSize() after adding every component to a panel, or use autoPreferredSize() once, after all addings.
// [...]
panelN.add(button);
updatePreferredSize(panelN, button);
// [...]
// or...
// [...]
autoPreferredSize(panelN);
// [...]
frame.setVisible(true);
This way, if you do not set you north panel height with a fixed value, with help of these functions you can expect your button will be visible according the position you set it with setBounds().

Resizing LayeredPane Swing

I have a JPanel that uses BorderLayout and contains a jTable and a layeredPane. I need to use the layeredPane because it contains a jComboBox on top of a jTextPane. The problem is that when the user resizes the screen, the layeredPane doesn't resize. How can i fix this? I have something like this:
JPanel panel = new JPanel(new Borderlayout());
MyTable table = new MyTable();
panel.add(table, BorderLayout.CENTER);
JLayeredPane layeredPane = new JLayeredPane();
//addind things in the layered pane
panel.add(layeredPane, BorderLayout.PAGE_END);
Using a layout manager for the layered pane won't work, because i need components to be overlapped.
In the example you have posted JLayeredPane takes the SOUTH (BorderLayout.PAGE_END) place in the panel with BorderLayout. That means that the component in CENTER will take all additional space offered to the panel. And you have your table in CENTER.
Just place JLayeredPane in the CENTER and table in the NORTH to let the pane take all additional space.
More on BorderLayout:
http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html
You also might want to read more on Swing layouts:
http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html
common issue about JLayeredPane is that its childs would be placed by setBounds, because doesn't supports Standards LayoutManagers excluding Null Layout
have to add ComponentListener on event componentResized to change JPanels Bounds
for JComponents placed to the JPanel to use Standard LayoutManager
more than an alternative is to use the proper JLayer for Java7 based on custom JXLayer for Java6

Scrollable flow panel

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.

Categories