patternjavaMinor
Vertical JButton allignment
Viewed 0 times
allignmentjbuttonvertical
Problem
I have created a simple component in Swing that lets me place other components such as buttons on top of each other.
They fill their parent horizontally but not vertically, which is exactly as I want it. I called this parent component
I can't shake the feeling though that there could be a more elegant solution. Especially the need for my
Here's the
This creates the example from the screenshot above:
```
public class VerticalButtons {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (ClassNotFoundE
They fill their parent horizontally but not vertically, which is exactly as I want it. I called this parent component
VerticalPanel and this is how it looks:I can't shake the feeling though that there could be a more elegant solution. Especially the need for my
VerticalPanel to know the number of components it will hold in advance is something I'm not entirely happy with.Here's the
VerticalPanel:public class VerticalPanel extends JPanel {
private static final long serialVersionUID = 1L;
public VerticalPanel(int nrOfComps) {
LayoutManager layout = getVerticalLayout(nrOfComps);
setLayout(layout);
}
@Override
public Component add(Component comp) {
return add(comp, getComponentCount());
}
@Override
public Component add(Component comp, int index) {
final GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
// Allocate extra width to the buttons
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.NORTH;
gbc.gridx = 0;
gbc.gridy = index;
add(comp, gbc);
return comp;
}
private LayoutManager getVerticalLayout(int nrOfComps) {
GridBagLayout layout = new GridBagLayout();
double[] rowWeights = new double[nrOfComps];
rowWeights[nrOfComps - 1] = Double.MIN_VALUE;
layout.rowWeights = rowWeights;
return layout;
}
}This creates the example from the screenshot above:
```
public class VerticalButtons {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (ClassNotFoundE
Solution
as I mentioned in my comment I was playing with a
LayoutManager. Based off of what you are hoping to achieve I would suggest going down this path as you are trying to control how the components are laid out which is what the LayoutManager does. Here is a version that works, but could stand to be cleaned up a bit more, and adapted a tad more to cover more scenario's (padding, margins, isVisible...etc)public class VerticalLayout implements LayoutManager {
private final Dimension minimumSize = new Dimension();
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public Dimension preferredLayoutSize(Container parent) {
Dimension dimension = new Dimension(getTotalPaddingWidth(parent), getTotalPaddingHeight(parent));
minimumSize.height = dimension.height;
for(Component c :parent.getComponents()){
if(!c.isVisible()){
continue;
}
Dimension preferredSize = c.getPreferredSize();
dimension.height += preferredSize.getHeight();
if(preferredSize.width > dimension.width){
dimension.width = preferredSize.width;
}
}
minimumSize.width = dimension.width;
return dimension;
}
private int getTotalPaddingWidth(Container container) {
Insets padding = container.getInsets();
return padding.left + padding.right;
}
private int getTotalPaddingHeight(Container container){
Insets padding = container.getInsets();
return padding.top + padding.bottom;
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return minimumSize;
}
@Override
public void layoutContainer(Container parent) {
Insets padding = parent.getInsets();
int y = padding.top;
for(Component c : parent.getComponents()){
if(c.isVisible()) {
c.setBounds(padding.left, y, parent.getWidth(), c.getPreferredSize().height);
y += c.getHeight();
}
}
}
}Code Snippets
public class VerticalLayout implements LayoutManager {
private final Dimension minimumSize = new Dimension();
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public Dimension preferredLayoutSize(Container parent) {
Dimension dimension = new Dimension(getTotalPaddingWidth(parent), getTotalPaddingHeight(parent));
minimumSize.height = dimension.height;
for(Component c :parent.getComponents()){
if(!c.isVisible()){
continue;
}
Dimension preferredSize = c.getPreferredSize();
dimension.height += preferredSize.getHeight();
if(preferredSize.width > dimension.width){
dimension.width = preferredSize.width;
}
}
minimumSize.width = dimension.width;
return dimension;
}
private int getTotalPaddingWidth(Container container) {
Insets padding = container.getInsets();
return padding.left + padding.right;
}
private int getTotalPaddingHeight(Container container){
Insets padding = container.getInsets();
return padding.top + padding.bottom;
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return minimumSize;
}
@Override
public void layoutContainer(Container parent) {
Insets padding = parent.getInsets();
int y = padding.top;
for(Component c : parent.getComponents()){
if(c.isVisible()) {
c.setBounds(padding.left, y, parent.getWidth(), c.getPreferredSize().height);
y += c.getHeight();
}
}
}
}Context
StackExchange Code Review Q#106043, answer score: 2
Revisions (0)
No revisions yet.