I have the following piece of code that I wrote in Vaadin.
The problem is that the alignment does not work. I set it to bottom_center, but the components are all stuck to the top (top_center) of my web browser.
Can anyone help me out with this?
Thanks!
VerticalLayout layout = new VerticalLayout();
VerticalLayout layout1 = new VerticalLayout();
Panel panel = new Panel();
panel.setWidth("500px");
panel.setHeight("300px");
Button button = new Button("Enter");
Button login = new Button("Login");
layout1.addComponent(textfield);
layout1.addComponent(button);
layout1.addComponent(login);
layout.addComponent(panel);
layout.setComponentAlignment(panel, Alignment.BOTTOM_CENTER);
layout1.setComponentAlignment(textfield, Alignment.BOTTOM_CENTER);
layout1.setComponentAlignment(login, Alignment.BOTTOM_CENTER);
layout1.setComponentAlignment(button, Alignment.BOTTOM_CENTER);
The reason for the components appering to be aligned to the top is that you haven't specified a height for your VerticalLayouts. When you don't specify a size for a layout, its size is determined by the child components it contains. In such a case, setting the alignment won't make any difference, as there's no extra room inside the layout's slots.
Set the size, using e.g. layout.setHeight("100%"); or layout.setSizeFull(); and you should notice the difference immediately.
You did not specify a height for the layout so it'll expand from the top towards the bottom as it needs with each component you add. If you set layout.setHeight("100%"); the components will be aligned at the bottom.
you mus set setSizeUndefined() to your panel, textfield, login, button component
and setSizeFull layout1.
Related
Is there a way to create a Label with some type of invisible contents, to preserve it's "space" in a layout such as a HBox or VBox so as to prevent Layout Manager engaging in some type of resizing, so that if I have to set the contents of a certain Label to empty, the Layout Manager will not resize the container?
Thanks!
All layouts will lay out an invisible node as if it is visible. You can use an invisible Label as a “strut” by making it invisible and placing it, along with your visible node, in a StackPane:
Label valueLabel = new Label("This may become empty");
Label strut = new Label(valueLabel.getText());
strut.setVisible(false);
StackPane labelPane = new StackPane(strut, valueLabel);
hBox.getChildren().add(labelPane);
Another option is to simply make your value Label invisible instead of making its text empty, but I realize there are circumstances where that may not be possible, such as if the Label’s text property is bound.
As with all Regions you can set the minWidth property:
label.setMinWidth(100);
Which will result in the label not being resized below size 100 regardless of it's text.
In my code I have a JFrame that opens up a main menu, in that menu you can click options, which will take you to the options menu. On that options menu I want to create a back button that will position itself somewhere in the top left corner of the screen. When I run the program and go to the options menu the JButton does not appear. Something must be wrong with my code. Any help? Below is where I first declare the JButton.
static JButton optionsBackButton = new JButton("<html><font size = 5
color = green>Back</font></html>");
Here is the other part of the code that has to do with the JButton.
//Options Menu
JPanel optionsPanel = new JPanel();
JLabel optionsOptionsTitle = new JLabel("<html><font size = 7 color = blue>Options</font></html>");
JPanel optionsOptionsTitlePanel = new JPanel();
JPanel optionsBackButtonPanel = new JPanel();
optionsPanel.setLayout(null);
optionsBackButton.setBounds(100,100,50,50);
optionsBackButtonPanel.add(optionsBackButton);
optionsOptionsTitlePanel.add(optionsOptionsTitle);
optionsPanel.add(optionsOptionsTitlePanel);
optionsPanel.add(optionsBackButtonPanel);
optionsBackButton.addActionListener(this);
//Add panels to the card
panel.add("Home Screen", homePanel);
panel.add("Options Menu", optionsPanel);
//card.add("Game screen", gamePanel);
cardLayout.show(panel, "HomeScreen");
contentPane.add(panel);
Your problem is stemming from your use of null layouts. Note:
JPanel optionsBackButtonPanel = new JPanel(); // holds the back button
// but never given a size
optionsPanel.setLayout(null); // uh oh,.... bad news
optionsBackButton.setBounds(100,100,50,50); // yes you set the bounds of the button
optionsBackButtonPanel.add(optionsBackButton);
optionsOptionsTitlePanel.add(optionsOptionsTitle);
optionsPanel.add(optionsOptionsTitlePanel);
optionsPanel.add(optionsBackButtonPanel); // again, optionsBackButtonPanel
// has been never given a size or location/bounds
optionsBackButton.addActionListener(this);
So you set the bounds of the button and add it to a JPanel that uses the default FlowLayout, and so the bounds are meaningless. Then you add that JPanel, whose bounds you never set, to a JPanel that uses null layout. So the optionsBackButtonPanel will never show.
Solution: Don't use null layouts, but instead learn and use the layout managers.
While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
Start here: Laying Out Components in a Container Tutorial
This piece of code that I wrote creates 2 panels. The aim is to have one of them directly on top of the other with no space in between, but the problem is that there is a huge gap between them.
Cann anyone help me out with this?
Code:
Panel panel = new Panel();
Panel Logo = new Panel();
VerticalLayout layout1 = new VerticalLayout();
VerticalLayout layout2 = new VerticalLayout();
panel.setWidth("500px");
panel.setHeight("300px");
Logo.setWidth("500px");
Logo.setHeight("100px");
Logo.addStyleName(Runo.PANEL_LIGHT);
Label label = new Label("test");
label.setWidth(null);
Button test = new Button("test");
first.setStyleName("test");;
first.setClickShortcut(KeyCode.ENTER, null);
layout1.addComponent(test);
layout2.addComponent(label);
layout.addComponent(Logo);
layout.addComponent(panel);
layout.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
layout1.setComponentAlignment(test, Alignment.MIDDLE_CENTER);
layout2.setComponentAlignment(label, Alignment.MIDDLE_CENTER);
layout.setSizeFull();
layout1.setSizeFull();
layout2.setSizeFull();
setContent(layout);
panel.setContent(layout1);
Logo.setContent(layout2);
It depends on the type of layout, which you have set to full size. Your layout will expand as much as the browser itself. What happens is that if your layout is a VerticalLayout, its height is 100% but it only has two panels with heights of 300 and 100, respectively. Since you did not specify any expand ratio, Vaadin assigns 50% of the screen to the panel and the other 50% to the Logo, hence you get a big gap in between.
To fix it, you can do two things:
Don't use layout.setSizeFull(); Instead, use layout.setSizeUndefined();
Play with expand ratio, so that the top panel gets less space and Logo gets more space: layout.setExpandRatio(panel, 0.2f); and layout.setExpandRatio(Logo, 0.8f);. The problem with this approach is that in case your browser height is less than 400 pixels, your layout will be cut off.
It took me a while and many trial/errors to learn this concept. Make sure you carefully read this page before going forward.
There are two ways to do this :
as #Abbas said use
layout.setExpandRatio(panel, float);
or you can add a property in the css file:
layout.setStyleName("my-layout");
in css you add :
.v-verticallayout-my-layout .v-slot{
height: auto !important;
}
This will do the job. I've tried both methods and they worked.
I know that when I create an instance of tabbed panes I set the position as such:
jtp = new JTabbedPane(SwingConstants.LEFT)
My question is that is it possible to set the position to the left as above, but to shift the starting position a little bit downwards? I do not want the first tab appearing at the very top of the left hand side. I want to leave some empty space. Is that possible? Thanks.
You can pack your component into javax.swing.Box add shift it:
jtp.add("Component shifted vertically", shiftVertical(your_component, 5)); // 5 px or more
public static Box shiftVertical(JComponent component, int size){
Box vBox = Box.createVerticalBox();
vBox.add(Box.createVerticalStrut(size));
vBox.add(component);
return vBox;
}
I managed to find a work around for this problem. I did this by creating a "dummy" icon which was basically a square with the same colour as the background colour of the tabbed panes. I then set this icon as the icon for a "dummy" tabbed pane and disabled the tab:
jtp.addTab("", dummyIcon, null);
jtp.setEnabledAt(0, false);
By resizing the icon I could make the first tabbed pane take up as much space as i wanted since the panes don't have to be the same size. This way The first tab was not clickable and it had a colour similar to the background colour of the panel, so it appeared as if the space was empty.
I have created a GUI in Java which looks as shown below -
'panel_mid' is the white panel in the middle. I have added it to a scrollpane called 'panel_mid_scrollpane'.
Apart from 'panel_mid' there are more panels -
panel_left (containing 'back' button)
panel_right (visible on right hand side)
Revelant code for this gui is -
panel_mid.setBorder(grayborder);
panel_mid.setBounds(0, 0, 1100, 1060);
panel_mid.setBackground(Color.white);
panel_mid.add(obj.create_test_add_section);
panel_mid_scrollpane = new JScrollPane(panel_mid);
panel_mid_scrollpane.setLocation(150, 20);
panel_mid_scrollpane.setSize(1000, 660);
panel_mid_scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
The Add Section button shown in panel_mid, adds a section to the middle panel, every time it is clicked. When this button is clicked multiple times, the gui looks like -
As you could see, the scrollbar does not appear automatically as panels are added, the last panel is thus only half visible. What could be causing this problem ?
Thanks !
Scrollbars appear automatically when the preferred size of the component added to the scrollpane is greater than the size of the scroll pane.
You appear to be using a null layout.
//panel_mid.setBounds(0, 0, 1100, 1060);
panel_mid.setBackground(Color.white);
panel_mid.add(obj.create_test_add_section);
panel_mid_scrollpane = new JScrollPane(panel_mid);
//panel_mid_scrollpane.setLocation(150, 20);
//panel_mid_scrollpane.setSize(1000, 660);
Don't use a null layout with setSize() and setLocation. Swing was designed to be used with layout managers. If you use layout managers then the scrollbar will work automatically and the size and location will be calculated automatically for you.
Read the Swing tutorial on Layout Mangers.
You must tell the GUI to refresh, so that the containers are laid out again. This will show the container that it also has to show a scrollbar.
So in the ActionListener or whatever you use to add a section, add code like:
container_with_sections.validate();
container_with_sections.repaint();
where container_with_sections is the container (JContainer) which contains the JScrollPane, or a container which contains a container which contains the JScrollPane, and so on.