Reputation: 396
Hello StackOverflow users!
I have a problem and I did find a solution to the problem, but I feel that the solution is not optimal. I feel like I used brute force to achieve what I wanted to do and am wondering if there might be a better way to achieve what I want.
Essentially what I have is a Java GUI application using the GridBagLayout. I use the GridBagLayout because the layout is essentially always center-aligned. When something else is added in, it shifts everything up, down, left, or right (depending on where the new object is added in). The issue, is that my program also needs to remove certain objects (depending on what happens in other blocks of code). So lets say I have four objects lined up like this [1] [2] [3] [4]
and I want to remove [3]
. I essentially want the layout to change to [1] [2] [3]
, essentially shifting everything over after the [3]
. There was no problem doing this visually (because of how GridBagLayout works). However, when something new was to be added to the display, there would be overlap because though [4]
took the visual position of [3]
, the GridBagPosition (not sure what else to call it) did not change. So I implemented the code below for the removal process.
public void removeSubImagePanel (int subPanelIdx) {
int x, y, nextX, nextY;
this.remove(this.portraits[subPanelIdx]);
nextX = this.portraits[subPanelIdx].getGbx();
nextY = this.portraits[subPanelIdx].getGby();
for (int i = subPanelIdx; i < this.numberOfPortraits; i++) {
x = nextX;
y = nextY;
this.portraits[i] = this.portraits[i+1];
if (this.portraits[i+1] != null) {
nextX = this.portraits[i+1].getGbx();
nextY = this.portraits[i+1].getGby();
this.portraits[i].getObject().setSubPanelIdx(i);
gbc.gridx = x;
gbc.gridy = y;
this.portraits[i].setGbLocation(x, y);
gb.setConstraints(this.portraits[i], gbc);
}
}
this.portraits[this.numberOfPortraits] = null;
this.numberOfPortraits--;
}
Essentially, I added two integer variables to the "portraits" object to hold the position of the X and Y on the GridBagLayout. That way, I could get the position [3]
, get the position of [4]
set [4]
s position to where [3]
's was and then (if there was a [5]
, set [5]
's position to [4]
's old position and so on until I arrived at the last element.
It feels too "brute force", having to add those integers, and I feel like it would be even worse if I were to make an individual GridBagConstraint for each object. Is there a better way to do this shifting that I need to do?
Sorry, this question is quite long. I didn't think it would be so long. I hope this is still okay. If I was unclear and you need any clarification, please don't hesitate to ask!
Edit: Would it be better if this were on the CodeReview stackexchange? It actually seems to make more sense to have it there. I'm not quite sure though.
Upvotes: 2
Views: 182
Reputation: 833
I'm not sure what your requirements are for this project, but I would check out the Spring Layout - this layout lets you specify things like:
the left of [1] should be 10 pixels from the left of the panel
the right of [1] should be 10 pixels from the left of [2]
etc.
It is much easier (imo) to implement a nice fluid layout like you are describing here.
Edit: Just to try and add to the discussion:
maybe you could have a class called PortraitPanel that extends from Panel and in there you could maintain a List of your image panels. You could have public methods: add(int index); remove(int index);
So that when you call add(2) it will add that panel to the list at that index - and then take the panel at index - 1 and index + 1 and do the routine to adjust the constraints on these so it lays them out on either side of the newly added panel. Similarly, for remove you could take index - 1 and set it's constraints to lay out next to index + 1 and then remove the item at index. Again, if you use a SpringLayout it will be really easy to set it up so that things remain fluid when the window resizes, etc.
Hopefully this is in line with what you are trying to do.
Upvotes: 2