Grow table larger than growx - java

I have configured my layout like that:
panel.add(addButtons(), "wrap");
panel.add(showTable(), "growx, wrap");
So at first I am adding a button group and then I would like to grow my table as large as it can and then wrap the next component in the next "line".
However, my gui looks like that:
Here you clearly cannot see any values from the table. Therefore, how to grow the table so that each value can be seen?
I appreciate your answer!

Here you clearly cannot see any values from the table. Therefore, how to grow the table so that each value can be seen?
As I've said in my comment, I don't think your problem is about columns (preferred | min | max) sizes but the default behavior of your layout manager: MigLayout. As stated in this answer by default rows in MigLayout doesn't fill all available width but just the necessary to display the longest row (based on components width). You can see this fact if you enable "debug" feature when you instantiate your layout:
MigLayout layout = new MigLayout("debug");
As I understand your question you need a combination of both growx and fillx constraint. The first one is a component constraint and the other one is a layout constraint.
That being said, pelase consider the following progression.
1. Adding scroll pane without "growx" constraint
Snippet
MigLayout layout = new MigLayout("debug");
JPanel panel = new JPanel(layout);
panel.add(buttonsPanel, "wrap");
panel.add(scrollPane);
Screenshot
2. Adding scroll pane with "growx" constraint
Snippet
MigLayout layout = new MigLayout("debug");
JPanel panel = new JPanel(layout);
panel.add(buttonsPanel, "wrap");
panel.add(scrollPane, "growx"); // Note "growx" here
Screenshot
3. Adding scroll pane with "growx" and "fillx" contraints
Snippet
MigLayout layout = new MigLayout("debug, fillx"); // Note "fillx" here
JPanel panel = new JPanel(layout);
panel.add(buttonsPanel, "wrap");
panel.add(scrollPane, "growx"); // Note "growx" here
Screenshot

You can use javax.swing.table.TableColumn;
TableColumn custom_column = yourTable.getColumnModel().getColumn(1); // 1 means column 1
custom_column.setPreferredWidth(500);
As you want to widen all columns you can use loop :
TableColumn custom_column ;
int numberOfColumns = yourTable.getColumnModel().getColumnCount();
for(int y= 0;y<numberOfColumns;y++){
custom_column=table.getColumnModel().getColumn(y);
custom_column.setMinWidth(500);
}

Related

Swing: how to add two JScrollPanes with TableLayout?

For my Java program I am actually using the simple library TableLayout as layout for my main JPanel body so that I can add any widget just by specifying its row and column index, for example"
body.add(new JLabel(
"Search by date"),
"1,8");
Now I would need to add two JScrollPane (one horizontal and one vertical) but they should include all the body and not just a single cell of the layout. Shall I add another JPanel? How can I do it?
Now I would need to add two JScrollPane (one horizontal and one
vertical) but they should include all the body and not just a single
cell of the layout. Shall I add another JPanel?
IMO, yes you should. Nesting Layouts is a common approach that could be applied in this way:
Create a new JScrollPane and set your panel as its viewport view.
Give the scroll pane a reasonable preferred size to enable the scroll bars if your panel's size exceeds this preferred size.
Have a wrapper panel with BorderLayout and add the scroll pane to its CENTER location.
In a nutshell:
JScrollPane scrollPane = new JScrollPane(yourPanel);
scrollPane.setPreferredSize(new Dimension(400, 300));
JPanel wrapperPanel = new JPanel(new BorderLayout());
wrapperPanel.add(scrollPane);
See also:
How to Use Scroll Panes

Miglayout grid constraints custom layout

i'm new here so go easy on me.
I've researched all the documentation on miglayout (which is pretty good btw) but I can't seem to properly display the grid that I want.
I need MigLayout() parameters to setup a grid as:
2 rows, being that the bottom row is split in half (or if you will: 1 top row adjacent to 2 bottom columns).
The top row will display the search textfield with an adjancent button.
The bottom left column will display 3 buttons stacked on top of each other.
The bottom right column will display an image label.
Here's some code to start with:
//main window panel setup
JPanel mainPanel = new JPanel();
mainWindow.add(mainPanel);
mainPanel.setLayout(new MigLayout(""));
//components insertion into panel (using MigLayout constraints)
mainPanel.add(searchText);
mainPanel.add(searchBtn, "wrap");
mainPanel.add(addBtn);
mainPanel.add(logoImage, "spany 3 , wrap");
mainPanel.add(randomBtn, "wrap");
mainPanel.add(getFileBtn);
(could not upload image)
With this code, Notice that the logo is being kept below the searchButton (i think it does this due to the layout being default-set as a grid) but I want it to fit adjacent-right to the buttons and below the textfield/searchButton.
First off I would say you are pretty close and you only need to play with both columns number and constraints (plus some missing component constraints). This can be done when you instantiate your layout:
MigLayout layout = new MigLayout("debug, fillx", "[][grow][]");
Note debug and fillx are layout constraints intended to enable debug feature and fill whole width, respectively. See this answer for more details.
Now you can think you need two columns, but you actually need three columns in order to expand the middle one, while first and last columns continue occupying the minimum possible width. That's what [][grow][] constraints mean.
Please consider this snippet:
MigLayout layout = new MigLayout("debug, fillx", "[][grow][]");
JPanel content = new JPanel(layout);
// First row
content.add(new JTextField(20), "spanx 2, growx"); // search text field
content.add(new JButton("Search"), "wrap");
// Second row
content.add(new JButton("Button # 1"), "growx");
content.add(new JLabel("Image here"), "span 2 3, grow, wrap"); // image label
content.add(new JButton("Button # 2"), "growx, wrap");
content.add(new JButton("Button # 3"), "growx, wrap");
This will produce something like this:
Please note that on horizontal resizing both search text field and image label will occupy the maximum available width, while search button and button's stack will occupy just the minimum possible width.

JPanel above JLabel using Layered Panes

I have a JPanel that contains a bunch of small icons, and a JLabel containing a bigger icon.
First of all, I need clarification on something. By not setting panel.isOpaque, the said panel would have a transparent background and would properly overlap the icons of my JPanel and JLabel. Is this true?
Now to my problem. I've been following the LayeredPanes tutorial on the Oracle website, and I can't seem to make it right on my case.
JFrame window = new JFrame();
ImageIcon underIcon;
URL urlUnder = myClass.class.getResource("images/underImage.gif");
underIcon = new ImageIcon(urlUnder);
JLabel labelUnder = new JLabel(underIcon);
ImageIcon panelIcon;
URL urlAbove = myClass.class.getResource("images/aboveImage.gif");
panelIcon = new ImageIcon(urlAbove);
JLabel aboveIcon1 = new JLabel(panelIcon);
JLabel aboveIcon2 = new JLabel(panelIcon);
JPanel panelAbove = new JPanel(new BorderLayout());
panelAbove.setOpaque(false);
panelAbove.add(aboveIcon1, BorderLayout.WEST);
panelAbove.add(aboveIcon2, BorderLayout.EAST);
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setLayout(new BorderLayout());
layeredPane.add(labelUnder, BorderLayout.CENTER, 1);
layeredPane.add(panelAbove, BorderLayout.CENTER, 2);
layeredPane.setOpaque(true);
window.setContentPane(layeredPane);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.pack();
window.setVisible(true);
I only see the contents of the panel. And I'm 100% sure the images are there on getResource, so that's not the issue. Please advice on how to properly use Layered Panes.
The problem is you are setting a layout manager to the JLayeredPane
layeredPane.setLayout(new BorderLayout());
In of it self, this is not a problem, but your choice of layout manager is.
BorderLayout will only a single componet to occupy any of it's 5 predefined positions. This means when you add your second component, it, effectively, replaces the first.
Try using someone like GridBagLayout instead. Providing a single GridBagConstaint set so that the weightx/y values ara equal to 1, the fill property is set to BOTH and it's gridx/y properties are set to 0
Unlike BorderLayout, GridBagLayout will allow you to layout components to the same position
From the Java Tutorial:
layeredPane.add(dukeLabel, new Integer(2), 0);
This code uses the three-argument version of the add method. The third argument specifies the Duke label position within its depth, which determines the component's relationship with other components at the same depth.
Positions are specified with an int between -1 and (n - 1), where n is the number of components at the depth. Unlike layer numbers, the smaller the position number, the higher the component within its depth. Using -1 is the same as using n - 1; it indicates the bottom-most position. Using 0 specifies that the component should be in the top-most position within its depth. As the following figure shows, with the exception of -1, a lower position number indicates a higher position within a depth.
So your depth orders are the wrong way around, also start from 0.
I also found this in the Solving Common Component Problems Section
Problem: The components in my layered pane are not layered correctly. In fact, the layers seem to be inversed — the lower the depth the higher the component.
This can happen if you use an int instead of an Integer when adding components to a layered pane. To see what happens, in the LayeredPaneDemo class, change
layeredPane.add(label, new Integer(i));
to
layeredPane.add(label, i);.

MigLayout: unexpected layout beside a vertical spanning component

While playing a bit to demonstrate how to easily fulfil a layout requirment with MigLayout, I was surprised by the outcome of:
MigLayout layout = new MigLayout("wrap 3, debug");
JComponent content = new JPanel(layout);
content.add(new JLabel("First:"));
content.add(new JScrollPane(new JTextArea(10, 20)), "skip, spany");
content.add(new JLabel("Second"));
content.add(new JTextField(10));
content.add(new JLabel("third"));
content.add(new JTextField(10));
//content.add(new JLabel());
The layout idea is simple enough:
three columns
last column spanning all rows
first two columns a bunch of label/component pairs
The unexpected is that the last row of the first two columns takes all the available vertical space which leads to positioning the last pair in its middle (top align is not an option, as they must be baseline aligned to each other)
uncommenting the last line above (adding a virtually invisible dummy) shows the expected layout, but a hack which shouldn't go into production code
The question is: how to achieve the expected layout without hacking?
might be a bug:
a less hacky way to workaround (applicable if number of rows is known at creation time of the form) is to explicitly define the row constraints
MigLayout layout = new MigLayout("wrap 3, debug", "", "[][][][]");
that is define one row more than actually needed for the components at the side of the spanning component

Need help understanding some row constraints behaviour

In a Java project I am working on, my constraints were originally set to:
JPanel panel = new JPanel();
String layoutConstraints = "fill";
String columnConstraints = "[right]rel[grow]";
String rowConstraints = "[]10[]";
panel.setLayout(new MigLayout(layoutConstraints, columnConstraints, rowConstraints));
From what I understand of the documentation the last gap and constraint will be repeated for every row in excess of the specification. (cf. "If there are fewer rows in the format string than there are in the grid cells in that dimension the last gap and row constraint will be used for the extra rows.")
So for all I understand, this should mean the row constraints would in fact be []10[]10[]10[] and so on.
My problem comes when I have a JTextArea in a JScrollPane with rows set to 3:
JLabel label = new JLabel("Text area");
JTextArea text = new JTextArea("Test", 3, 40);
JScrollPane scroll = new JScrollPane(text);
panel.add(label);
panel.add(scroll, "grow,wrap");
When used with a row constraint of []10[] is only 1 row high, yet when I change
String rowConstraints = "[]10[]";
to
String rowConstraints = "[]";
it suddenly uses the full 3 rows height that I specified for the JTextArea.
Have I misunderstood how the row constraints work or is there something else at work here that I totally failed to see/understand?
In both cases you are using only one layout row (i.e. row managed by MigLayout) to which you put JLabel (first column) and JScrollPanel (containing JTextArea, second column).
You can easily visualize your MigLayout rows and columns structure by simply adding "debug" to layout constraints:
String layoutConstraints = "fill,debug";
And launching application. I really recommend using this setting while working on your layouts.
Rows property that you set for JTextArea have nothing to do with layout rows. This property only tells JTextArea component what size it will try to have, as defined in javadocs:
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 (...)
But JTextArea rows doesn't correspond by any means to rows in container's (JPanel in your case) layout.
Please, learn more carefully (and experiment!) what exactly JTextArea row property means.

Categories

Resources