I have a ScrollPane in a SplitPane and the ScrollPane contains a Gridbag layout panel.
I like to add horizontal filling Buttons to it.
Setting weightx and filling does not help at all.
I already tried it by using the dividers property listener, but nothing works.
Thanks for your answers!
Should be no problem:
// ScrollPane in a SplitPane
var scrollPane = new JScrollPane();
var splitPane = new JSplitPane();
splitPane.setLeftComponent(scrollPane);
splitPane.setRightComponent(new JLabel("dummy"));
// ScrollPane contains a Gridbag layout panel
var gridBagLayout = new GridBagLayout();
var panel = new JPanel(gridBagLayout);
scrollPane.setViewportView(panel);
// add horizontal filling Buttons
var gbc = new GridBagConstraints(
0, RELATIVE, 1, 1, 1.0, 0.0,
CENTER, HORIZONTAL, new Insets(2, 2, 2, 2), 0, 0);
panel.add(new JButton("first"), gbc);
panel.add(new JButton("second"), gbc);
JOptionPane.showMessageDialog(null, splitPane);
Related
I'm pretty new to Java Swing. Can someone help me figure out what I am doing wrong? Please correct me anywhere necessary. A good portion of this code was trial and error.
I have a frame, which contains a JPanel. The JPanel is using the "GridBag" layout. The code included revolves around the child JPanel on the right side as seen in the picture. For some reason, I can't seem get my vertical scrollbar working properly.
Here's the code of interest:
/// GridBagConstraints
GridBagConstraints gbc = new GridBagConstraints();
// parent jpanel for scrollpane
scrollPanel = new JPanel();
scrollPanel.setLayout(new BorderLayout());
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
add(scrollPanel, gbc);
// content jpanel for scrollpane
scrollPaneContent = new JPanel();
scrollPaneContent.setLayout(new GridLayout(0, 1, 0, 1));
// scrollPane
scrollPane = new JScrollPane();
scrollPane.setBorder(BorderFactory.createEmptyBorder(0,30,0,0));
scrollPane.setViewportView(scrollPaneContent);
scrollPanel.add(scrollPane, BorderLayout.PAGE_START);
And here is what the program looks like at the moment.
You can see the numbers just go off the screen:
Any help is greatly appreciated! Thank you.
scrollPanel.add(scrollPane, BorderLayout.PAGE_START);
You are attempting to add the scrollPane to the scrollPanel. That is not the way it works.
A JScrollPane is a container, so you need to add the panel containing the components to the scroll pane
JPanel panel = new JPanel(...);
panel.add(....);
panel.add(....);
JScrollPane scrollPane = new JScrollPane( panel );
frame.add( scrollPane );
The above code will add the panel to the "viewport" of the scroll pane.
I am trying to make a game which looks something like this:
I'm trying to find the most suitable layout design for this. I tried using gridbag layout but there are some components which are not added correctly. This is my code:
//Gridbag for the whole frame
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
this.setLayout(gridbag);
constraints.fill = GridBagConstraints.BOTH;
constraints.insets = new Insets(10, 10, 10, 10);
constraints.weightx = 0.5;
//Top left panel
pnlHP = new JPanel();
pnlHP.setBackground(new Color (75, 55, 28));
gridbag.setConstraints(pnlHP, constraints);
this.add(pnlHP);
GridBagLayout gridbagHP = new GridBagLayout();
GridBagConstraints constraintsHP = new GridBagConstraints();
pnlHP.setLayout(gridbagHP);
constraintsHP.fill = GridBagConstraints.BOTH;
constraintsHP.insets = new Insets(10, 10, 10, 10);
constraintsHP.weightx = 1.0;
lblHPTitle = new JLabel();
lblHPTitle.setText("HP");
lblHPTitle.setForeground(Color.WHITE);
lblHPTitle.setFont(new Font("Arial", Font.PLAIN, 60));
gridbagHP.setConstraints(lblHPTitle, constraintsHP);
pnlHP.add(lblHPTitle);
lblHP = new JLabel();
lblHP.setText("asdf");
lblHP.setForeground(Color.WHITE);
lblHP.setFont(new Font("Arial", Font.PLAIN, 20));
lblHP.setHorizontalAlignment(SwingConstants.RIGHT);
constraintsHP.gridwidth = GridBagConstraints.REMAINDER;
gridbagHP.setConstraints(lblHP, constraintsHP);
pnlHP.add(lblHP);
pgbHP = new JProgressBar();
pgbHP.setBackground(new Color (75, 55, 28));
pgbHP.setValue(25);
constraintsHP.weightx = 0.0;
gridbagHP.setConstraints(pgbHP, constraintsHP);
pnlHP.add(pgbHP);
//Top center part
btnGo = new JButton();
btnGo.setBackground(new Color (126, 72, 28));
btnGo.setText("Start Adventure!");
btnGo.setForeground(Color.WHITE);
btnGo.setFont(new Font("Arial", Font.PLAIN, 42));
gridbag.setConstraints(btnGo, constraints);
this.add(btnGo);
//Top right panel
pnlMPSP = new JPanel();
pnlMPSP.setBackground(new Color (75, 55, 28));
constraints.gridwidth = GridBagConstraints.REMAINDER;
gridbag.setConstraints(pnlMPSP, constraints);
this.add(pnlMPSP);
GridBagLayout gridbagMPSP = new GridBagLayout();
GridBagConstraints constraintsMPSP = new GridBagConstraints();
pnlMPSP.setLayout(gridbagMPSP);
constraintsMPSP.fill = GridBagConstraints.BOTH;
constraintsMPSP.insets = new Insets(10, 10, 10, 10);
constraintsMPSP.weightx = 1.0;
lblMPSP = new JLabel();
lblMPSP.setText("asdf");
lblMPSP.setForeground(Color.WHITE);
lblMPSP.setFont(new Font("Arial", Font.PLAIN, 20));
gridbagMPSP.setConstraints(lblMPSP, constraintsMPSP);
pnlMPSP.add(lblMPSP);
lblMPSPTitle = new JLabel();
lblMPSPTitle.setText("MP");
lblMPSPTitle.setForeground(Color.WHITE);
lblMPSPTitle.setFont(new Font("Arial", Font.PLAIN, 60));
lblMPSPTitle.setHorizontalAlignment(SwingConstants.RIGHT);
constraintsMPSP.gridwidth = GridBagConstraints.REMAINDER;
gridbagMPSP.setConstraints(lblMPSPTitle, constraintsMPSP);
pnlMPSP.add(lblMPSPTitle);
pgbMPSP = new JProgressBar();
pgbMPSP.setBackground(new Color (0, 0, 255));
pgbMPSP.setValue(25);
constraintsMPSP.weightx = 0.0;
gridbagMPSP.setConstraints(pgbMPSP, constraintsMPSP);
pnlMPSP.add(pgbMPSP);
//Middle Left
lblNotifications = new JLabel();
lblNotifications.setText("<html>N<br>o<br>t<br>i<br>f<br>i<br>c<br>a<br>t<br>i<br>o<br>n<br>s</html>");
lblNotifications.setFont(new Font("Arial", Font.PLAIN, 20));
lblNotifications.setBackground(Color.WHITE);
gridbag.setConstraints(lblNotifications, constraints);
this.add(lblNotifications);
//Middle Center
txtNotifCenter = new JTextPane();
txtNotifCenter.setBackground(new Color (205, 160, 96));
txtNotifCenter.setEnabled(false);
txtNotifCenter.setDisabledTextColor(Color.black);
scpNotifCenter = new JScrollPane(txtNotifCenter);
scpNotifCenter.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
gridbag.setConstraints(scpNotifCenter, constraints);
this.add(scpNotifCenter);
//Middle Right
txtXPInfo = new JTextPane();
txtXPInfo.setBackground(new Color (205, 160, 96));
txtXPInfo.setEnabled(false);
txtXPInfo.setDisabledTextColor(Color.black);
scpXPInfo = new JScrollPane(txtXPInfo);
scpXPInfo.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
constraints.gridwidth = GridBagConstraints.REMAINDER;
gridbag.setConstraints(scpXPInfo, constraints);
this.add(scpXPInfo);
//I haven't made the bottom part yet
this.pack();
If this was run, the lblNotifications and txtNotifCenter (or scpNotifCenter) seemed to have the same width. I wanted to make it like in the picture. Am I supposed to use another layout, or am I just using the gridbag layout in the wrong way? Thank you in advance!
GridBagLayout is very difficult to use and only people that are a glutton for punishment try to use it. It was actually originally intended to be used by GUI builders rather than be coded by hand.
You should use nested layouts. You actually have a pretty standard layout. For your main window use BorderLayout (and this is the default layout of all top-level containers like JFrame).
Your HP, Start Adventure, and MP will be in a JPanel that uses a X_AXIS BoxLayout (JPanels use FlowLayout by default, so you will have to set it to BoxLayout). That JPanel will go in the NORTH position of the BorderLayout.
Your two notification text areas would probably go best in a JSplitPane (with one text area on the left side, the other text area on the right side), then put the split pane in the CENTER of the BorderLayout.
Then your CharMode, Level, and Logout will be in yet another JPanel using X_AXIS BoxLayout. That JPanel will go in the SOUTH position of your BorderLayout.
Tutorials for Border and Box Layouts:
https://docs.oracle.com/javase/tutorial/uiswing/layout/border.html
https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html
Split Panes:
https://docs.oracle.com/javase/tutorial/uiswing/components/splitpane.html
It is unsure which parts of your screen are components and which are not (for example is the hp display one component or a group of them?) but GridBagLayout can certainly do what you want.
The key is not to try and do it all with one GridBagLayout, since then everything needs to line up in a grid.
Instead split your screen into three rows. Use on layout to arrange the three rows (for example BoxLayout) and then use a separate layout manager inside each row (for example GridBagLayout) to lay out the components within that row.
I'm trying to make a text-based adventure game where the top of the screen is a JTextArea inside a JScrollPane that shows what is happening, and the bottom is a JOptionPane where you click on a button to make a choice. By default, the buttons are arranged horizontally. The only problem is that if I have too many buttons, there is no room for new ones and they are pushed off the screen. I need them to be arranged vertically since they are fatter than they are tall. The JOptionPane and the JScrollPane are nested in a gridLayout, which is nested in a JFrame. This is the method I am using to make the frame:
/**
* Make the frame and everything in it
*/
private void makeFrame()
{
frame = new JFrame("Adventure!");
JPanel contentPane = (JPanel)frame.getContentPane();
contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));
contentPane.setLayout(new GridLayout(0, 1));
textArea = new JTextArea(20, 50);
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setFont(new Font("font", Font.BOLD, 15));
JScrollPane scrollPane = new JScrollPane(textArea);
contentPane.add(textArea);
optionPane = new JOptionPane("", JOptionPane.DEFAULT_OPTION, JOptionPane.DEFAULT_OPTION, null, null);
contentPane.add(optionPane);
frame.pack();
// place the frame at the center of the screen and show
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
}
Instead of using a JOptionPane, use JButtons in a GridLayout. You can specify how many components you want across and down upon creation like this: new GridLayout(0, 3). This would result in 3 buttons stacked on top of each other, the first int being how many you want across, and the second, how many you want down. Try this:
/**
* Make the frame and everything in it
*/
private void makeFrame()
{
frame = new JFrame("Adventure!");
JPanel contentPane = (JPanel)frame.getContentPane();
contentPane.setBorder(new EmptyBorder(6, 6, 6, 6));
contentPane.setLayout(new GridLayout(0, 1));
textArea = new JTextArea(20, 50);
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setFont(new Font("font", Font.BOLD, 15));
JScrollPane scrollPane = new JScrollPane(textArea);
contentPane.add(textArea);
//This replaces your JOptionPane block
buttonPane = new JPanel();
buttonPane.setLayout(new GridLayout(0, 1));
contentPane.add(buttonPane);
frame.pack();
// place the frame at the center of the screen and show
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
}
I need some help in JInternalFrame within JPanel's Area.I have a JFrame which contains
JPanel added to its ContentPane.JFrame Contains Menu when i click one of its Menu item i
need JInternal Frame to be added on top of the contentpane.The Code i have given so far,
JDesktopPane desktop = new JDesktopPane();
desktop.setLayout(new BorderLayout());
JPanel topPanel = new JPanel();
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[] { 0, 0, 0, 0 };
gbl_contentPane.rowHeights = new int[] { 0, 0, 0, 0 };
gbl_contentPane.columnWeights = new double[] { 1.0, 6.0, 1.0,
Double.MIN_VALUE };
gbl_contentPane.rowWeights = new double[] { 0.0, 8.0, 0.0,
Double.MIN_VALUE };
topPanel.setLayout(gbl_contentPane);
JPanel left = new JPanel();
GridBagConstraints gbc_left = new GridBagConstraints();
gbc_left.insets = new Insets(0, 0, 5, 5);
gbc_left.fill = GridBagConstraints.BOTH;
gbc_left.gridx = 0;
gbc_left.gridy = 1;
topPanel.add(left, gbc_left);
JPanel middle = new JPanel();
GridBagLayout gbl_middle = new GridBagLayout();
gbl_middle.columnWeights = new double[] { 1.0 };
middle.setLayout(gbl_middle);
GridBagConstraints gbc_middle = new GridBagConstraints();
gbc_middle.insets = new Insets(0, 0, 5, 5);
gbc_middle.fill = GridBagConstraints.BOTH;
gbc_middle.gridx = 1;
gbc_middle.gridy = 1;
topPanel.add(middle, gbc_middle);
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel1 = new JPanel();
Border eBorder = BorderFactory.createEtchedBorder();
panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "70pct"));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = gbc.weighty = 30;
middle.add(panel1, gbc);
panel1.setLayout(new MigLayout("", "[944.00,grow][353.00]",
"[6.00][128.00,grow][]"));
/*lblHeader = new JLabel(
"<html>Indira Institute of Technology<br>Tatabad<br>Karpagam Complex Stop<br>Coimbatre</html>");
lblHeader.setIcon(new ImageIcon(
"C:\\Users\\Prakash\\Desktop\\images.jpg"));
panel1.add(lblHeader, "cell 0 1 2 1,alignx center,aligny center");*/
JPanel panel2 = new JPanel();
gbc = new GridBagConstraints();
panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "30pct"));
gbc.gridy = 1;
gbc.gridwidth = gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = gbc.weighty = 70;
gbc.insets = new Insets(2, 2, 2, 2);
middle.add(panel2, gbc);
panel2.setLayout(new MigLayout(
"",
"[30px][69.00px][144.00][68.00][][159.00px][59.00px][65px][28.00][]",
"[20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][30.00][48.00:n,grow 50,shrink 50]"));
getContentPane.add(topPanel);
I have never used the DesktopPane in this(I don't know how to make use of this in this situation) And The Screen So far is as follows,
Now I need the JInternalFrame to be added for the Previous Screen as Follows,
I am aware that i can only be able to add a JInternalFrame to the DesktopPane.But i
Already Filled my ContentPane with JPanel to show its content.How can i achieve Jinternal
Frame to be added in this JFrame.Kindly give your valuable suggestions.
Not really the right direction. You original panel is under the control of layout manager, this means that when you add the JInternalFrame to it, the layout manager wants to try and layout it out.
Generally speaking, a JInternalFrame wants to reside in a container which is unmanaged, allowing it to be positioned and sized independently of the content.
A possible solution might be to take advantage of the glass pane for the JInternalFrame instead, for more details see How to Use Root Panes
Another solution might be to use a JLayeredPane. Basically, you would start by setting the layout manager of the JLayeredPane to something link BorderLayout add the first panel to it and then add a second, transparent pane, with no layout, above it. You would add the JInternalFrames to this second panel.
See How to Use Layered Panes for more details
The question that jumps out at me though is...why? Why wouldn't you just use some kind of dialog instead? See How to Make Dialogs for more details
What is it what you really want?
You wrote you already have your content pane added to your frame. JDesktopPane has to have its own space reserved. If you don't have or you don't want to reserve space for the internal frames in your main frame, then maybe you don't even want it to be part of the main frame. In this case you might want to use child JDialogs instead of JInternalFrames.
So either add your JDesktopPane to your main frame (having its space reserved) or use child JDialogs which can be modal or not and can overlap any part of the main frame. JInternalFrames are only visible in the area of the JDesktopPane while child JDialogs can "float" over your main frame.
Check out this Oracle documentation: How to Use Internal Frames
And How to Make Dialogs.
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);