How do i get vertical scrolling to JPanel? - java

I have written a code in java using swing, so that I will have a JscrollPane added to JPanel and then I will add buttons of fixed size to JPanel in vertical fashion
JPanel panel=new JPanel();
panel.setBackground(Color.WHITE);
int v=ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;
int h=ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS;
JScrollPane jsp=new JScrollPane(panel,v,h);
jsp.setPreferredSize(new Dimension(600,600));
jsp.setBounds(150,670,850,200);
frame.add(jsp);
then I am adding buttons to it at run time.
for(i=0;i<n;i++)
{
button[i]=new JButton();
button[i].setBounds(20,y,120,120);
button[i].setSize(120,120);
button[i].setToolTipText(file[i].toString());
button[i].setIcon(Icon);
panel.add(button[i]);
y=y+140;
}
I want to add a buttons one below the other...(i.e I want a vertical scrollbar)
i.e. button1
button2
'
'
but above code is giving me buttons in a line (i.e. I am getting horizontal scrollbar)
i.e. button1 button2...
another problem is the size of the buttons. Using btn.setSize() is not affecting size at all...
can anybody help me?

You must use an appropriate Layoutmanager like GridLayout, Boxlayout or GridBagLayout for the panel.
It depends what else you want to put into the panel.
GridLayout is easier to use IMO:
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0, 1)); // any number of rows, 1 column
...
panel.add(button[i]);
BoxLayout is almost as easy:
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
...
panel.add(button[i]);
GridBagLayout is more powerful, allowing more than one column, components spanning more than one cell, ... needs a GridBagConstraints to add the elements:
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints(
0, RELATIVE, // x = 0, y = below previous element
1, 1, // cell width = 1, cell height = 1
0.0, 0.0 // how to distribute space: weightx = 0.0, weighty = 0,0
GridBagConstraints.CENTER, // anchor
GridBagConstraints.BOTH, // fill
new Insets(0, 0, 0, 0), // cell insets
0, 0); // internal padding
...
panel.add(button[i], constraints);
Have a look at this tutorial: Laying Out Components Within a Container (The visual guide is a good start point)
EDIT:
you can also lay out the components by hand, that is, specify the location and size of each component in the container. For this you must set the LayoutManager to null so the default manager gets removed.
JPanel panel = new JPanel();
panel.setLayout(null);
...
button[i].setLocation(x, y);
button[i].setSize(width, heigth);
// OR button[i].setBounds(x, y, width, height);
panel.add(button[i]);

You need to define an appropriate LayoutManager for your JPanel, which is responsible for how the Components added to it are positioned. The default LayoutManager is FlowLayout, which lays out Components left-to-right. For laying out Components vertically you should consider using BoxLayout or GridBagLayout.

You have to set LayoutManager for JPanel or use Box(BoxLayout.Y_AXIS) instead.

For the size of buttons use preferredSize
For your layout problem you need to change the layout manager to one that does a vertical layout. For playing around purposes you can use BoxLayout like this:
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

This is much easier if you let the layout manager do its work.
In Swing, the way the components are layout over other component ( a panel for instance ) is using a layout manager.
It is used to avoid having to compute the coordinates of all the components against each other each time the container component resizes, or a new component is added.
There are different layout mangers, the one that you need here is BoxLayout.
By using this layout you don't need to specify the button position, nor its size. The layout manager query each component and use that information to place them in the correct position and size.
For instance the following frame
Was created this ( modified version of your ) code:
import javax.swing.*;
import java.awt.*;
public class ScrollTest {
private JPanel panel;
private Icon[] icons = new Icon[3];
public void main() {
panel =new JPanel();
// Use top to bottom layout in a column
panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ));
panel.setBackground(Color.WHITE);
int v=ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;
int h=ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS;
JScrollPane jsp=new JScrollPane(panel,v,h);
jsp.setPreferredSize(new Dimension(600,600));
jsp.setBounds(150,670,850,200);
JFrame frame = new JFrame();
frame.add(jsp);
// my addition to load sample icons
loadImages();
// simulate dynamic buttons
addButtons();
frame.pack();
frame.setVisible( true );
}
void loadImages() {
icons[0] = new ImageIcon( "a.png" );
icons[1] = new ImageIcon( "b.png" );
icons[2] = new ImageIcon( "c.png" );
}
void addButtons() {
for( int i = 0 ; i < icons.length ; i++ ) {
JButton button = new JButton();
Icon icon = icons[i];
button.setIcon( icon );
// Set the button size to be the same as the icon size
// The preferred size is used by the layout manager
// to know what the component "better" size is.
button.setPreferredSize( new Dimension( icon.getIconWidth(),
icon.getIconHeight() ) );
// This is IMPORTANT. The maximum size is used bythe layout manager
// to know "how big" could this component be.
button.setMaximumSize( button.getPreferredSize() );
panel.add( button );
}
}
public static void main( String ... args ) {
new ScrollTest().main();
}
}
I hope this helps.

One can also get a vertical scrolling for JPanel with SpringLayout. It's possible if panel's vertical size will be defined by setting a constraint SpringLayout.SOUTH. This can be done like this:
JPanel panel = new JPanel();
SpringLayout panelLayout = new SpringLayout();
panel.setLayout(panelLayout);
// Adding components to the panel here
// .....
// That's what defines panel's exact size and makes its scrolling possible
panelLayout.putConstraint(SpringLayout.SOUTH, panel, 0,
SpringLayout.SOUTH, lastComponentOfThePanel);
JScrollPane panelScrollPane = new JScrollPane(panel);
where lastComponentOfThePanel is a component at the bottom of a panel.
Hope this will help somebody. In my opinion, SpringLayout is very powerful layout manager, and sometimes it's very difficult or almost impossible to replace this one with GridBagLayout.

What about?
JScrollPane scrollPane = new JScrollPane(yourpanel);
container.add(scrollPane);

Related

Align to the limit Components in a JPanel Swing

I need to totally align components to the JTextArea components, I am currently using a BoxLayout and I already used the setAlignmentX and setHorizontalAlignment to LEFT but it's not working. Here I upload an image to make clearer what I mean. For example look at "+ Pla PLAMARC" it's clearly not aligned with the text area component.
By the moment this is the code:
//Declarations
private JLabel nomPla;
private JTextArea infoPla;
private JScrollPane textAreaScroll;
//Inside the constructor
nomPla = new JLabel();
infoPla = new JTextArea(2, 50);
textAreaScroll = new JScrollPane(infoPla);
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
nomPla.setAlignmentX(Component.LEFT_ALIGNMENT);
nomPla.setHorizontalAlignment(nomPla.LEFT);
textAreaScroll.setAlignmentX(Component.CENTER_ALIGNMENT);
this.setBorder(new EmptyBorder(new Insets(25, 25, 25, 25)));
this.add(nomPla, BorderLayout.NORTH);
this.add(textAreaScroll, BorderLayout.NORTH); //Orientacions
I am clearly telling nomPla to be on the leftside, but this is not the same as the JTextArea.
How is this done then?
I already used the setAlignmentX and
The setAlignmentX(...) needs to be applied to all the components you add to the BoxLayout if you want all to be left aligned with respect to the BoxLayout.
Edit:
I just want the labels to be on the left side, not the JTextArea components..
Then you need to use a wrapper panel for the BoxLayout Panel.
For example:
JPanel wrapper = new JPanel( new FlowLayout(FlowLayout.CENTER) );
wrapper.add(yourBoxLayoutPanel);
frame.add(wrapper);
Now all the components in the BoxLayout will be left aligned and the BoxLayout panel will be center aligned in the wrapper panel.
Layout management is about nesting panels with different layout manager to achieve you desired effect.

How to fill Cells of GridbagLayout with the controls in Swing?

I need to design a swing GUI which has a JFrame with a Menu on top and another main panel having three more panels in center and a separate panel in the bottom of the panel. The required design of the UI is as below
But when I run my swing application I get the output like this (all the panels are packed in the center of the window)
Below is my code
import java.awt.*;
import javax.swing.*;
public class FrontEndView {
private JFrame mainFrame;
private JPanel mainPanel,subPanelUp,subPanelDown,panelLeft,panelRight,panelCenter,panelDown;
private JScrollPane scrollPane;
private JList logViewList;
private JPanel panel1;
public FrontEndView(){
this.prepareGUI();
}
public void prepareGUI(){
mainFrame=new JFrame("GUI");
Toolkit tk = Toolkit.getDefaultToolkit();
int xSize = ((int) tk.getScreenSize().getWidth());
int ySize = ((int) tk.getScreenSize().getHeight());
mainFrame.setSize(xSize,ySize);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setResizable(true);
mainFrame.setLayout(new BorderLayout());
mainPanel=new JPanel();
mainPanel.setLayout(new GridBagLayout());
mainPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
GridBagConstraints gridbagConstMain = new GridBagConstraints();
GridBagConstraints gridbagConstSub = new GridBagConstraints();
subPanelUp=new JPanel();
subPanelUp.setLayout(new GridBagLayout());
subPanelUp.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
panelLeft=new JPanel();
panelLeft.setBorder(BorderFactory.createTitledBorder("Message Defs"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 0;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelLeft, gridbagConstSub);
panelCenter=new JPanel();
panelCenter.setBorder(BorderFactory.createTitledBorder("Main Workspace"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 1;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelCenter, gridbagConstSub);
panelRight=new JPanel();
panelRight.setBorder(BorderFactory.createTitledBorder("Script Viewer"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 2;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelRight, gridbagConstSub);
mainPanel.add(subPanelUp,gridbagConstMain);
subPanelDown=new JPanel();
subPanelDown.setLayout(new BorderLayout());
panelDown=new JPanel();
panelDown.setBorder(BorderFactory.createTitledBorder("Log View"));
logViewList= new JList();
panelDown.add(logViewList);
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
//gridbagConst.ipady=20;
//gridbagConst.weightx = 0.0;
gridbagConstSub.gridwidth = 5;
gridbagConstSub.gridx = 0;
gridbagConstSub.gridy = 0;
subPanelDown.add(panelDown,BorderLayout.PAGE_END);
mainPanel.add(subPanelDown, gridbagConstSub);
scrollPane=new JScrollPane(mainPanel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
mainFrame.add(scrollPane);
mainFrame.setVisible(true);
}
public static void main(String[] args){
FrontEndView frontEnd = new FrontEndView();
}
}
I want to fill the GridBagLayout's cells with the relevant panel/control it holds as shown in the design and also each panel should have its controls filled inside (I need to add a JList inside the panelDown whose size should be the size of the panelDown JPanel).Simply I don't need any extra space visible in my JFrame. Please guide me on what is missing in my code.
I would suggest you can use nested panels with different layout managers to solve the problem.
The default layout of a frame is a BorderLayout.
So you could create a panel and add it to the PAGE_END so it displays the entire width at the bottom.
Then you can create another panel that uses a GridLayout. You can then add 3 child panels to this panel and each panel can use its own layout. Then you add this panel to the CENTER of the frame. As the frame size changes the extra spaces will be allocated to the CENTER so the panels will dynamically grow.
Edit:
Too many panels for me to take the time to understand what is happening
I was suggesting a structure like this:
frame (which by default uses a BorderLayout)
--- CENTER
panel using GrigBagLayout
childPanel1
childPanel2
childPanel3
---- PAGE_END
JScrollPane containing the JList
When you create the JList the basic code would be:
JList list = new JList(...);
list.setVisibleRowCount(5);
JScrollPane scrollPane = new JScrollPane( list );
There is no need to create a panel just to add the list to another panel. The point of setting the visible row count is to give the JList a fixed height. Scrollbars will then appear in the scroll pane as needed.
Now that the PAGE_END has a fixed height component all the reset of the space will go to the component that you add to the CENTER of the frame.
all the panels are packed in the center of the window)
The panels are displayed at their preferred sizes when you use the GridBagLayout. If the total size of all the panels is less than the size of the scrollpane then they will be in the center. If you want the panels to fill the space available, then I believe you need to use the weightx/y constraints. Read the section from the Swing tutorial on How to Use GridBagLayout which describes all the constraints.
That is why I suggested a GridLayout instead. It will make all the panels the same size and will fill the viewport of the scroll pane without playing with constraints.
mainFrame.add(menubar,BorderLayout.NORTH);
That is not how you add a menubar to the frame.
You should be using:
mainFrame.setJMenuBar(menuBar);
You were told this in your last question. Why did you not listen to the advice??? Why should we take the time to help when you don't pay attention to what is suggested.
Based on your instructions I changed my design in a way all of the outer panels are used with Border Layout and the inner most ones with more controls were used with Grid, GridBag and FlowLayouts based on the requirement. In that way the entire design could be done nicely.
Also if a particular panel within a cell of a layout needs to be expanded, I used the setPreferredSize(new Dimension(int,int)) whenever required.

JLabel wont change Width

I'm programming right now a Chomp Game for Uni. Everything works fine but the Label at the bottom. Its background is supposed to fill out the entire bottom. In the attachment you can see how it instead looks now. I tried setting the minimum and the preferred size of the label. The Height is changing but the width just stays adjusted to the text. How can I change that?
Note: The snippet only contains the setting up of the Frame and Panels in a custom method and not the main class.
private void init()
{
JFrame fenster = new JFrame();
this.spielfeld = new SpielfeldPanel(M, N);
this.anzeige = new SpielerAnzeigeLabel(this.spieler);
JPanel panel = new JPanel();
BoxLayout boxlayout = new BoxLayout(panel,BoxLayout.Y_AXIS);
panel.setLayout(boxlayout);
fenster.setTitle("Chomp");
fenster.setSize(1000,700);
panel.setPreferredSize(new Dimension(1000, 60));
Dimension d = new Dimension(getPreferredSize());
panel.setMinimumSize(d);
panel.add(spielfeld);
panel.add(anzeige);
fenster.add(panel);
this.spielfeld.setVisible(true);
this.anzeige.setVisible(true);
panel.setVisible(true);
fenster.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
A BoxLayout respects the width of the component to the label is displayed at its preferred width/height.
A JFrame uses a BorderLayout by default. So just add the label to the frame independently of the panel:
//panel.add(anzeige);
//fenster.add(panel);
fenster.add(panel, BorderLayout.CENTER);
fenster.add(anzeige, BorderLayout.PAGE_END);
The PAGE_END constraint respects the height but makes the width equal to the space available. Read the section from the Swing tutorial on How to Use BorderLayout for more information and examples.

Scrolling issue (Java-JFrame-JScrollBar)

INTRO:
I created a java application using JFrame. I have a JMenuBar at the top and under that I'd like to display rows of text.
PURPOSE:
When I have 50 rows and only 20 are displayable at once, I'd like to be able to scroll down and back up again.
PROBLEM:
Of course, my theory doesn't wanna work as it should. My problem is that I don't know how to add a vertical scroll properly.
QUESTION:
How should I change this code to reach my goal?
public void display(){
Container content = this.window.getContentPane();
content.setLayout(new BorderLayout());
Border border = LineBorder.createGrayLineBorder();
//this is just a sample
for(int i = 0;i<50;i++){
JLabel lab = new JLabel("lonyaladek");
lab.setSize(570, 20);
lab.setBorder(border);
lab.setLocation(10, 20+(i*25));
content.add(lab);
}
//scroll
JScrollBar sb = new JScrollBar(JScrollBar.VERTICAL, 0, 0, 0, 0);
content.add(sb);
}
First you need to start with a layout manager that allows you to add multiple components to the container. Maybe a GridLayout is the best place to start.
Then you add this container to the scrollPane and then you add the scrollpane to the window.
So the basic code would be:
JPanel panel = new JPanel( new GridLayout(0, 1) );
panel.add(...);
panel.add(...);
JScrollPane scrollPane = new JScrollPane( panel );
window.add(scrollPane, BorderLayout.CENTER);
I suggest you read the section from the Swing tutorial on How to Use Scroll Panes for more info.

java scrollpane with flowlayout

For some reason, I cannot this working. It should be simple really.
I've having a JFrame with a BorderLayout, which contains a JPanel (SOUTH) and a (CENTER) JPanel (itemPanel).
itemPanel should be wrapped in a scrollpane. Its width = x, and all of its children shares its length, so it basically works like a table with only 1 column.
For some reason, I cannot get the scrollpane to show the scrollbars (and scroll). In the JFrame:
setPreferredSize(dimension);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add("South",controlPanel);
JScrollPane scroll = new JScrollPane(itemPanel);
scroll.setBorder(null);
getContentPane().add("Center",scroll);
super.pack();
setVisible(true);
Initilizing and adding some dummy-panels to the itemPanel:
itemPanel = new ItemPanel(); // A JPanel with a flowlayout
itemPanel.setPreferredSize(new Dimension(dimension.width,0));
for(int i = 0; i < 20; i++){
JPanel p = new JPanel();
p.setPreferredSize(new Dimension(0,50));
p.setBackground(i%2 == 0 ? Color.GREEN : Color.YELLOW);
itemPanel.add(p);
}
if omitting itemPanel.setPreferredSize(new Dimension(dimension.width,0)); the scrollpane shows the horizontal scrollbars, but since the flowlayout does not have a width to follow, it just shows the components in one row.
A FlowLayout does NOT recalculate the preferred size of a panel. The scrollbars only appear when the preferred size of the component is greater than the size of the scroll pane.
WrapLayout may be what you are looking for.

Categories

Resources