Create FormLayout rows and columns dynamically (at runtime) - java

Hello guys and ladies,
as I let the Eclipse WindowBuilder create me a JPanel with a FormLayout, I wanted to make this creation to be dynamical, because the program I'm writing needs it that way in order to avoid 1000 row long from. I used the following code:
JPanel pData = new JPanel();
pData.setBounds(10, 232, 381, 163);
FormLayout fLayout= new FormLayout(new ColumnSpec[]{}, new RowSpec[]{});
int numCols = 5;
int numRows = 10;
for(int i=1;i<=numCols;i+=2)
{
fLayout.insertColumn(i, FormFactory.RELATED_GAP_COLSPEC);
fLayout.insertColumn(i+1, FormFactory.DEFAULT_COLSPEC);
}
for(int j=1;j<=numRows;j+=2)
{
fLayout.insertRow(j, FormFactory.RELATED_GAP_ROWSPEC);
fLayout.insertRow(j+1, FormFactory.DEFAULT_ROWSPEC);
}
pData.setLayout(fLayout);
getContentPane().add(pData);
But starting the program, I get a stack of errors starting with:
"The column index 1 must be in the range [1, 0]"
Changing the index in the for-loop(s) simply changes the number in the middle of this error text, but the rest stays the same.
What am I doing wrong? Is it even possible to create a FormLayout dynamically? I'd really appreciate your help!
Additional Information:
The reason I'm using a FormLayout is the fact, the columns have different sizes. I know GridBagLayout can do so as well, but it needs many more lines and numbers to have the same result concerning insets and position. But if it's the only sensible alternative, I'll accept it ... as long as it's dynamical ;-)

It has to do with how the "insertRow()/insertColumn()" work. To insert something you must already have row/columns to insert in between. You should instead use the ".appendRow()/.appendColumn()" which just add a new row or column at the bottom of any existing rows or to the right of any existing columns.
EX:
int numCols = 2;
int numRows = 10;
for(int i=1;i<=numCols;i++)
{
fLayout.appendColumn(FormFactory.RELATED_GAP_COLSPEC);
fLayout.appendColumn(FormFactory.DEFAULT_COLSPEC );
}
for(int j=1;j<=numRows;j++)
{
fLayout.appendRow(FormFactory.RELATED_GAP_ROWSPEC);
fLayout.appendRow(FormFactory.DEFAULT_ROWSPEC);;
}
this.setLayout(fLayout);
This would add 4 columns(2 default and 2 related gaps) and 4 rows(2 default and 2 related gaps) to whatever already exists.

Related

Position a Table Row in the Center of my Window using SWT

I have a large table created with Java SWT which I can sort columnwise in various ways. But whenever I sort a column, the table starts displaying the 1st row and I could not find a way to move the table to display a specific row, e.g. the last selected row.
Any idea is appreciated!
Gerald
You can use `Table.setTopIndex" to set the row shown at the top of the table window. So to centre a row you might use something like:
static void showCentredRow(Table table, int rowToShow)
{
Rectangle clientArea = table.getClientArea();
int itemHeight = table.getItemHeight();
int visibleRows = clientArea.height / itemHeight;
int topRow = Math.max(rowToShow - (visibleRows / 2), 0);
table.setTopIndex(topRow);
}

Overflowing layout with TableLayout

I need to show three things in a row in a sort of table. The first column should have a fixed width of say 15% of the screen. The third one should be right aligned and take its preferred width. The second one should take all the remaining space (I'll need to add some spacing, but that's another story).
This happens in start:
final Container list = new Container(BoxLayout.y());
list.setScrollableY(true);
final String[][] lines = {
{"19", "Some text", "123,00"},
{"20", "Some very very very very looong text", "1,00"},
};
for(final String[] line : lines) list.add(createContainer(line));
form.add(list);
The container is rather trivial:
private Container createContainer(String[] line) {
final TableLayout tableLayout = new TableLayout(1, 3);
tableLayout.setGrowHorizontally(true);
final Container result = new Container(tableLayout);
{
final Label l = new Label(line[0]);
l.getAllStyles().setFgColor(0x0000FF);
result.add(tableLayout.createConstraint().widthPercentage(15), l);
}
{
final Label l = new Label(emptyToSpace(line[1]));
l.getAllStyles().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
result.add(tableLayout.createConstraint().widthPercentage(-2), l);
}
{
final Label l = new Label(line[2]);
l.getAllStyles().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE));
l.getAllStyles().setFgColor(0x00FF00);
result.add(tableLayout.createConstraint().widthPercentage(-1).horizontalAlign(Component.RIGHT), l);
}
return result;
}
According to the javadoc, -1 means preferred size and -2 means "remaining space". It sort of works, but there seem to be a miscalculation.
The problem happens in the simulator, no matter what device I choose. I may be doing it all wrong, as I'm new to codenameone layouts.
The -2 flag is mostly optimized for the last column so this looks like a bug but might be hard to workaround. I don't see a need to use table layout here since you don't use one table which would provide alignment between the rows.
A simpler approach would be border layout e.g.:
Container c = BorderLayout.centerEastWest(new Label(emptyToSpace(line[1])),
rightText, leftText);
If you want the left column to align just use Component.setSameWidth() on the entire column.

gridbag layout GUI

I am having problems with the gridbag layout, I am trying to get the images to be on one line horizontally, however when I add images to the left of the original one, it will go down vertically instead of going horizontally to the left.
I have tried to specify the gridY to be the same, however this did not work, also I have tried the GridBayConstarints.Horizontal however that was irrelevant.
So far I have
import java.awt.GridBagConstraints;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class main {
public static void main(String[] args)
{
GUI g = new GUI();
int turnCounter = 1;
for(int i = 0; i<6; i++)
{
String image = "src/resources/bone"+0+i+".png";
GridBagConstraints c = new GridBagConstraints();
//ADDS IMAGE TO THE LEFT
if(turnCounter%2 == 0)
{
c.gridy = c.gridy;
c.gridx = c.gridx-1;
ImageIcon icon1 = new ImageIcon(image);
JLabel label1 = new JLabel((ImageIcon) icon1);
g.add(label1,c);
g.revalidate();
turnCounter++;
}
//ADD IMAGES TO THE RIGHT
else if(turnCounter%2 == 1)
{
c.gridy = c.gridy;
c.gridx = c.gridx+1;
ImageIcon icon1 = new ImageIcon(image);
JLabel label1 = new JLabel((ImageIcon) icon1);
g.add(label1,c);
g.revalidate();
turnCounter++;
}
}
}
}
What the image looks like at the moment.
The [2|0] and [3|0] should be to the left of [0|0] in that order so it will look like this
[4|0][2|0][0|0][1|0][3|0][5|0] all in one line.
The code you used for putting things to the right is correct, but as the default value of gridx is 0, what you are doing when you try to add a component to the left is giving a value to gridx of -1, an incorrect value for gridx, seems like the problem is there.
The solution I can give right now, is making an array with a lenght of how many images you want to display, in this case it would be a:
int yourLenght = 5; //Sounds dirty lol
JLabel[] yourArray;
yourArray = new JLabel[myLenght]
After this, only select the place of the array where you want to place it, I would recommend it in the middle.
Why does this work?
Now your images can only be on the 5th or 1st column (gridx = 0), but not on -1, altough we haven't finished yet, if you leave it like this, and you add or quit one to "yourLenght" your images could only be placed on the 2nd column or the 4th one, cause you can only add or quit one to 3. To avoid these what we are going to do is declare another int.
int magicInt = 1;
And then after each component is added we will add 1 to the "magicInt" value.
//You already added the object rather on the left or on the right
magicInt++;
And that way each time you add an object you can advance one place to the left or to the right more.
Notes:
1-Anchors won't work if you don't give a value to weighty. You can read more about these variables here.
2-I discourage using
c.gridy = c.gridy;
If you are only going to use that loop for adding things on one row, better use:
c.gridy = 0;
That way your code is easier to read.
3- Solution listed above only works if objects are added consitently with the following pattern : left, right, left, right... or right, left, right, left...
(It was a quick solution, but you will find your solution just think...)
Hope, this helped you, if you have any doubts don't mind commenting that way I can help :)

Fill a GridLayout in Java with Objects from a 2DArray?

I am learning Java and am trying to implement MineSweeper as a learning experience. I've got most of the logic working, but I am running into trouble with my recursive checkMine() method. I think the problem is my understanding, or misunderstanding rather, of how the GridLayout interacts with 2D arrays.
What I need to be able to do is to construct a 2D array full of Mines--which are an object extending JButton--and assign each element of the array to its own GridLayout location. Currently, I have the game working, but the numbers are not displaying the correct number of bombs, and I believe after debugging this could only be an issue with my implementation of the 2D Array with the GridLayout.
QUESTION: Is it possible to fill a GridLayout with individual elements of a 2D array? If not, what would be the best way for me to do this?
dAssuming your class extends java.applet.Applet
// Columns, Rows
Mines[][] mineGrid;
// Add stuff to the `mineGrid` array
// Set the height to the number of rows, length to number of columns
setLayout(new GridLayout(mineGrid.length, mineGrid[0].length);
// For each row
for(int rowIndex = 0; rowIndex < mineGrid.length; rowIndex++) {
// For each column
for(int colIndex = 0; colIndex < mineGrid[0].length; colIndex++) {
// Add the button, because of GridLayout it starts # the top row, goes across left to right, down a row, across left to right, etc.
add(mineGrid[rowIndex][colIndex];
}
}

GridLayout columns

I recently decided to start using GridLayout because FlowLayout seems somewhat amateur. However, I need help. The parameters when creating the GridLayout are (rows,columns,row space,column space). I have a variable for the row amount and 4 for the column amount, but when I try to add a JButton after everything else, there are 5 columns.
Here is my code:
byte i = 0;
while(i < main.componentNum)
{
comp[i] = new JLabel("component #" + (i+1));
box[i] = new JComboBox();
field[i] = new JTextField(5);
edit[i] = new JButton("edit");
comp[i].setBackground(Color.WHITE);
box[i].setBackground(Color.WHITE);
field[i].setBackground(Color.WHITE);
edit[i].setBackground(Color.WHITE);
add(comp[i]);
add(box[i]);
add(field[i]);
add(edit[i]);
i++;
}
When I run the above code, I get four columns and it works fine. But when I add a button to the end, I get five. Can anyone tell me how to give one button an entire row?
From the Java Docs
One, but not both, of rows and cols can be zero, which means that any
number of objects can be placed in a row or in a column.
Now, without your actual code the sets up the GridLayout, it's difficult to say, but, if your after maintaining only 4 columns, I would create a GridLayout as follows, new GridLayout(0, 4)
If you want something more flexible, look into GridBagLayout

Categories

Resources