Java - JPanel and/ or its contents not showing - java

At the moment I'm trying to implement a GUI. Unfortunately I'm only getting a frame with a menuBar. The Panel and its content I defined do not show up.
I would appreciate any advice about why the panel and its content are not shown and what I did wrong (most likely in the initialiseLeftPanel() method).
What I have tried so far:
changed the position of setVisible(true);
included some revalidate()'s;
public class Codebreakerz {
private static GameRenderer renderer;
public static void main(String[] args) {
renderer = new GameRenderer();
}
public class GameRenderer extends JFrame {
private final String TITLE = "Codebreakerz";
private Image ICON = getToolkit().getImage("res/confused.png");
private final int WIDTH = 900;
private final int HEIGHT = 800;
private final int ROUNDS = 12;
private final Color BACKGROUND = Color.lightGray;
private JPanel left;
private JPanel right;
private JLabel attemptsLabel;
private JLabel correctLabel;
private JLabel rightNumbLabel;
private JLabel[] roundLabels;
public GameRenderer() {
initialiseWindow();
initialiseMenu()
initialiseLabels();
initialiseLeftPanel();
}
private void initialiseWindow() {
setTitle(TITLE);
setIconImage(ICON);
setSize(WIDTH, HEIGHT);
setLocationRelativeTo(null);
setResizable(false);
setLayout(null);
setVisible(true);
}
private void initialiseMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("Menu");
JMenuItem newGame = new JMenuItem("Neues Spiel");
JMenuItem close = new JMenuItem("Schließen");
file.add(newGame);
file.add(close);
menuBar.add(file);
setJMenuBar(menuBar);
}
private void initialiseLabels() {
attemptsLabel = new JLabel("0");
correctLabel = new JLabel("0");
rightNumbLabel = new JLabel("0");
roundLabels = new JLabel[ROUNDS];
for(int i=0; i<ROUNDS; i++) {
roundLabels[i] = new JLabel();
}
}
private void initialiseLeftPanel() {
left = new JPanel();
left.setLayout(null); // Tried other stuff aswell
JLabel heading = new JLabel("Codebreakerz");
JLabel tryNr = new JLabel("Anzahl Versuche: ");
JLabel correct = new JLabel("Richtig: ");
JLabel correctNumb = new JLabel("Richtige Nummer an falscher Stelle: ");
left.add(heading);
left.add(tryNr);
left.add(correct);
left.add(correctNumb);
add(left);
}
}

If you supress the line left.setLayout(null); in your method initialiseLeftPanel() and setLayout(null); in your method initialiseWindow() it will work.
You are obliged to have a Layout if you want display your panels. By default it uses a FlowLayout, but here you replaced it by null.

Related

Strange behavior when using JFileChooser

I've been making a Minesweeper clone in Java and everything has been going relatively well until I added support for saving and loading files. Saving and Loading the files works as intended, but the issue occurs when I load up the game, perform the initial click, and then exit. I'm presented with this error but it does not always occur:
Exception while removing reference.
If I never declare JFileChooser in the constructor, I never get the error. When I do get the error, it never prints the stack trace either or any information regarding it.
public class FileMenu extends JMenuBar implements ActionListener
{
private static final long serialVersionUID = 459585961076461945L;
private JFileChooser fileChooser;
private Path dir = Paths.get(".");
private File file;
private MineFrame frame;
private JMenuItem easy, medium, hard,loadItem, exitItem, saveItem;
private FileNameExtensionFilter filter;
private JMenu menu, newGameMenu;
private ObjectInputStream in;
private ObjectOutputStream out;
private FileDialog saveDialog;
public FileMenu(MineFrame frame)
{
super();
this.frame = frame;
exitItem = new JMenuItem("Quit Game");
saveItem = new JMenuItem("Save Game");
loadItem = new JMenuItem("Load Game");
easy = new JMenuItem("Beginner: 10 x 10. 10 Mines");
medium = new JMenuItem("Intermdiate: 16 x 16. 40 Mines");
hard = new JMenuItem("Expert: 16 x 30. 99 Mines");
fileChooser = new JFileChooser(dir.toString());
menu = new JMenu("File");
newGameMenu = new JMenu("New Game");
add(menu);
menu.add(newGameMenu);
menu.add(saveItem);
menu.add(loadItem);
menu.add(exitItem);
newGameMenu.add(easy);
newGameMenu.add(medium);
newGameMenu.add(hard);
easy.addActionListener(this);
medium.addActionListener(this);
hard.addActionListener(this);
saveItem.addActionListener(this);
loadItem.addActionListener(this);
exitItem.addActionListener(this);
}
This is the only location where the call to FileMenu() occurs
public class MineFrame extends JFrame
{
private static final long serialVersionUID = 4816731330494815932L;
private MineBoard board;
private JLabel mineLabel;
private MinePanel minePanel;
private JPanel fileBarPanel, mainPanel, labelPanel;
private FileMenu menu;
private BorderLayout layout;
public MineFrame(MineBoard board)
{
super("Minesweeper Java");
this.board = board;
fileBarPanel = new JPanel();
mainPanel = new JPanel();
labelPanel = new JPanel();
menu = new FileMenu(this);
layout = new BorderLayout();
mineLabel = new JLabel();
minePanel = new MinePanel(this);
labelPanel.add(mineLabel);
labelPanel.setBackground(Color.WHITE);
mineLabel.setForeground(Color.RED);
mineLabel.setFont(new Font("Times", Font.BOLD, 20));
fileBarPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
fileBarPanel.add(menu);
minePanel.setBackground(Color.WHITE);
mainPanel.setLayout(new GridLayout(2, 1));
mainPanel.add(fileBarPanel);
mainPanel.add(labelPanel);
setLayout(layout);
add(mainPanel, BorderLayout.NORTH);
add(minePanel, BorderLayout.CENTER);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBackground(Color.WHITE);
setVisible(true);
setResizable(false);
setSize(500,500);
}
Interestingly enough, the error does not occur with FileDialog. I've searched google for it extensively and it's seemingly rare.
UPDATE Moving the object into the actionPerformed method did the trick somehow!

Switch Between JPanels With Use of JButton?

Trying to make flashcard application. The JButton b_switchmode will be used to switch between panels (an edit mode and a test mode, both have panels created for separate use). Not quite sure how to go from the GUI I've created. Ideally I would click the JButton b_switchmode and I would be able to switch from "Edit Mode" to "Test Mode".
I'm aware that a CardLayout may be needed but I'm unable to implement the correct syntax to make the program executable.
So I want to know how to:
insert CardLayout to be able to switch between JPanels
allow JButton b_switchmode to execute the switch between JPanels
public class App2 {
private static JFrame frame;
private static JPanel editpanel;
private static JPanel testpanel;
private static JLabel l_appmode;
private static JLabel l_number;
private static JLabel l_question;
private static JLabel l_answer;
public static JTextField t_questions;
public static JTextField t_answer;
public static JButton b_switchmode;
public static JButton b_previous;
public static JButton b_next;
public static JButton b_add;
public static JButton b_save;
public static JButton b_question;
public static JButton b_answer;
static int width = 600;
static int height = 450;
public static void main(String[] args) {
// TODO Auto-generated method stub
gui();
}
private static void gui(){
frame = new JFrame("Assignment2");
frame.setTitle("Flash Cards");
frame.setSize(width,height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
l_appmode = new JLabel("Current Mode: Edit");
l_number = new JLabel ("");
l_question = new JLabel("Question:");
l_answer = new JLabel("Answer:");
t_questions = new JTextField("");
t_answer = new JTextField("");
b_switchmode = new JButton("Switch Mode");
b_previous = new JButton("Previous");
b_next = new JButton("Next");
b_add = new JButton("Add");
b_save = new JButton("Save");
b_question = new JButton("Question");
b_answer = new JButton("Answer");
editpanel = new JPanel();
int rows = 6, columns = 1;
int hgap = 20; int vgap = 20;
editpanel.setLayout(new GridLayout(rows, columns, hgap,
vgap));
editpanel.add(l_appmode);
editpanel.add(l_number);
editpanel.add(l_question);
editpanel.add(t_questions);
editpanel.add(l_answer);
editpanel.add(t_answer);
editpanel.add(b_switchmode);
editpanel.add(b_previous);
editpanel.add(b_next);
editpanel.add(b_add);
editpanel.add(b_save);
//testpanel.add(b_question);
//testpanel.add(t_questions);
//testpanel.add(b_answer);
//testpanel.add(t_answer);
frame.add(editpanel);
//frame.add(testpanel);
frame.setVisible(true);
}

Can't seem to update my GridLayout in my JFrame. Right now it adds more and more to the frame and I just want to update it

So this is my runner that runs my entire game. CharacterGame, CharacterChoice and CharacterHead are all classes that contain graphics and paint. I was hoping to be able to call separate parts from these classes into the graphics by the remove and repaint located in one of my button's code. Right now its just updating the Frame with more and more panels instead of removing the old panels and adding these panels into the old panels place. I hope this makes sense as I am a bit new to graphics and may not have thought of the best way to do this. If anyone can shed some light into how to do this, I will be very grateful. Thanks! I've tried everything I can think of... from removeAll methods to repaint. I can't think of anything else to do.
The part not working is located in the ShowButtonDemo() in the choice1Button listener.
public class GraphicsRunner extends JFrame
{
private static final int WIDTH = 1280;
private static final int HEIGHT = 980;
private JFrame mainframe;
private JPanel controlPanel;
private JPanel headPanel;
private JPanel gamePanel;
private JPanel choicePanel;
private int gameInt = 0;
private int choiceInt = 0;
private int endGame = 0;
public GraphicsRunner()
{
super("Stranded...");
mainframe = new JFrame();
mainframe.setBackground(Color.BLACK);
mainframe.setSize(WIDTH,HEIGHT);
mainframe.setLayout(new GridLayout(4, 0));
mainframe.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
headPanel = new JPanel();
gamePanel = new JPanel();
choicePanel = new JPanel();
controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
headPanel = new CharacterHeading();
gamePanel = new CharacterGame(gameInt);
choicePanel = new CharacterChoice(choiceInt);
mainframe.add(headPanel);
mainframe.add(gamePanel);
mainframe.add(choicePanel);
mainframe.add(controlPanel);
mainframe.setDefaultCloseOperation(EXIT_ON_CLOSE);
mainframe.setVisible(true);
}
public static void main( String args[] )
{
GraphicsRunner run = new GraphicsRunner();
run.showButtonDemo();
}
private void showButtonDemo(){
JButton choice1Button = new JButton("Choice #1");
JButton choice2Button = new JButton("Choice #2");
JButton choice3Button = new JButton("Choice #3");
choice3Button.setHorizontalTextPosition(SwingConstants.LEFT);
choice1Button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
gameInt = gameInt + 1;
choiceInt = choiceInt + 1;
gamePanel = new CharacterGame(gameInt);
//This is the part I am currently working on and I was hoping
//it would remove the panel instead of just removing the
//content on the panel...
mainframe.remove(headPanel);
mainframe.remove(gamePanel);
mainframe.remove(choicePanel);
mainframe.remove(controlPanel);
mainframe.add(headPanel, 0);
mainframe.add(gamePanel, 1);
mainframe.add(choicePanel, 2);
mainframe.add(controlPanel, 3);
mainframe.revalidate();
mainframe.repaint();
System.out.println(gameInt);
}
});
controlPanel.setBackground(Color.BLACK);
controlPanel.add(choice1Button);
controlPanel.add(choice2Button);
controlPanel.add(choice3Button);
mainframe.setVisible(true);
}
}

How do I get the JLabel to show which button has been selected

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.*;
public class filecabinet extends JFrame implements ActionListener {
private String folder = "";
//create buttons
private JButton a = new JButton("A");
private JButton b = new JButton("B");
private JButton c = new JButton("C");
private JButton d = new JButton("D");
private JButton e = new JButton("E");
private JButton f = new JButton("F");
private JButton g = new JButton("G");
private JButton h = new JButton("H");
private JButton i = new JButton("I");
private JButton j = new JButton("J");
private JButton k = new JButton("K");
private JButton l = new JButton("L");
private JButton m = new JButton("M");
private JButton n = new JButton("N");
private JButton o = new JButton("O");
private JButton p = new JButton("P");
private JButton q = new JButton("Q");
private JButton r = new JButton("R");
private JButton s = new JButton("S");
private JButton t = new JButton("T");
private JButton u = new JButton("U");
private JButton v = new JButton("V");
private JButton w = new JButton("W");
private JButton x = new JButton("X");
private JButton y = new JButton("Y");
private JButton z = new JButton("Z");
//create panels
private JPanel aF = new JPanel();
private JPanel gL = new JPanel();
private JPanel mR = new JPanel();
private JPanel sX = new JPanel();
private JPanel yZ = new JPanel();
private JPanel readout = new JPanel();
private JLabel notify = new JLabel("You have selected folder " + folder);
public void ComposePane(){
//set buttons to panels
aF.add(a);
aF.add(b);
aF.add(c);
aF.add(d);
aF.add(e);
aF.add(f);
//set layout of panels
aF.setLayout(new GridLayout(2,3));
gL.add(g);
gL.add(h);
gL.add(i);
gL.add(j);
gL.add(k);
gL.add(l);
gL.setLayout(new GridLayout(2,3));
mR.add(m);
mR.add(n);
mR.add(o);
mR.add(p);
mR.add(q);
mR.add(r);
mR.setLayout(new GridLayout(2,3));
sX.add(s);
sX.add(t);
sX.add(u);
sX.add(v);
sX.add(w);
sX.add(x);
sX.setLayout(new GridLayout(2,3));
yZ.add(y);
yZ.add(z);
yZ.add(readout);
readout.add(notify);
yZ.setLayout(new GridLayout(2,3));
}
public filecabinet(){
setTitle("File Cabinet");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(5,1));
ComposePane();
add(aF);
add(gL);
add(mR);
add(sX);
add(yZ);
addActionListener();
}
public void actionPerformed(ActionEvent e) {
folder = ((JButton) e.getSource()).getText();
}
public void addActionListener(){
a.addActionListener(this);
b.addActionListener(this);
c.addActionListener(this);
d.addActionListener(this);
e.addActionListener(this);
f.addActionListener(this);
g.addActionListener(this);
h.addActionListener(this);
i.addActionListener(this);
j.addActionListener(this);
k.addActionListener(this);
l.addActionListener(this);
m.addActionListener(this);
n.addActionListener(this);
o.addActionListener(this);
p.addActionListener(this);
q.addActionListener(this);
r.addActionListener(this);
s.addActionListener(this);
t.addActionListener(this);
u.addActionListener(this);
v.addActionListener(this);
w.addActionListener(this);
x.addActionListener(this);
y.addActionListener(this);
z.addActionListener(this);
}
public static void main(String[]args){
filecabinet frame = new filecabinet();
final int WIDTH = 600;
final int HEIGHT = 600;
frame.setSize(WIDTH, HEIGHT);
frame.setVisible(true);
}
}
I would prefer not to have to write out a listener for every button
and I was wandering if I could just get the text contained in the button.
such as "You have selected foler X", X is the button chosen.
Again, either use arrays and/or a for loop to consolidate your code getting rid of code redundancy. For example:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class FileCabinet2 extends JPanel {
public static final char FIRST_LETTER = 'A';
public static final char LAST_LETTER = 'Z';
private static final float lARGE_FONT_POINTS = 32f;
private static final int GRID_COLS = 3;
private JLabel chosenLabel = new JLabel();
public FileCabinet2() {
JPanel letterPanel = new JPanel(new GridLayout(0, GRID_COLS));
ActionListener btnListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
chosenLabel.setText(evt.getActionCommand());
}
};
for (char c = FIRST_LETTER; c <= LAST_LETTER; c++) {
String buttonTitle = String.valueOf(c);
JButton button = new JButton(buttonTitle);
setFontPoints(button, lARGE_FONT_POINTS);
letterPanel.add(button);
button.addActionListener(btnListener);
}
JLabel selectionLabel = new JLabel("Selection: ", SwingConstants.RIGHT);
setFontPoints(selectionLabel, lARGE_FONT_POINTS);
setFontPoints(chosenLabel, lARGE_FONT_POINTS);
JPanel bottomPanel = new JPanel(new GridLayout(1, 0));
bottomPanel.add(selectionLabel);
bottomPanel.add(chosenLabel);
bottomPanel.setBorder(BorderFactory.createEtchedBorder());
setLayout(new BorderLayout());
add(letterPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private void setFontPoints(JComponent jComp, float points) {
jComp.setFont(jComp.getFont().deriveFont(points));
}
private static void createAndShowGui() {
FileCabinet2 mainPanel = new FileCabinet2();
JFrame frame = new JFrame("File Cabinet");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Now if you want to change how many button columns there are, all you need to do is change one constant, GRID_COLS, and the same for the size of the font, just change LARGE_FONT_POINTS.
For this:
would prefer not to have to write out a listener for every button
Create a method that accept the JPanel as the parameter and then iterate to each component in JPanel, add the action listener if the component is JButton
This one:
I was wandering if I could just get the text contained in the button.
Just set the value in the JLabel. You already get the button content right?
So, the full code is:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.*;
public class filecabinet extends JFrame implements ActionListener {
private String folder = "";
// create buttons
private JButton a = new JButton("A");
private JButton b = new JButton("B");
private JButton c = new JButton("C");
private JButton d = new JButton("D");
private JButton e = new JButton("E");
private JButton f = new JButton("F");
private JButton g = new JButton("G");
private JButton h = new JButton("H");
private JButton i = new JButton("I");
private JButton j = new JButton("J");
private JButton k = new JButton("K");
private JButton l = new JButton("L");
private JButton m = new JButton("M");
private JButton n = new JButton("N");
private JButton o = new JButton("O");
private JButton p = new JButton("P");
private JButton q = new JButton("Q");
private JButton r = new JButton("R");
private JButton s = new JButton("S");
private JButton t = new JButton("T");
private JButton u = new JButton("U");
private JButton v = new JButton("V");
private JButton w = new JButton("W");
private JButton x = new JButton("X");
private JButton y = new JButton("Y");
private JButton z = new JButton("Z");
// create panels
private JPanel aF = new JPanel();
private JPanel gL = new JPanel();
private JPanel mR = new JPanel();
private JPanel sX = new JPanel();
private JPanel yZ = new JPanel();
private JPanel readout = new JPanel();
private JLabel notify = new JLabel("You have selected folder " + folder);
public void ComposePane() {
// set buttons to panels
aF.add(a);
aF.add(b);
aF.add(c);
aF.add(d);
aF.add(e);
aF.add(f);
// set layout of panels
aF.setLayout(new GridLayout(2, 3));
gL.add(g);
gL.add(h);
gL.add(i);
gL.add(j);
gL.add(k);
gL.add(l);
gL.setLayout(new GridLayout(2, 3));
mR.add(m);
mR.add(n);
mR.add(o);
mR.add(p);
mR.add(q);
mR.add(r);
mR.setLayout(new GridLayout(2, 3));
sX.add(s);
sX.add(t);
sX.add(u);
sX.add(v);
sX.add(w);
sX.add(x);
sX.setLayout(new GridLayout(2, 3));
yZ.add(y);
yZ.add(z);
yZ.add(readout);
readout.add(notify);
yZ.setLayout(new GridLayout(2, 3));
}
public filecabinet() {
setTitle("File Cabinet");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(5, 1));
ComposePane();
add(aF);
add(gL);
add(mR);
add(sX);
add(yZ);
addActionListener(aF);
addActionListener(gL);
addActionListener(mR);
addActionListener(sX);
addActionListener(yZ);
}
public void actionPerformed(ActionEvent e) {
folder = ((JButton) e.getSource()).getText();
// set the label with folder value
notify.setText("You have selected folder " + folder);
}
// Attach event handler to each JButton in JPanel
public void addActionListener(JPanel panel) {
Component[] components = panel.getComponents();
for (Component component : components) {
if (component instanceof JButton) {
((JButton) component).addActionListener(this);
}
}
}
public static void main(String[] args) {
filecabinet frame = new filecabinet();
final int WIDTH = 600;
final int HEIGHT = 600;
frame.setSize(WIDTH, HEIGHT);
frame.setVisible(true);
}
}
A quick review of your code, brought your code down to this length.
Imagine, what you can achieve if you give it a bit more insight.
Furthermore, when you see that in your code, you are repeating some
lines again and again for the same thingy, you can indeed think of a
pattern that can accomplish that for you in a rightful manner, with
fewer keystrokes.
Try this modified code of yours :-)
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.*;
public class Filecabinet extends JFrame implements ActionListener {
private String folder = "";
//create buttons
private JButton[] button = new JButton[26];
//create panels
private JPanel aF = new JPanel();
private JPanel gL = new JPanel();
private JPanel mR = new JPanel();
private JPanel sX = new JPanel();
private JPanel yZ = new JPanel();
private JPanel readout = new JPanel();
private JLabel notify = new JLabel("You have selected folder " + folder);
public void ComposePane(){
init_Buttons(button);
//set buttons to panels
for (int i = 0; i < 6; i++)
aF.add(button[i]);
//set layout of panels
aF.setLayout(new GridLayout(2,3));
for (int i = 6; i < 12; i++)
gL.add(button[i]);
gL.setLayout(new GridLayout(2,3));
for (int i = 12; i < 18; i++)
mR.add(button[i]);
mR.setLayout(new GridLayout(2,3));
for (int i = 18; i < 24; i++)
sX.add(button[i]);
sX.setLayout(new GridLayout(2,3));
for (int i = 24; i < 26; i++)
yZ.add(button[i]);
yZ.add(readout);
readout.add(notify);
yZ.setLayout(new GridLayout(2,3));
}
private void init_Buttons(JButton[] button)
{
int value = 65;
for (int i = 0; i < button.length; i++)
{
button[i] = new JButton(Character.toString((char) value++));
button[i].addActionListener(this);
}
}
public Filecabinet(){
setTitle("File Cabinet");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(5,1));
ComposePane();
add(aF);
add(gL);
add(mR);
add(sX);
add(yZ);
}
public void actionPerformed(ActionEvent e) {
folder = ((JButton) e.getSource()).getText();
notify.setText(folder);
}
public static void main(String[]args){
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
Filecabinet frame = new Filecabinet();
final int WIDTH = 600;
final int HEIGHT = 600;
//frame.setSize(WIDTH, HEIGHT);
frame.pack();
frame.setVisible(true);
}
});
}
}
You can subclass JButton and write a constructor for the subclass that takes in as a parameter a reference to the action listener, your JFrame.
For instance, your subclass could simply be:
public class YourButton extends JButton {
public YourButton(String title, ActionListener listener) {
super(title);
this.addActionListener(listener);
}
}
So instead of:
private JButton a = new JButton("A");
You would call:
private YourButton a = new YourButton("A", this);
Additionally, as others have suggested, your actionPerformed(ActionEvent e) method requires you to update your notify JLabel instance to reflect the selected button's title.
Hope that helps!

JPanel disappearing from window

The SSCCE below is a class that extends JPanel. The JPanel is the basic outline of a calendar (I've stripped it way down for simplicity's sake), and it consists of JButton components, a JLabel, and a JTable. When I add this frame to a window (i.e. JDialog), it appears as normal. However, when I add another component with it, it disappears. Why is this happening, and how can I make this not happen?
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
public class CalendarPanel extends JPanel {
private static JDialog dialog = new JDialog();
public static void main(String[] args) {
setDialogProperties();
addComponentsToDialog();
dialog.setVisible(true);
}
private static void setDialogProperties() {
dialog.setModal(true);
dialog.setResizable(false);
dialog.setSize(new Dimension(330, 400));
dialog.setDefaultCloseOperation(2);
dialog.setLocationRelativeTo(null);
}
private static void addComponentsToDialog() {
CalendarPanel calendar = new CalendarPanel();
JPanel panel = new JPanel();
panel.add(calendar);
dialog.add(panel);
//dialog.add(new JLabel("Hello"));
}
private static final long serialVersionUID = 1L;
private JLabel lblMonth;
private JButton btnPrev, btnNext;
private JTable tblCalendar;
private DefaultTableModel mtblCalendar;
private JScrollPane stblCalendar;
private static GridBagLayout gridBag = new GridBagLayout();
private GridBagConstraints constraints = new GridBagConstraints();
public CalendarPanel() {
super(gridBag);
createControls();
addControlsToPanel();
addHeaders();
setTableProperties();
}
private void createControls() {
lblMonth = new JLabel("January");
btnPrev = new JButton("<");
btnNext = new JButton(">");
mtblCalendar = new DefaultTableModel() {
public boolean isCellEditable(int rowIndex, int mColIndex) {
return false;
}
};
tblCalendar = new JTable(mtblCalendar);
stblCalendar = new JScrollPane(tblCalendar);
stblCalendar.setPreferredSize(new Dimension(300, 247));
}
private void addControlsToPanel() {
GridBagLayout topGridBag = new GridBagLayout();
JPanel topPanel = new JPanel(topGridBag);
JPanel labelPanel = new JPanel();
labelPanel.add(lblMonth);
labelPanel.setPreferredSize(new Dimension(180, 20));
constraints.gridx = 1;
topGridBag.setConstraints(labelPanel, constraints);
constraints.gridx = 2;
topGridBag.setConstraints(btnNext, constraints);
topPanel.add(btnPrev);
topPanel.add(labelPanel);
topPanel.add(btnNext);
gridBag.setConstraints(topPanel, constraints);
constraints.gridy = 1;
gridBag.setConstraints(stblCalendar, constraints);
this.add(topPanel);
this.add(stblCalendar);
}
private void addHeaders() {
String[] headers = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
for (int i = 0; i < 7; i++) {
mtblCalendar.addColumn(headers[i]);
}
}
private void setTableProperties() {
tblCalendar.getTableHeader().setReorderingAllowed(false);
tblCalendar.setRowHeight(38);
mtblCalendar.setColumnCount(7);
mtblCalendar.setRowCount(6);
}
}
JDialogs and all top-level windows use BorderLayout by default. When you add a component to it (actually its contentPane) without specifying the position, you add it to the BorderLayout.CENTER position by default. You are covering up the previously added component whenever you add a new one. You will want to learn about the layouts available for your use and then use them to their best advantage.
e.g.,
dialog.add(panel);
dialog.add(new JLabel("Hello", SwingConstants.CENTER), BorderLayout.SOUTH);
}
Next you'll want to avoid setting the sizes of anything and to be sure to pack() your top level windows that allow this.

Categories

Resources