Panel is not showing on frame in Java Swing - java

I've made a HallOfFame class which is subclass of JPanel and i want to add a label writing "Hall OF Fame" on this panel.In the MainWindow class (frame) i have added the HallOfFame (Panel) to the content pane but nothing shows up. The same happens with every component i am trying to add on the frame (MainWindow) except the top (placed North with the BorderLayout) panel with 3 buttons.
public class HallOfFame extends JPanel{
JLabel hofLabel;
public HallOfFame() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.setBorder(new LineBorder(Color.GRAY, 1));
this.setAlignmentX(CENTER_ALIGNMENT);
hofLabel = new JLabel("Hall OF Fame");
add(hofLabel);
}
}
public class MainWindow extends JFrame{
/*Size of main window*/
public static final Dimension winSize = new Dimension(1200, 800);
public static final int TOP_HEIGHT = 80;
public static final int PLAYER_WIDTH = 300;
private GameBoard gameBoard;
private HallOfFame hallOfFame;
private BannerPanel bannerPanel;
private PlayerPanel playerPanel;
public MainWindow() {
//Initializing the frame.
Container c = this.getContentPane();
c.setPreferredSize(winSize);
this.setTitle("TucTacToe");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/*Hall of fame*/
hallOfFame = new HallOfFame();
/*GameBoard*/
gameBoard = new GameBoard();
/*Banner Panel*/
bannerPanel = new BannerPanel();
/*PlayerPanel*/
playerPanel = new PlayerPanel();
/*Adding the components to the window*/
c.add(bannerPanel, BorderLayout.NORTH);
c.add(hallOfFame, BorderLayout.CENTER);
//add(gameBoard, BorderLayout.CENTER);
c.add(playerPanel);
this.pack();
this.setVisible(true);//setting visible the frame.
}
}
Here is the window of the project

c.add(hallOfFame, BorderLayout.CENTER);
c.add(playerPanel)
You are adding the "playerPanel" to the CENTER of the frame. When you don't specify the constraint it defaults to the CENTER when using BorderLayout.
Only the last component added will be visible. So it appears your playerPanel doesn't have any components added to it.
For a simple test just use:
c.add(hallOfFame, BorderLayout.CENTER);
//c.add(playerPanel)
Now you should see the hallOfFame panel.

Related

Resizing JPanel With BorderLayout

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.

JFrame strange white stripe on top of background image

I have a strange white stripe (see below) appearing on top of my background image. The code is quite simple. How to get rid of the white stripe?
//Graphics side of the game
public class GUI extends JFrame {
private final int larghezza = 1280;
private final int altezza = 720;
private final String name = "Sette e Mezzo";
private final ImageIcon backgroundImage;
private JLabel bgImageLabel;
private JPanel backgroundPanel, borderLayoutPanel, topGridLayout, botGridLayout;
public GUI () {
backgroundImage = new ImageIcon ("assets/background.png");
bgImageLabel = new JLabel (backgroundImage);
//Panels
borderLayoutPanel = new JPanel (new BorderLayout ());
topGridLayout = new JPanel (new GridLayout (1, 3));
botGridLayout = new JPanel (new GridLayout (1, 3));
backgroundPanel = new JPanel ();
backgroundPanel.add (bgImageLabel);
//Frame
this.setName (name);
this.setPreferredSize (new Dimension(larghezza, altezza));
this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
//Adding to frame and panels
borderLayoutPanel.add (topGridLayout, BorderLayout.NORTH);
borderLayoutPanel.add (botGridLayout, BorderLayout.SOUTH);
this.add (borderLayoutPanel);
this.add (backgroundPanel);
this.pack ();
this.setLocationRelativeTo (null);
this.setVisible (true);
}
}
Don't use setPreferredSize() when you really mean to override getPreferredSize(). In this case, the specified Dimension probably doesn't quite match the size of "assets/background.png". This allows some portion of another panel to show, perhaps backgroundPanel.
In the example below,
The default layout of JPanel is FlowLayout, which has a "default 5-unit horizontal and vertical gap." A touch of Color.blue makes the gap stand out; resize the enclosing frame to see the behavior.
As the default layout of JFrame is BorderLayout, you may not need borderLayoutPanel at all.
Because the two GridLayout panels have no content, they remain invisible. Add content to each or override getPreferredSize() in each to see the effect.
Construct and manipulate Swing GUI objects only on the event dispatch thread.
import java.awt.*;
import java.net.URL;
import javax.swing.*;
public class GUI {
private static final String TITLE = "Title";
private static ImageIcon IMAGE_ICON;
private void display() {
//Panels
JPanel topGridLayout = new JPanel(new GridLayout(1, 3));
JPanel botGridLayout = new JPanel(new GridLayout(1, 3));
JPanel backgroundPanel = new JPanel();
backgroundPanel.setBackground(Color.blue);
backgroundPanel.add(new JLabel(IMAGE_ICON));
//Frame
JFrame f = new JFrame(TITLE);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add components
f.add(topGridLayout, BorderLayout.NORTH);
f.add(backgroundPanel);
f.add(botGridLayout, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) throws Exception {
IMAGE_ICON = new ImageIcon(new URL("http://i.imgur.com/mowekvC.jpg"));
EventQueue.invokeLater(new GUI()::display);
}
}

Adding JPanels to a main Panel

So I have created three classes, the main method class, the Frame class and the JPanel class. Inside the JPanel class i would like to add three more JPanels, one at the top of the JFrame, one in the center and one at the bottom. My Code for the classes JPanel and JFrame are as follows:
JPanel:
public class ConcertPanel extends JPanel
{
public ConcertPanel()
{
JPanel ConcertPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
JPanel Panel1 = new JPanel();
Panel1.setSize(800,200);
Panel1.setBackground(Color.BLUE);
JPanel Panel2 = new JPanel();
Panel2.setSize(800,400);
Panel1.setBackground(Color.GREEN);
JPanel Panel3 = new JPanel();
Panel3.setSize(800,200);
Panel1.setBackground(Color.GRAY);
this.add(Panel1);
this.add(Panel2);
this.add(Panel3);
}
}
public class ConcertFrame extends JFrame
{
private ConcertPanel controlPane;
// The constructor
public ConcertFrame()
{
controlPane = new ConcertPanel() ;
this.add(controlPane);
....
When this project is ran, there are no errors showing up, but when the JFrame pops up it doesn't give me the three different colored panels within it but only a small grey box at the top. Can anyone tell me why or help?
One main problem is that the code does not take preferredSize nor layout managers into consideration.
The preferred sizes of all your color JPanels is 0,0, and setting the size does not affect this. Since they're being added to a JPanel who's default layout manager is FlowLayout, then the layout does not increase their sizes. So since most all layout managers respect preferred size and not actual size, and the FlowLayout doesn't change this, the JPanels are added, but are never seen.
Instead consider using other layouts for the main container such as GridLayout if all components have the same size, or BoxLayout, if all components are placed in a row or in a column. Consider overriding the getPreferredSize method as well but carefully and only if needed.
A "cheat" solution would be to change setSize(...) to setPreferredSize(new Dimensnion(...)), but that's frowned upon.
For example:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;
#SuppressWarnings("serial")
public class ColorPanels extends JPanel {
public ColorPanels() {
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(new ColorPanel(Color.BLUE, 800, 200));
add(new ColorPanel(Color.GREEN, 800, 400));
add(new ColorPanel(Color.GRAY, 800, 200));
}
private static class ColorPanel extends JPanel {
private int w;
private int h;
public ColorPanel(Color color, int w, int h) {
this.w = w;
this.h = h;
setBackground(color);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(w, h);
}
}
private static void createAndShowGui() {
ColorPanels mainPanel = new ColorPanels();
JFrame frame = new JFrame("ColorPanels");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

How to arrange components in a JFrame

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();
});
}
}

Adding JLabels to a Panel inside a Panel inside another Panel

I have one "main" panel. I'd like to have a "side" panel inside the main one. The side is composed of two other panels, let's call one graphicPanel and one supportPanel. I'm trying to add labels to the SupportPanel from the main one, but no changes happen.
Here is my side panel:
public class LateralSupportPane extends JPanel{
private final static int WIDTH = 240;
private final static int HEIGHT = 740;
private GraphicPanel gp;
private SupportPanel sp;
public LateralSupportPane(){
this.gp = new GraphicPanel();
this.sp = new SupportPanel();
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
this.setLayout(new GridLayout(2, 1));
//this.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(gp);
this.add(sp);
this.setVisible(true);
}
public void addLabel(String label){
sp.addLabel(label);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
gp.paintComponent(g);
}
public void addLabel(String label){
sp.addLabel(label);
}
Here my supportPanel:
public class SupportPanel extends JPanel{
private JLabel label;
private final static int WIDTH = 240;
private final static int HEIGHT = 370;
public SupportPanel(){
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
label = new JLabel();
label.setText("<html>BlaBla</html>");
this.setLayout(new GridLayout(10, 1));
this.add(label);
this.setVisible(true);
}
public JLabel getLabel() {
return label;
}
public void addLabel(String text){
JLabel label = new JLabel(text);
if(this.getComponentCount() < 10){
this.add(label);
} else {
this.remove(0);
this.add(label);
}
}
From the main panel I call the addLabel of the side panel.
EDIT: Here is the frame with all panels. The board itself is a panel added into a frame. The board also has another panel, that are the black rectangle and the area where the string is, together. Then the side panel is composed by 2 other panels, the GraphicPanel (the black rectangle) and the supportPanel, that is the area where I'd like to have my labels.
Board
Validating all panels made no progress.
Not sure if i undurstend it correctly, but it seams, that you have to validate your panels after inserting new label;
public static void main(String[] args) {
JFrame frame = new JFrame("test");
frame.setSize(900, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new CardLayout());
frame.setVisible(true);
LateralSupportPane p = new LateralSupportPane();
frame.add(p);
frame.validate();
p.addLabel("test 2");
p.validate();
}
as you see, after adding a label, validation is performed and object is painted on form.
your method addLabel(String label) should have this method called at end of it.

Categories