I am trying to resize the center panel of my BorderLayout but the size is not changing. It keeps filling the rest of the frame that is available. I have tried setting the preferred size but has no effect. I would like how size of the frame but only need a portion of the center to be actually a panel for later use.
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
public class Gui extends JFrame {
Border blackline = BorderFactory.createLineBorder(Color.black);
private JPanel board;
private JPanel buttons;
private JButton setMissing, by4, by8;
public Gui(){
setUpGui();
}
public void setUpGui(){
this.setSize(1000,1000);
this.setTitle("Comp361 Assignment One");
addButtons();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
board = new JPanel();
board.setPreferredSize(new Dimension(400,400));
this.add(board, BorderLayout.CENTER);
//Sboard.setBackground(Color.Gray);
board.setBorder(blackline);
this.setVisible(true);
}
public void addButtons(){
buttons = new JPanel(new FlowLayout());
setMissing = new JButton("Set X");
by4 = new JButton("4 by 4");
by8 = new JButton("8 by 8");
buttons.add(setMissing);
buttons.add(by4);
buttons.add(by8);
this.add(buttons,BorderLayout.PAGE_START);
}
public static void main (String[] args){
new Gui();
}
}
For extra padding around the central panel, you might put it to a panel with GridBagLayout (with no constraint) to center it, then add the GBL panel to the CENTER of the BorderLayout.
Related
I'm writing this swing application and I'm using multiple panels in a BoxLayout format, but it seems to be that the empty space between the panels is being divided up between them and it looks really ugly. How do you adjust and customize how much space is put between panels? Sorry if this is a repost; I was unable to find an older post.
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
class gui extends JFrame implements ActionListener{
JFrame frame = new JFrame("Ark Admin Spawn Commands");
JPanel panel = new JPanel();
JComboBox dinos;
JComboBox corruptedDinos;
public JSlider dinoLevel;
JLabel input;
JLabel dino;
JLabel title;
gui(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JPanel panelOne = new JPanel();
JPanel panelTwo = new JPanel();
JPanel panelThree = new JPanel();
mainPanel.add(panelOne);
mainPanel.add(panelTwo);
mainPanel.add(panelThree);
title = new JLabel("Spawning Dinos");
String[] dinoNames= {"The Island:"};
String[] corruptedDinoNames = {"Extinction:"};
dinos = new JComboBox(dinoNames);
corruptedDinos = new JComboBox(corruptedDinoNames);
dinoLevel = new JSlider(JSlider.HORIZONTAL, 1, 600, 400);
dinoLevel.setMajorTickSpacing(20);
dinoLevel.setPaintTicks(true);
input = new JLabel("Select Level: ");
event e = new event();
dinoLevel.addChangeListener(e);
dinos.addActionListener(this);
corruptedDinos.addActionListener(this);
panelOne.add(title);
panelTwo.add(input);
panelTwo.add(dinoLevel);
panelThree.add(dinos);
panelThree.add(corruptedDinos);
this.getContentPane().add(mainPanel);
this.setTitle("Ark Admin Spawn Commands");
this.setSize(600, 600);
this.setVisible(true);
}
public static void main (String args[]) {
new gui();
}
public class event implements ChangeListener{
#Override
public void stateChanged(ChangeEvent e) {
int value = dinoLevel.getValue();
input.setText("Level: " + value);
}
}
#Override
public void actionPerformed(ActionEvent arg0) {
}
}
but it seems to be that the empty space between the panels is being divided up between them
Correct. A BoxLayout will attempt to allocate extra space to all components.
However, it will respect the maximum size of each panel.
So to prevent the panels height from growing you can use code like:
JPanel panelOne = new JPanel()
{
#Override
public dimension getMaximumSize()
{
Dimension d = getPreferredSize()
d.width = Integer.MAX_VALUE;
return d;
}
};
Or because the default layout manager of the frame is a BorderLayout, you can just use:
//this.getContentPane().add(mainPanel);
add(mainPanel, BorderLayout.PAGE_START); // getContentPane() is not needed
The PAGE_START of the BorderLayout respects the preferred height of the component.
I'm trying to get a JTextArea with a "save" JButton centered underneath it, maybe with a small bit of padding between the components as well as the components to the frame if possible. I've tried messing around with layout managers, panels, etc. and can't seem to get the result i want. Just looking for the simplest way to do this. Thanks.
Suggestions:
The overall layout of the GUI container could be BorderLayout.
Add the JScrollPane that holds your JTextArea BorderLayout.CENTER.
Create a JPanel just to hold the JButton and don't give it a specific layout manager. It will now use JPanel's default FlowLayout and will center components in the horizontal direction.
Add your JButton to this last JPanel.
Add that same JPanel to the GUI in the BorderLayout.PAGE_END (bottom) position.
For example:
import java.awt.BorderLayout;
import javax.swing.*;
public class SimpleLayout extends JPanel {
private static final int ROWS = 20;
private static final int COLS = 60;
private JTextArea textArea = new JTextArea(ROWS, COLS);
private JButton button = new JButton("Button");
public SimpleLayout() {
JPanel buttonPanel = new JPanel();
buttonPanel.add(button);
setLayout(new BorderLayout());
add(new JScrollPane(textArea), BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
SimpleLayout mainPanel = new SimpleLayout();
JFrame frame = new JFrame("SimpleLayout");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
In the below code, I am using gridbaglayout to have all my buttons displayed in two lines on a frame size of 600 X 400. Commenting out setSize() or pack() in the below code did not help. my question is how to get frame of size 600 X 400, and the bottom of frame has a panel with alpabet buttons. Thanks for help.
import javax.swing.*;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.event.*;
public class HangmanGUI {
public static void main(String[] args){
new HangmanGUI();
}
//constructor for Hangman
/**
* Instantiates a new hangman gui.
*/
public HangmanGUI() {
JFrame myframe= new JFrame();
JPanel myPanel = new JPanel();
myPanel.setLayout(new GridLayout());
GridBagConstraints gbc = new GridBagConstraints();
myframe.setSize(600,400);
int x =0; int y=5;
for (char alphabet = 'A';alphabet<='Z';alphabet++){
gbc.gridx=x;
gbc.gridy=y;
myPanel.add(new JButton(alphabet+""),gbc);
x++;
if (x>15){
y =6;x=0;
}
}
myframe.add(myPanel);
myframe.pack();
myframe.setTitle("Hangman Game");
myframe.setVisible(true);
myframe.setLocationRelativeTo(null);
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
When packed, the frame size is computed based on the preferred size of it's content pane.
Personally, I'd care less about the window size and the functionality of the program and let the underlying framework figure it all out...but, if it's important to you...
Start with, something like, a JPanel and override it's getPreferredSize method...
public class BigPane extends JPanel {
public Dimension getPreferredSize() {
return new Dimension(600, 400);
}
}
Set this panel as the frame's content pane...
JFrame myframe= new JFrame();
myFrame.setContentPane(new BigPane());
// This is important as the panels default layout is FlowLayout...
myFrame.setLayout(new BorderLayout());
If you want you button pane to positioned in the south position, then you simply need to supply the correct layout constraint for the layout, in this case, BorderLayout...
myFrame.add(myPanel, BorderLayout.SOUTH);
This will allow you to add a "main" component to the CENTER position.
As has already being suggested, it might be better to use a GridLayout for the buttons, but this will depend on what you want to achieve.
Take a look at Laying out components within a container for more details
In your last Q&A you were advised to use GridLayout as opposed to GridBagLayout. GridBagConstraints are only used in the latter.
This is probably not how you want the GUI to look, but take it as a basic guide of what GridLayout is actually good for.
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
public class HangmanGUI {
/**
* Instantiates a new hangman gui.
*/
public HangmanGUI() {
JPanel gui = new JPanel(new BorderLayout(2,2));
BufferedImage bi = new BufferedImage(
600,200,BufferedImage.TYPE_INT_RGB);
gui.add(new JLabel(new ImageIcon(bi)));
JFrame myframe= new JFrame();
JPanel myPanel = new JPanel();
gui.add(myPanel,BorderLayout.PAGE_END);
myPanel.setLayout(new GridLayout(2,0,0,0));
int x =0; int y=5;
for (char alphabet = 'A';alphabet<='Z';alphabet++){
myPanel.add(new JButton(alphabet+""));
x++;
if (x>15){
y =6;x=0;
}
}
myframe.add(gui);
myframe.pack();
myframe.setTitle("Hangman Game");
myframe.setVisible(true);
myframe.setLocationRelativeTo(null);
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
new HangmanGUI();
}
}
JFrame myframe= new JFrame();
myframe.getContentPane().setLayout(new BorderLayout());
JPanel myPanel = new JPanel();
myPanel.setLayout(new GridLayout(2,13));
GridBagConstraints gbc = new GridBagConstraints();
myframe.setSize(600,400);
int x =0; int y=5;
for (char alphabet = 'A';alphabet<='Z';alphabet++){
gbc.gridx=x;
gbc.gridy=y;
myPanel.add(new JButton(alphabet+""),gbc);
x++;
if (x>15){
y =6;x=0;
}
}
myframe.getContentPane().add(myPanel, BorderLayout.SOUTH);
myframe.setTitle("Hangman Game");
myframe.setVisible(true);
myframe.setLocationRelativeTo(null);
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
I added the BorderLayout to the ContentPane and then added the Panel to the bottom of the ContentPane.
Also removed the pack.
And added the constraints in your new GridLayout to specify 2 rows of 13 columns
I'm completely new to using the GUI in java, so I'm having a bit of trouble figuring out how to align everything that I need to. I have to panels in my JFrame that I need to align (One to the left, one to the right) and a few buttons in one of the panels that I need to be centered in the panel. Here is my code.
package application;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.nio.*;
import java.util.*;
public class Main extends JPanel
{
public static void main(String[] args)
{
//set the ui to the native OS
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e)
{
}
JFrame frame = new JFrame("Application Name");
Menu menu = new Menu();
JPanel iconPanel = new JPanel();
final JPanel grid = new JPanel(new FlowLayout());
JButton firewallButton = new JButton("Firewall");
JButton networkButton = new JButton("Network");
JButton printerButton = new JButton("Printer");
int iconPanelSizeX;
int iconPanelSizeY;
int gridSizeX;
int gridSizeY;
int gridPosition;
//frame setting
frame.setSize(800, 600);
frame.setMinimumSize(new Dimension(800, 600));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//add grid and iconPanel JPanels to the frame
frame.add(iconPanel);
iconPanel.add(firewallButton);
iconPanel.add(networkButton);
iconPanel.add(printerButton);
frame.add(grid);
//iconPanel settings
iconPanel.setBorder(BorderFactory.createLoweredSoftBevelBorder());
iconPanel.setBackground(Color.gray);
iconPanel.setLayout(new FlowLayout());
iconPanel.setSize(new Dimension(100, 600));
iconPanel.setVisible(true);
//grid setting
grid.setBackground(Color.red);
grid.setSize(new Dimension(700, 600));
grid.setVisible(true);
//this is for resizing components when the user resizes the window
int counter = 0;
while(counter == 0)
{
firewallButton.setSize(new Dimension(iconPanel.getWidth(), 50));
networkButton.setSize(new Dimension(iconPanel.getWidth(), 50));
printerButton.setSize(new Dimension(iconPanel.getWidth(), 50));
iconPanelSizeX = frame.getWidth() / 10;
iconPanelSizeY = frame.getHeight();
gridSizeX = (frame.getWidth() / 10) * 9;
gridSizeY = frame.getHeight();
iconPanel.setSize(new Dimension(iconPanelSizeX, iconPanelSizeY));
grid.setSize(new Dimension(gridSizeX, gridSizeY));
}
}
}
As you can see, the second JPanel (grid) doesn't line up with the right side of the frame, and the buttons inside iconTray don't center either. I realize these are both probably simple layout fixes, but I have no clue where to start.
For simple splitting of JFrame you can use GridLayout with 1 row and 2 colums.
frame.setLayout(new GridLayout(1,2,3,3)); //3,3 are gaps
frame.add(grid);
frame.add(iconPanel);
For centering components in panels you can use FlowLayout which is by default set on JPanels:
Doing it manualy:
grid.setLayout(new FlowLayout()); //Centered components
grid.setLayout(new FlowLayout(FlowLayout.LEFT,3,3)); //Components aligned to left
grid.setLayout(new FlowLayout(FlowLayout.RIGHT,3,3)); //Components aligned to right
This is how it looks:
Also, few observations:
Never call setXXXSize() methods for your components;
Try to avoid calling setSize(); for JFrame, call pack(); instead;
Call setVisible(true); in the end of code;
All your huge code can be "stripped" to this:
import javax.swing.*;
import java.awt.*;
public class Main extends JPanel
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Application Name");
JPanel iconPanel = new JPanel();
JPanel grid = new JPanel(new FlowLayout());
JButton firewallButton = new JButton("Firewall");
JButton networkButton = new JButton("Network");
JButton printerButton = new JButton("Printer");
frame.add(iconPanel);
iconPanel.add(firewallButton);
iconPanel.add(networkButton);
iconPanel.add(printerButton);
grid.setBackground(Color.GREEN);
frame.setLayout(new GridLayout(1,2,3,3));
frame.add(grid);
frame.add(iconPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
how to align buttons vertically?
This example uses a vertical Box in the WEST area of the frame's default BorderLayout:
import java.awt.*;
import javax.swing.*;
/** #see http://stackoverflow.com/a/14927280/230513 */
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
display();
}
});
}
private static void display() throws HeadlessException {
JFrame frame = new JFrame("Application Name");
JButton firewallButton = new JButton("Firewall");
JButton networkButton = new JButton("Network");
JButton printerButton = new JButton("Printer");
//iconPanel settings
Box iconPanel = new Box(BoxLayout.Y_AXIS);
iconPanel.add(firewallButton);
iconPanel.add(networkButton);
iconPanel.add(printerButton);
iconPanel.setBackground(Color.gray);
iconPanel.setVisible(true);
frame.add(iconPanel, BorderLayout.WEST);
//grid setting
JPanel grid = new JPanel() {
#Override
// arbitrary placeholder size
public Dimension getPreferredSize() {
return new Dimension(320, 230);
}
};
grid.setBackground(Color.red);
frame.add(grid, BorderLayout.CENTER);
//frame setting
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I suggest you take some time going through A Visual Guide to Layout Managers. This will help you become familiar with the layout managers which are available with the Standard API. It takes some experience and hard work to figure out which of these is the right tool to get the exact look you want. Once you become comfortable with what is available from the Standard API, you should also look around for third-party Layout Manager APIs which provide other options.
I have to panels in my JFrame that I need to align (One to the left,
one to the right) and a few buttons in one of the panels that I need
to be centered in the panel. Here is my code.
I realize these are both probably simple layout fixes, but I have no
clue where to start.
Use more complex layout than simple FlowLayout which you actually using. I suggest to you use
GridBagLayout
BoxLayout
Check references here
What I am trying to achieve is
Create a custom component (mypanel) that extends JPanel with JLabels and JButtons in it arranged via GridBagLayout.
Have a JFrame that would display multiple mypanel in a vertical stack and have its height change accordingly, depending on the number of mypanels added to it (width of the JFrame = width of mypanel).
When the JFrame's height becomes greater than the screen height, have a vertical scrollbar appear for scrolling
I have created mypanel successfully but having lot of trouble with the adding to the JFrame and setting its size, scrollbars part.
this is the code for my jframe
this.window = new JFrame("ADesktop Notifications");
this.window_panel = new JPanel();
this.window_panel_scroll = new JScrollPane(this.window_panel);
this.window.setBounds(this.top_left_x,this.top_left_y, this.width, this.height);
this.window_panel.setLayout(new FlowLayout());
this.window_panel.setAutoscrolls(true);
this.window.add(this.window_panel);
Try this example out (for dynamic expanding JFrame).
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class DynaFrame extends JFrame{
private JPanel basePnl = new JPanel();
public DynaFrame(){
this.setTitle("Dynamic panel addition");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//this.setSize(600, 700);
this.add(getMainPanel());
this.setLocationRelativeTo(null);
this.pack();
this.setVisible(true);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new DynaFrame();
}
});
}
public JPanel getMainPanel(){
basePnl.setLayout(new BoxLayout(basePnl, BoxLayout.Y_AXIS));
basePnl.add(getRowPanel());
return basePnl;
}
public JPanel getRowPanel(){
JPanel pnl = new JPanel();
GridLayout gLayout = new GridLayout();
gLayout.setColumns(4);
gLayout.setRows(1);
pnl.setLayout(gLayout);
pnl.add(new JLabel("Filetype"));
pnl.add(new JTextField());
pnl.add(new JButton("Browse"));
JButton addBtn = new JButton("Add");
addBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
basePnl.add(getRowPanel());
DynaFrame.this.pack();
}
});
pnl.add(addBtn);
return pnl;
}
}