add borders around each element in a JPanel - java

I have a JPanel and I'm adding 25 JPanels to the inside in a grid. I want a border around each panel so you can clearly distinguish between each element. Padding would work as well. The way I'm adding panels to the board if I try to add a border it will apply it to the larger panel containing the elements instead.
public class LightsOutView
{
GridLayout experimentLayout = new GridLayout(5, 5);
// Creates layout of the GUI
public LightsOutView ()
{
JFrame frame = new JFrame();
frame.setTitle("Lights Out");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setContentPane(makeContents());
frame.setVisible(true);
}
/**
* Creates the blank game board. Returns the panel
*
* #return JPanel
*/
public JPanel makeContents ()
{
// Create a panel to hold the 5x5 grid
JPanel board = new JPanel(new GridLayout(5, 5));
board.setLayout(experimentLayout);
// Add the components to the panel
for (int i = 0; i < 25; i++)
{
board.add(new JPanel()).setBackground(Color.YELLOW);
}
// Return the panel
return board;
}
}
How do I add a border around each element. Will I need to change how I'm adding panels to the grid?

One way:
Change your GridLayout to something like:
GridLayout experimentLayout = new GridLayout(5, 5, gap, gap);
where gap is some small int value, say 1 to 3 (for pixels). Then give the background container a background color, and it will show through the gaps. You'll also want to give the background JPanel a line border with the same gap width.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
#SuppressWarnings("serial")
public class GridWithBorders extends JPanel {
private static final int SIDES = 6;
private static final int SIDE_LENGTH = 60;
private static final int GAP = 3;
private static final Color BG = Color.BLACK;
private static final Color CELL_COLOR = Color.GREEN.darker();
public GridWithBorders() {
setBackground(BG);
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new GridLayout(SIDES, SIDES, GAP, GAP));
Dimension prefSize = new Dimension(SIDE_LENGTH, SIDE_LENGTH);
for (int i = 0; i < SIDES; i++) {
for (int j = 0; j < SIDES; j++) {
JPanel cell = new JPanel();
cell.setBackground(CELL_COLOR);
cell.setPreferredSize(prefSize);
add(cell);
}
}
}
private static void createAndShowGui() {
GridWithBorders mainPanel = new GridWithBorders();
JFrame frame = new JFrame("GridWithBorders");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

Related

Attempting to change grid size based on which RadioButton is selected - Java Swing GUI - SOS board game

This project revolves around a game that is a variation of TicTacToe called SOS. One of the requirements is that the game grid needs to have two size options. The smaller grid is 5x5 and the larger is 8x8.
My goal is to have the grid size change based off which radio button is selected. In my code below I have a commented out method to change the GRID_SIZE variable based off which radio button is selected. But it does not work where it is currently and I am struggling to come up with the solution. The other problem related to the grid size changing that I think I'll have is, I do not believe the way I create the grid now will allow for it to change live as the radio buttons are pushed.
I will need to be keeping track of what gets played in each cell of the grid (whether a player is placing an S or an O) So my thought is maybe there is a better way to create the grid for both the GUI and as a storage method for the moves played.
This project is my first java project and first GUI project of this depth. It is also the major project for one of my last classes to graduate so I'm taking this seriously and could really use the help. I know my code is probably not great, I'm here to improve so any help is welcomed.
package practice;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings({ "serial", "unused"})
public class SOS_GUI extends JFrame {
public int GRID_SIZE = 8;
public Grid grid;
public SOS_GUI() {
GameBoard();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setTitle("SOS Practice");
this.setLocationRelativeTo(null);
setVisible(true);
}
public void GameBoard(){
// CONTENT PANE FOR HOLDING ALL GUI COMPONENTS
Container ContentPane = getContentPane();
// PANEL FOR GAME GRID
JPanel gameBoardCanvas = new JPanel();
gameBoardCanvas.setLayout(new GridLayout(GRID_SIZE, GRID_SIZE));
for (int x = 0; x < GRID_SIZE; x++) {
for (int y = 0; y < GRID_SIZE; y++) {
final Grid cell = new Grid(x, y);
gameBoardCanvas.add(cell);
}
}
// FOUR PANELS SURROUNDING GAME GRID
JPanel TopPanel = new JPanel();
JPanel BottomPanel = new JPanel();
JPanel LeftPanel = new JPanel();
JPanel RightPanel = new JPanel();
JLabel SpacerLabel = new JLabel(" || ");
// GAME MODE OOPTIONS - SIMPLE OR GENERAL
JLabel GameModeLabel = new JLabel("Game Mode :");
JRadioButton SimpleGameButton = new JRadioButton("Simple", true);
JRadioButton GeneralGameButton = new JRadioButton("General");
ButtonGroup GameModeButtons = new ButtonGroup();
GameModeButtons.add(SimpleGameButton);
GameModeButtons.add(GeneralGameButton);
// BOARD SIZE BUTTONS - SMALL(5X5) OR LARGE(8X8)
JLabel SizeOptionLabel = new JLabel("Board Size :");
JRadioButton SmallGridButton = new JRadioButton("Small", true);
JRadioButton LargeGridButton = new JRadioButton("Large");
ButtonGroup GridSizeButtons = new ButtonGroup();
GridSizeButtons.add(SmallGridButton);
GridSizeButtons.add(LargeGridButton);
// PLAY LETTER SETTINGS
JRadioButton PlayS_Button = new JRadioButton("S", true);
JRadioButton PlayO_Button = new JRadioButton("O");
ButtonGroup PlayLetterButtons = new ButtonGroup();
PlayLetterButtons.add(PlayS_Button);
PlayLetterButtons.add(PlayO_Button);
// BLUE PLAYER SETTINGS
JLabel BluePlayerLabel = new JLabel("Blue Player");
JRadioButton BlueHumanButton = new JRadioButton("Human", true);
JRadioButton BlueComputerButton = new JRadioButton("Computer");
ButtonGroup BluePlayerButtons = new ButtonGroup();
BluePlayerButtons.add(BlueHumanButton);
BluePlayerButtons.add(BlueComputerButton);
// RED PLAYER SETTINGS
JLabel RedPlayerLabel = new JLabel("Red Player");
JRadioButton RedHumanButton = new JRadioButton("Human");
JRadioButton RedComputerButton = new JRadioButton("Computer", true);
ButtonGroup RedPlayerButtons = new ButtonGroup();
RedPlayerButtons.add(RedHumanButton);
RedPlayerButtons.add(RedComputerButton);
// ADDING COMPONENTS TO TOP PANEL
TopPanel.add(GameModeLabel);
TopPanel.add(SimpleGameButton);
TopPanel.add(GeneralGameButton);
TopPanel.add(SpacerLabel);
TopPanel.add(SizeOptionLabel);
TopPanel.add(SmallGridButton);
TopPanel.add(LargeGridButton);
// ADDING COMPONENTS TO BOTTOM PANEL
BottomPanel.add(PlayS_Button);
BottomPanel.add(PlayO_Button);
// ADDING COMPONENTS TO LEFT PANEL
LeftPanel.add(BluePlayerLabel);
LeftPanel.add(BlueHumanButton);
LeftPanel.add(BlueComputerButton);
// ADDING COMPONENTS TO RIGHT PANEL
RightPanel.add(RedPlayerLabel);
RightPanel.add(RedHumanButton);
RightPanel.add(RedComputerButton);
// ADDING PANELS TO CONTENT PANE
ContentPane.setLayout(new BorderLayout());
ContentPane.add(TopPanel, BorderLayout.NORTH);
ContentPane.add(BottomPanel, BorderLayout.SOUTH);
ContentPane.add(LeftPanel, BorderLayout.WEST);
ContentPane.add(RightPanel, BorderLayout.EAST);
ContentPane.add(gameBoardCanvas, BorderLayout.CENTER);
TopPanel.setPreferredSize(new Dimension(50, 50));
BottomPanel.setPreferredSize(new Dimension(50, 50));
LeftPanel.setPreferredSize(new Dimension(100, 100));
RightPanel.setPreferredSize(new Dimension(100, 100));
ContentPane.setPreferredSize(new Dimension(550, 500));
}
// CLASS SETTING UP HOW THE GRID WILL BE CREATED
class Grid extends JPanel {
public static final int CELL_SIZE = 1;
private int xPos;
private int yPos;
public JLabel gridLabel;
public Grid (int x, int y) {
xPos = x;
yPos = y;
gridLabel = new JLabel("");
gridLabel.setFont(new Font("Serif", Font.BOLD, 40));
add(gridLabel);
setOpaque(true);
setLayout(new FlowLayout());
setBorder(BorderFactory.createBevelBorder(CELL_SIZE));
setBackground(new Color(200, 200, 200));
setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
}
}
/* POSSIBLE FUNCTION TO SET GRID_SIZE BASED OFF RADIO BUTTON INPUT? DOESNT WORK HERE
public getGridSize() {
if (GameBoard().SmallGridButton.isSelected() == true) {
GRID_SIZE = 5;
}
else if (GameBoard().LargeGridButton.isSelected() == true) {
GRID_SIZE = 8;
}
return GRID_SIZE;
}
*/
public static void main(String[] args) {
new SOS_GUI();
}
}
screenshot of the smaller 5x5 grid
screenshot of larger 8x8 grid
Again, I suggest that if you want to use components as your grid cell, that you either swap views (JPanels) using a CardLayout, or you swap out the grid cells when a JRadioButton is pressed.
I suggest:
Adding an ActionListener to the JRadioButton to be notified when it is pressed.
If you will swap components, then create a JPanel to hold the grid cells, say called gridHolder, and remove all components when the button is pressed.
Then add a new GridLayout layout manager to this JPanel, with constraints set depending on whih JRadioButton has been pressed.
Then re-adding grid cell components to this holder JPanel
Then relaying out all components in the GUI and resizing it by calling pack() on the top-level window, here a JFrame.
In the example below, I use JLabels to hold the grid cells since it is trivial to add text to these.
I store the row and column of each grid cell using the .putClientProperty(...) method and likewise can retrieve values using the .getClientProperty(...) method.
I call createGrid(...) in the constructor to create the grid with the default, small, size.
I call the same method whenever a JRadioButton has been pressed.
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.border.BevelBorder;
#SuppressWarnings("serial")
public class SosGrid2 extends JPanel {
private static final int SMALL_SIZE = 5;
private static final int LARGE_SIZE = 8;
private static final String[] SIZES = { "Small", "Large" };
private static final Dimension CELL_SIZE = new Dimension(60, 60);
private static final Color GRID_BG = new Color(200, 200, 200);
private static final String ROW = "row";
private static final String COL = "col";
private JPanel gridHolder = new JPanel();
private ButtonGroup gridSizeGroup = new ButtonGroup();
public SosGrid2() {
JPanel radioButtonPanel = new JPanel();
for (String size : SIZES) {
JRadioButton radioButton = new JRadioButton(size);
radioButton.setSelected(size.equals(SIZES[0]));
radioButton.setActionCommand(size);
gridSizeGroup.add(radioButton);
radioButtonPanel.add(radioButton);
radioButton.addActionListener(e -> radioListener());
}
createGrid(SMALL_SIZE);
setLayout(new BorderLayout());
add(gridHolder);
add(radioButtonPanel, BorderLayout.PAGE_END);
}
private void createGrid(int gridSize) {
gridHolder.removeAll();
gridHolder.setLayout(new GridLayout(gridSize, gridSize));
for (int row = 0; row < gridSize; row++) {
for (int col = 0; col < gridSize; col++) {
JLabel gridCell = createGridCell(row, col);
gridHolder.add(gridCell);
}
}
}
// factory method to create grid cell JLabels.
private JLabel createGridCell(int row, int col) {
JLabel label = new JLabel("", SwingConstants.CENTER);
label.setFont(label.getFont().deriveFont(Font.BOLD, 32f));
label.setOpaque(true);
label.setBackground(GRID_BG);
label.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
label.setPreferredSize(CELL_SIZE);
label.putClientProperty(ROW, row);
label.putClientProperty(COL, col);
label.addMouseListener(new MyMouseListener());
return label;
}
private class MyMouseListener extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
JLabel gridCell = (JLabel) e.getSource();
int row = (int) gridCell.getClientProperty(ROW);
int col = (int) gridCell.getClientProperty(COL);
String message = String.format("Row: %d, Col: %d", row, col);
String title = "Cell Pressed";
int type = JOptionPane.PLAIN_MESSAGE;
JOptionPane.showMessageDialog(SosGrid2.this, message, title, type);
String text = gridCell.getText();
if (text.isEmpty()) {
gridCell.setText("X");
} else {
gridCell.setText("");
}
}
}
private void radioListener() {
ButtonModel btnModel = gridSizeGroup.getSelection();
if (btnModel != null) {
int gridSize = btnModel.getActionCommand().equals(SIZES[0]) ? SMALL_SIZE : LARGE_SIZE;
createGrid(gridSize);
Window jframe = SwingUtilities.getWindowAncestor(this);
jframe.pack();
jframe.setLocationRelativeTo(null);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SosGrid2 mainPanel = new SosGrid2();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

Java GUI Swing, buttons in GridLayout without space between buttons

I want to create a grid of buttons. Between the buttons there should not be a space, so that the buttons touch the next buttons.
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
public class Bild extends JFrame {
public static class createButton extends JPanel {
public createButton() {
JButton b = new JButton();
Border border = new LineBorder(Color.BLACK, 1);
b.setBorder(border);
b.setBackground(Color.WHITE);
b.setPreferredSize (new Dimension(10,10));
this.add(b);
}
}
public Bild() {
GridLayout layout = new GridLayout(10,10,0,0);
this.setLayout(layout);
for (int i = 0; i < 100; i++) {
this.add(new createButton());
}
}
}
import javax.swing.*;
import java.awt.*;
public class Main{
public static void main (String[] args) {
JFrame frame = new Bild();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
}
with the grid layout I tried to get a 10x10 grid of buttons. But although I created the GridLayout with the parameters 10,10,0,0 there is a space between the buttons.
Where is my mistake?
It's because createButton is actually a JPanel, which has a FlowLayout as it's layout manager by default. Make createButton a method that returns a JButton and the button will span across the whole space within the cell. (You can remove the setPreferredSize()). If you want the buttons to remain 10x10 pixels and be centered within the frame: Set the layout manager of the main panel to a GridBagLayout and add a JPanel with the GridLayout to it. Maybe also override getPreferredSize() of the buttons rather than calling setPreferredSize().
Buttons spanning across whole screen:
class Bild extends JFrame {
public JButton createButton() {
JButton b = new JButton();
Border border = new LineBorder(Color.BLACK, 1);
b.setBorder(border);
b.setBackground(Color.WHITE);
return b;
}
public Bild() {
setLayout(new GridLayout(10, 10));
for (int i = 0; i < 100; i++) {
add(createButton());
}
}
}
Buttons remaining 10x10:
class Bild extends JFrame {
public JButton createButton() {
JButton b = new JButton() {
#Override
public Dimension getPreferredSize() {
return new Dimension(10, 10);
}
};
Border border = new LineBorder(Color.BLACK, 1);
b.setBorder(border);
b.setBackground(Color.WHITE);
return b;
}
public Bild() {
JPanel panel = new JPanel(new GridLayout(10, 10));
for (int i = 0; i < 100; i++) {
panel.add(createButton());
}
setLayout(new GridBagLayout());
add(panel);
}
}

How to make a JPanel expand to max width in another JPanel

I feel I need to rephrase the question a bit.
Updated question below.
I have a JPanel that contains:
myjpanel.setLayout(new BoxLayout(selectors, BoxLayout.PAGE_AXIS));
It contains the following three panels:
JPanel with fixed size 'x' and 'y'
JPanel with no fixed size
JPanel with no fixed size and small height
The second JPanel contains a JTable so it expands to fill the full height and pushes the bottom panel all the way down, as expected.
Like this:
t
t
m
m
m
m
m
b
t = top panel,
m = middle panel,
b = bottom panel.
That works. But the bottom panel does not feel like filling the entire width of the parent which is a problem.
ttt
mmm
b
I would like either this, where the panel fills the entire width:
ttt
mmm
bbb
or this, where the bottom panel is left centered:
ttt
mmm
b
Old question below:
I have a JPanel that contains:
.setLayout(new BoxLayout(selectors, BoxLayout.PAGE_AXIS));
Within it, there are three more JPanels. The first two are of fixed size and the middle one isn't.
I want my bottom panel to take only the height it needs, but uses all the available width of the outer JPanel.
I have tried using glue but to no avail, and I would rather not set preferred and min/max sizes.
Is there a way to tell the component to "Fill the entire parents width" using just the layout manager and framework. I would rather not start to do hacks like setting sizes and overriding methods.
Note: I can't put any glue or filler in the inner panel, only the outer panel and its layout manager can be modified.
Attempt 1:
Using myPanel.setLayout(new GridLayout(3, 1)); did not produce the expected results. It made a grid like this:
XX
X
But I expected:
X
X
X
Attempt 2:
Using myPanel.setLayout(new GridLayout(0,1)); did not produce the expected results. It made a grid like this:
x
x
x
But all panels were of the same size, ignoring the restraints.
The easiest way would be to use another layout manager such as GridLayout that automatically sizes components to fill the parent container.
myPanel.setLayout(new GridLayout(0, 1));
If using a BorderLayout and the b panel is in the SOUTH or PAGE_END it does fill the entire width.
You can use GridBagLayout, for that, using
gridBagObject.fill = GridBagConstraints.HORIZONTAL
One example for your help, relating to GridBagLayout.
As asked in comments, related to that
The BoxLayout is another alternative, that respects the preferred sizes of the components. You can try that if GridBagLayout is that tough :-)
Code with GridBagLayout, for more clarity :
import javax.swing.*;
import java.awt.*;
/**
* Created with IntelliJ IDEA.
* User: Gagandeep Bali
* Date: 1/10/13
* Time: 7:43 PM
*/
public class GridBagExample
{
private void displayGUI()
{
JFrame frame = new JFrame("GridBagLayout Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
CustomPanel topPanel = new CustomPanel(Color.BLUE.darker().darker());
CustomPanel middlePanel = new CustomPanel(Color.CYAN.darker().darker());
CustomPanel bottomPanel = new CustomPanel(Color.DARK_GRAY);
JPanel contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.3;
contentPane.add(topPanel, gbc);
gbc.gridy = 1;
contentPane.add(middlePanel, gbc);
gbc.gridy = 2;
gbc.fill = GridBagConstraints.BOTH;
contentPane.add(bottomPanel, gbc);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new GridBagExample().displayGUI();
}
});
}
}
class CustomPanel extends JPanel
{
public CustomPanel(Color backGroundColour)
{
setOpaque(true);
setBackground(backGroundColour);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(200, 150));
}
}
OUTPUT :
Here some custom JPanel is used to expanding and shrinking with static input values.
Java timer is using to Delay and speed up the panel display time.
public class SlidingPanel extends JPanel {
private int paneHeight;
private int paneWidth;
private int comHeight;
private int comWidth;
private Timer everyspeedmillisec;
/**custom class for slide up and down actions for JPanel
*
*/
public SlidingPanel(LayoutManager layout,Dimension panedim) {
super(layout);
setPreferredSize(panedim);
paneHeight = (int)panedim.getHeight();;
paneWidth = (int) panedim.getWidth();
}
/**function for expanding Jpanel
*
*/
public void expand_sft_det(int speed ,JPanel slidingcom)
{
//Add Jpanel for sliding
this.add(slidingcom);
//Get height and width for panel ,that what we want to display as slide height.
comHeight=(int)slidingcom.getMinimumSize().getHeight();
comWidth=(int) slidingcom.getMinimumSize().getWidth();
//Intializing timer with some static values - Medium speed)
everyspeedmillisec = new Timer(30, new ActionListener() {
private int count_timer=0;
public void actionPerformed(ActionEvent e) {
count_timer++;
if( paneHeight < comHeight){
setPreferredSize(new Dimension(paneWidth, paneHeight));
paneHeight+=20;
repaint();
revalidate();
}
else
everyspeedmillisec.stop() ;
}
});
everyspeedmillisec.start();
}
/**function for Shrinking Jpanel
*
*/
public void shrink_sft_det(int speed ,JPanel slidingcom) {
comHeight = (int)slidingcom.getMinimumSize().getHeight();
comWidth = (int)slidingcom.getMinimumSize().getWidth();
//height for slide up to top position
paneHeight=0;
everyspeedmillisec = new Timer(30, new ActionListener() {
private int count_timer=0;
public void actionPerformed(ActionEvent e) {
count_timer++;
if( paneHeight < comHeight){
setPreferredSize(new Dimension(comWidth,comHeight));
comHeight-=20;
repaint();
revalidate();
}
else
everyspeedmillisec.stop() ;
}
});
everyspeedmillisec.start();
}
//Declare class and using shrinking onclick event
public class SoftPanel extends JPanel implements ActionListener
, MouseListener {
JPanel MoredetPane;
JPanel SlidedetPane;
private JLabel SoftDOCLabel;
private JLabel SoftLocation;
private JLabel SoftUpdates;
private boolean mr_det_flag =true;
MoredetPane = new SlidingPanel(new GridLayout(1,1,5,5),new Dimension(300,1));
MoredetPane.setOpaque(false);
//Add some components
SlidedetPane = new JPanel(new GridLayout(3,2,50,25));
SlidedetPane.setPreferredSize(new Dimension(300,200));
SlidedetPane.setOpaque(false);
SoftDOCLabel = new JLabel("Software Date") ;
SoftLocation = new JLabel("Software Location") ;
SoftUpdates = new JLabel("Software Updates") ;
SlidedetPane.add(SoftDOCLabel);
SlidedetPane.add(new JLabel(softbean.getSoftDOC()));
SlidedetPane.add(SoftLocation);
SlidedetPane.add(new JLabel(softbean.getSoftPath()));
SlidedetPane.add( SoftUpdates);
SlidedetPane.add(new JLabel(""));
//Onclick events
modedetails_Label.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent clickeve) {
if(mr_det_flag){
mr_det_flag=false;
((SlidingPanel)MoredetPane).expand_sft_det(200,SlidedetPane);
add(SlidingPanel);
}
else{
mr_det_flag=true;
((SlidingPanel) MoredetPane).shrink_sft_det(0,SlidedetPane);
}
});
add( MoredetPane );
}

Empty JPanel not positioning correctly in relation to other JPanels

I am using swing to build a GUI with 4 JPanels inside a JPanel using the BorderLayout manager:
A row of labels
A column of JButtons
A display area (it is a class that extends JPanel and has nothing added to it and is used as a drawing area)
Another column of buttons
My code looks like this:
JPanel middle = new JPanel();
middle.setLayout(new BorderLayout());
middle.add(midLabels,BorderLayout.NORTH);
middle.add(pickupButtons,BorderLayout.WEST);
middle.add(simulation,BorderLayout.CENTER);
middle.add(dropButtons,BorderLayout.EAST);
The simulation panel is just an extended JPanel that overrides paintComponent to draw an image. The problem is, the simulation area is on the left and not in the middle:
What I actually want is:
Edit, here is an example, do I need to use a different layout manager to get the empty JPanel positioned correctly?:
import java.awt.*;
import javax.swing.*;
public class Test extends JFrame {
final static int MAXFLOORS = 8;
public Test() {
setLayout(new BorderLayout());
setTitle("Simulator");
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 500);
JPanel simulation = new JPanel();
JPanel dropButtons = new JPanel();
JPanel pickupButtons = new JPanel();
pickupButtons.setLayout(new GridLayout(MAXFLOORS, 1));
dropButtons.setLayout(new GridLayout(MAXFLOORS, 1));
setLayout(new BorderLayout());
add(simulation,BorderLayout.CENTER);
add(dropButtons,BorderLayout.EAST);
add(pickupButtons,BorderLayout.WEST);
for (int i = MAXFLOORS; i != 0; i--) {
JButton pb = new JButton("F" + i);
dropButtons.add(pb);
JButton db = new JButton("F" + i);
dropButtons.add(db);
}
repaint();
}
public static void main(String[] args) {
new Test();
}
}
Look at your code:
for (int i = MAXFLOORS; i != 0; i--) {
final JButton pb = new JButton("F" + i);
dropButtons.add(pb);
final JButton db = new JButton("F" + i);
dropButtons.add(db);
}
You're adding onto dropButtons twice, instead of pickupButtons.

Java, BorderLayout.CENTER, getting the width and height of the JPanel

I am using Swing and AWT (for the listeners) to make a small program. I have a problem concerning getting the size of my JPanel (the class named Chess).
My Layout:
public class Main extends JFrame implements MouseListener, ActionListener{
Chess chessPanel = new Chess ();
JButton newGameButton = new JButton ("New Game");
JButton loadGameButton = new JButton ("Load Game");
JButton saveGameButton = new JButton ("Save Game");
JButton exitButton = new JButton ("Exit");
public static void main (String [] args) {
new Main();
}
Main () {
super ("Chess");
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
setSize(dim);
setLocation(0,0);
setUndecorated(true);
chessPanel.addMouseListener(this);
add(chessPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
newGameButton.addActionListener(this);
loadGameButton.addActionListener(this);
saveGameButton.addActionListener(this);
exitButton.addActionListener(this);
buttonPanel.add(newGameButton);
buttonPanel.add(loadGameButton);
buttonPanel.add(saveGameButton);
buttonPanel.add(exitButton);
add(buttonPanel, BorderLayout.SOUTH);
setVisible(true);
}
// ... Code ...
}
As you can see by the code, I have one JPanel in the CENTER, which takes nearly all the screen. In the bottom I have another JPanel (SOUTH), which has a row of buttons.
What I need is the size that the JPanel in the CENTER takes. When I call the getWidth(), getHeight() or getBounds() methods inherited from JPanel, they all return 0, because of the BorderLayout.
Any idea how to get the real values?
PS: The screen always takes up the entire screen, and will never be resized, if that helps.
You're likely calling getWidth before the JPanel has been rendered, and so it will be 0. The solution is to get the size after rendering, for instance after pack() or setVisible(true) has been called on the root container that holds this JPanel.
Also, I recommend against calling setSize() on anything since most of the standard layout managers observe the preferred size of a component, not the size, and when you call pack() telling the layout managers to do their thing, the set sizes are usually ignored. You may want to make your JPanel that is in the center set its own size by overriding its setPreferredSize method if it needs to be a certain size. Then let the JFrame and its held containers set the bet fit size based on the their layout managers when you call pack.
e.g.,
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame {
Chess chessPanel = new Chess();
JButton newGameButton = new JButton("New Game");
JButton loadGameButton = new JButton("Load Game");
JButton saveGameButton = new JButton("Save Game");
JButton exitButton = new JButton("Exit");
public static void main(String[] args) {
new Main();
}
Main() {
super("Chess");
add(chessPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(newGameButton);
buttonPanel.add(loadGameButton);
buttonPanel.add(saveGameButton);
buttonPanel.add(exitButton);
System.out.printf("chessPanel Size before rendering: %s%n", chessPanel.getSize());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(buttonPanel, BorderLayout.SOUTH);
pack();
System.out.printf("chessPanel Size after rendering: %s%n", chessPanel.getSize());
setLocationRelativeTo(null);
setVisible(true);
}
// ... Code ...
}
#SuppressWarnings("serial")
class Chess extends JPanel {
private static final int CHESS_WIDTH = 600;
private static final int CHESS_HEIGHT = CHESS_WIDTH;
private static final int MAX_ROW = 8;
private static final int MAX_COL = 8;
private static final Color LIGHT_COLOR = new Color(240, 190, 40);
private static final Color DARK_COLOR = new Color(180, 50, 0);
#Override
public Dimension getPreferredSize() {
return new Dimension(CHESS_WIDTH, CHESS_HEIGHT);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int panelWidth = getWidth();
int panelHeight = getHeight();
int sqrWidth = panelWidth / MAX_ROW;
int sqrHeight = panelHeight / MAX_COL;
for (int row = 0; row < MAX_ROW; row++) {
for (int col = 0; col < MAX_COL; col++) {
Color c = (row % 2 == col % 2) ? LIGHT_COLOR : DARK_COLOR;
g.setColor(c);
int x = (row * panelWidth) / MAX_ROW;
int y = (col * panelHeight) / MAX_COL;
g.fillRect(x, y, sqrWidth, sqrHeight);
}
}
}
}

Categories