I have a game of chess.
I have written 3 classes.
1st if for game. (chessboard, pieces, and so on)
And another one is for menu. (buttons like new, open, set time)
Both of them use JFrame.
I would like to put both classes mentioned above into the 3rd class. For example the Game window would be on the left, and the menu on the right.
The third class would also show the whole app by JFrame.
How to do that?
You can't put one JFrame inside another. You have a couple of design choices here. You can change your JFrames to JPanels. This is probably the easiest change. On the other hand, you can look at using Internal Frames instead.
In your case i suggest you to use JInternalFrame which can be added inside Jframe try out this code i hope it will work:
package demo;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
public class Demo {
public static void main(String[] args) {
JFrame jf=new JFrame();
jf.setLayout(null);
jf.setSize(1280, 720);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JInternalFrame jInternalFrame=new JInternalFrame();
jInternalFrame.setLocation(100, 100);
jInternalFrame.setSize(500, 300);
jInternalFrame.setTitle("Internal frame");
jInternalFrame.setVisible(true);
jInternalFrame.setClosable(true);
jInternalFrame.setResizable(true);
jf.add(jInternalFrame);
jf.repaint();
}
}
You can use JPanels for that. It's easier that way... use a JFrame for the main window and for menu items use a JPanel inside it. Search for tutorials on JPanel usage.
The best thing to do would be to leave the outer frame as it is and change the inner contents to JPanels. When I wrote Chess, I had an outer frame which extended JFrame, and inner panel that extended JPanel on which I placed the board. The board itself was comprised of 64 JButtons.
Given your description, I think this would be a good starting point:
package data_structures;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Chess extends JFrame implements ActionListener {
private JButton[][] tiles;
public Chess() {
setTitle("Chess");
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(new BorderLayout());
JPanel board = new JPanel();
board.setLayout(new GridLayout(8, 8));
tiles = new JButton[8][8];
for(int y = 0; y < tiles.length; y++) {
for(int x = 0; x < tiles[y].length; x++) {
tiles[x][y] = new JButton();
tiles[x][y].setActionCommand(x + " " + y);
tiles[x][y].addActionListener(this);
board.add(tiles[x][y]);
}
}
add(board, BorderLayout.CENTER);
JPanel options = new JPanel();
options.setLayout(new GridLayout(1, 3));
JButton newGame = new JButton("New");
newGame.addActionListener(this);
options.add(newGame);
JButton openGame = new JButton("Open");
openGame.addActionListener(this);
options.add(openGame);
JButton setTime = new JButton("Set Time");
setTime.addActionListener(this);
options.add(setTime);
add(options, BorderLayout.SOUTH);
revalidate();
}
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
System.out.println(command);
revalidate();
}
public static void main(String[] args) {
new Chess();
}
}
Also, a word of warning:
Fully implementing the logic of Chess is very difficult, no matter what you do for the graphics.
Hope this helps!
I guess that's what you want to do.
public class OuterFrame extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
OuterFrame outerFrame = new OuterFrame();
outerFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public OuterFrame() {
JFrame innerFrame = new JFrame();
innerFrame.setVisible(true);
}
}
You have a MainFrame (OuterFrame), and you create it. But, you create a JFrame inside this MainFrame. That's not a beautiful thing to do, but it's certainly a way of opening a "JFrame inside the other". This will give you two "windows" on the screen. You could create countless JFrames inside the MainFrame.
Related
I am trying to create this layout
for a project using Swing in Java 8, but since Swing is something I have never learned I am really struggling with trying to get the layout set up. I've tried my best but I just do not understand this. I don't think I will have any trouble with the backend functionality of the window I just can't get it to look the way I need it.
A common strategy to solve complex computing tasks, is to break them into small, well defined manageable tasks. Divide and conquer.
This also applies to gui: break the design into small, easy to layout containers.
In this case, consider dividing the design into 4 areas (JPanels) nested in a main JPanel:
This basic layout, that can get you started, can be achieved like so:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Gui {
private final String text ="Growing ";
private JPanel grid;
private JFrame f;
Gui() {
creategui();
}
void creategui(){
f = new JFrame("Hexagon Cross For Less");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.setLayout(new BoxLayout(f.getContentPane(),BoxLayout.Y_AXIS));
JPanel primes = new JPanel();
primes.setPreferredSize(new Dimension(1000,120));
primes.setBackground(Color.CYAN);
f.add(primes);
JPanel xFiles = new JPanel();
xFiles.setPreferredSize(new Dimension(1000,120));
xFiles.setBackground(Color.YELLOW);
f.add(xFiles);
JPanel actions = new JPanel();
actions.setPreferredSize(new Dimension(1000,120));
actions.setBackground(Color.GREEN);
f.add(actions);
JPanel status = new JPanel();
status.setPreferredSize(new Dimension(1000,40));
status.setBackground(Color.LIGHT_GRAY);
f.add(status);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new Gui();
}
}
it produces the following layout:
It can be better structured by representing each such distinct area (JPanel) in a separate class.
The following code produces exactly the same layout (it is a single-file mre. Copy past it to Gui.java and run):
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Gui {
private final String text ="Growing ";
private JPanel grid;
private JFrame f;
Gui() {
creategui();
}
void creategui(){
f = new JFrame("Hexagon Cross For Less");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.add(new MainPane());
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new Gui();
}
}
class MainPane extends JPanel{
MainPane() {
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
add(new Primes());
add(new CrossFiles());
add(new Actions());
add(new Status());
}
}
class Primes extends JPanel{
Primes() {
setPreferredSize(new Dimension(1000,120));
setBackground(Color.CYAN);
}
}
class CrossFiles extends JPanel{
CrossFiles() {
setPreferredSize(new Dimension(1000,120));
setBackground(Color.YELLOW);
}
}
class Actions extends JPanel{
Actions() {
setPreferredSize(new Dimension(1000,120));
setBackground(Color.GREEN);
}
}
class Status extends JPanel{
Status() {
setPreferredSize(new Dimension(1000,40));
setBackground(Color.LIGHT_GRAY);
}
}
To continue, apply the same technique and define the layout of each of the 4 sub panels.
The design of Actions could be :
Hint: Primes and CrossFiles have exactly the same layout.
I have 2 jframes, 1 is kinda like the main menu, i want an attribute to change in the level jframe when a button is pressed so i tried:
SpeelVeld frame = new SpeelVeld();
frame.level = 1;
System.out.println(frame.level);
I used the sout to see what really happens because it wasnt working, but i see that the level goes from 0 to 1 back to 0 and goes on and on, does someone know why and how to fix?
SpeelVeld frame = new SpeelVeld();
frame.setBounds(0,0,519,591);
frame.setLocationRelativeTo(null);
frame.getContentPane().setBackground(Color.WHITE);
frame.setTitle("RWINA");
frame.setVisible(true);
frame.setLevel(1);
this is in the main method of my original GameProject file.
How can i make a jdialog
I have 2 jframes, 1 is kinda like the main menu,
You shouldn't use 2 JFrames for this. The dependent sub-window, likely your main menu window, should in fact be a JDialog, probably a non-modal dialog from the looks of it.
I want an attribute to change in the level jframe when a button is pressed so i tried:
SpeelVeld frame = new SpeelVeld();
frame.level = 1;
System.out.println(frame.level);
and here's a big problem. Understand that in this code, you're creating a new SpeelVeld object, the stress being on the word new. Changing the state of this object will have no effect on the other SeelVeld object that is currently being displayed. Do do that, your second window will need a valid reference to the displayed SeelVeld object. How to do this will depend all on code not yet shown, but often it can be done simply by passing in the displayed SpeelVeld object into the main menu object by use of a constructor parameter or setter method.
For example:
import java.awt.Dialog.ModalityType;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
// JPanel for our main GUI
public class SpeelVeldFoo {
private static void createAndShowGui() {
// JPanel used by the main JFrame
SpeelVeldPanel speelVeldPanel = new SpeelVeldPanel();
// JPanel used by the main menu JDialog. Pass the above into it
MainMenuPanel mainMenuPanel = new MainMenuPanel(speelVeldPanel);
// create your JFrame
JFrame frame = new JFrame("Speel Veld");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(speelVeldPanel); // add the JPanel
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
// create your non-modal JDialog
JDialog menuDialog = new JDialog(frame, "Main Menu", ModalityType.MODELESS);
menuDialog.add(mainMenuPanel); // add the JPanel that holds its "guts"
menuDialog.pack();
menuDialog.setLocationByPlatform(true);
menuDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
#SuppressWarnings("serial")
class SpeelVeldPanel extends JPanel {
private int level = 1; // simple example just has a level int
private JLabel levelLabel = new JLabel("1"); // and displays it in a JLabel
public SpeelVeldPanel() {
add(new JLabel("Level:"));
add(levelLabel);
int ebGap = 50;
setBorder(BorderFactory.createEmptyBorder(ebGap, 2 * ebGap, ebGap, 2 * ebGap));
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
// whenever level is changed, update the display
this.level = level;
levelLabel.setText(String.valueOf(level));
}
}
// class for the JPanel held by the JDialog
#SuppressWarnings("serial")
class MainMenuPanel extends JPanel {
private JSpinner levelSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 5, 1));
private SpeelVeldPanel speelVeldPanel = null; // reference to the main GUI
// note the parameter.... you pass in the displayed main GUI so you can
// change it
public MainMenuPanel(final SpeelVeldPanel speelVeldPanel) {
this.speelVeldPanel = speelVeldPanel; // set the field
// respond when the spinner's data changes
levelSpinner.addChangeListener(new LevelListener());
add(new JLabel("Set the Speel Veld's level:"));
add(levelSpinner);
int ebGap = 10;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
}
private class LevelListener implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
// when the spinner's data changes
int level = (int) levelSpinner.getValue(); // get the data
speelVeldPanel.setLevel(level); // and send it to the main GUI
}
}
}
You'll note that I don't like extending JFrame or JDialog if I can avoid it. My feeling is that one can paint oneself into a corner by having your class extend JFrame, forcing you to create and display JFrames, when often more flexibility is called for. More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. This will greatly increase the flexibility of your GUI coding.
You probably want the JFrame to be the top-level container, then have a JPanel that holds your menu. The menu could be whatever you want, I'm using a JTextArea. Then, you need a JButton for the JPanel or JFrame that when pressed, changes the text in the JTextArea. Here is an implementation that you could work from. I'm using the ActionEvent as the trigger for when to mess with the JTextArea:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class SimpleSwing {
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
JPanel mainMenuPanel = new JPanel();
JTextArea textAttribute = new JTextArea("Original Text");
JButton changeAttributeButton = new JButton("Change Attribute");
changeAttributeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textAttribute.setText("Whatever new text you want");
}
});
mainMenuPanel.add(textAttribute);
mainMenuPanel.add(changeAttributeButton);
mainFrame.add(mainMenuPanel);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(500, 500);
mainFrame.setVisible(true);
}
}
I am trying to build a little program that has a main GUI with 2 buttons. One button closes the program, the other I want to open a new JPanel that will have text fields etc.
I would like to be able to make the buttons so they look like normal application buttons I guess, nice and square, equal size etc. etc., I am not sure how to do this though.
Also, I am unsure how to open a new JFrame from a button click.
GUI Code:
package practice;
public class UserInterface extends JFrame {
private JButton openReportSelection = new JButton("Open new Window");
private JButton closeButton = new JButton("Close Program");
private JButton getCloseButton() {
return closeButton;
}
private JButton getOpenReportSelection() {
return openReportSelection;
}
public UserInterface() {
mainInterface();
}
private void mainInterface() {
setTitle("Program Information Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel centerPanel = new JPanel(new GridLayout(0, 3));
centerPanel.add(openReportSelection);
centerPanel.add(closeButton);
getCloseButton().addActionListener(new Listener());
add(centerPanel, BorderLayout.CENTER);
setSize(1000, 200);
setVisible(true);
}
private void addReportPanel() {
JPanel reportPanel = createNewPanel();
getContentPane().add(reportPanel, BorderLayout.CENTER);
}
private JPanel createNewPanel() {
JPanel localJPanel = new JPanel();
localJPanel.setLayout(new FlowLayout());
return localJPanel;
}
}
ActionListener Class code:
package practice;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Listener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
}
EDIT: I think opening a new JPanel would be the way to go rather than a JFrame. What would be the best way to do this from a Jbutton click?
Start by using a different layout manager, FlowLayout or GridBagLayout might work better
JPanel centerPanel = new JPanel(new FlowLayout());
centerPanel.add(openReportSelection);
centerPanel.add(closeButton);
These layouts will honour the preferred sizes of your buttons
As for opening another window, well, you've already create one, so the process is pretty much the same. Having said that, you might consider having a look at The Use of Multiple JFrames: Good or Bad Practice? before you commit yourself to far.
A better approach might be to use a JMenuBar and JMenuItems to act as the "open" and "exit" actions. Take a look at How to Use Menus then you could use a CardLayout to switch between views instead, for example
From a pure design perspective (I know it's only practice, but perfect practice makes perfect), I wouldn't extend anything from JFrame and instead would rely on building your main GUIs around something like JPanel instead.
This affords you the flexibility to decide how to use these components, as you could add them to frames, applets or other components...
If you want your buttons to have the native Look and Feel (L&F), add the following to your program:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Instead of opening another JFrame, you'll want to instead use a JDialog, typically with modality set.
In Java, you can only extend one class and therefore you should consider carefully whether it is appropriate or not to extend another class. You could ask yourself, "Am I actually extending the functionality of JFrame?" If the answer is no, then you actually want to use an instance variable.
Below is an example program from the above recommendations:
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class MyApplication {
private JFrame myframe; // instance variable of a JFrame
private JDialog mydialog;
public MyApplication() {
super();
myframe = new JFrame(); // instantiation
myframe.setSize(new Dimension(400, 75));
myframe.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
JButton btnNewWindow = new JButton("Open New Window");
btnNewWindow.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mydialog = new JDialog();
mydialog.setSize(new Dimension(400,100));
mydialog.setTitle("I got you! You can't click on your JFrame now!");
mydialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); // prevent user from doing something else
mydialog.setVisible(true);
}
});
myframe.getContentPane().add(btnNewWindow);
JButton btnCloseProgram = new JButton("Close Program :(");
btnCloseProgram.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
myframe.dispose();
}
});
myframe.getContentPane().add(btnCloseProgram);
myframe.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MyApplication();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
I am not sure from your question what do wou want to do. Do you want to open a new JFrame or do you want to add a JPanel to the existing frame.
To open a new JFrame using a button, create an instance of the JFrame in the actionPerformed method of the button. In your case it would look similar to this:
openReportSelection.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JFrame frame = new JFrame();
// Do something with the frame
}
}
});
You're probably looking up to create and open a new JFrame. For this purpose, first you need to instantiate an object from JFrame Class. As an example, Let's instantiate a new JFrame with specific boundries.
JFrame testFrame = new testFrame();
verificationFrame.setBounds(400, 100, 250, 250);
Then you need to create your components like JButtons, Jlabels and so on, and next you should add them to your new testFrame object.
for example, let's create a Jlabel and add it testFrame:
JLabel testLbl = new JLabel("Ok");
testLbl.setBounds(319, 49, 200, 30);
testFrame.getContentPane().add(testLbl);
Now let's suppose you have a Jbutton which is named "jbutton" and by clicking it, a new JFrame object will be created and the Jlabel component will be added to it:
jButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JFrame testFrame = new testFrame();
verificationFrame.setBounds(400, 100, 250, 250);
Label testLbl = new JLabel("Ok");
testLbl.setBounds(319, 49, 200, 30);
testFrame.getContentPane().add(testLbl);
}}});
I have a problem which is most likely "simple" however I can't figure it out. I am trying to reference my current JFrame so that I can dispose of it, and create a new one, thus "resetting" the program, however I and having trouble figuring out how to reference the JFrame, I have tried, super, this and getParent(), but none of the seem to work. Thanks for any / all help. ^^
Here is my code:
Main Class, just sets up the Jframe and calls the class that creates everything:
public static void main(String args[]) {
JFrame window = new JFrame();
Director director = new Director(window, args);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.pack();
window.setVisible(true);
}
}
Class the creates everything:
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class Director extends JFrame implements CollisionListener {
private BrickWall wall;
private JLabel gameTitle, gameScore, gameLives;
private JPanel controlPanel;
private JButton reset, quit;
private JRadioButton hard, normal, easy;
private int score = 6, lives = 5;
private ButtonGroup difficulty;
public Director(JFrame window, String[] args) {
window.getContentPane().add(makeGamePanel(), BorderLayout.CENTER);
window.getContentPane().add(gameControlPanel(), BorderLayout.NORTH);
}
public void collisionDetected(CollisionEvent e) {
wall.setBrick(e.getRow(), e.getColumn(), null);
}
private JComponent makeGamePanel() {
wall = new BrickWall();
wall.addCollisionListener(this);
wall.buildWall(3, 6, 1, wall.getColumns(), Color.GRAY);
return wall;
}
// Reset method I'm trying to dispose of the JFrame in.
private void reset() {
JFrame frame = new JFrame();
frame.getContentPane().add(makeGamePanel(), BorderLayout.CENTER);
frame.getContentPane().add(gameControlPanel(), BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private JComponent gameControlPanel() {
// CONTROL PANEL PANEL!
controlPanel = new JPanel();
gameTitle = new JLabel("Brickles");
gameScore = new JLabel("Score:" + " " + score);
gameLives = new JLabel("Lives:" + " " + lives);
reset = new JButton("Reset");
quit = new JButton("Quit");
hard = new JRadioButton("Hard", false);
normal = new JRadioButton("Normal", true);
easy = new JRadioButton("Easy", false);
difficulty = new ButtonGroup();
difficulty.add(hard);
difficulty.add(normal);
difficulty.add(easy);
controlPanel.setLayout(new GridLayout(4, 2));
controlPanel.add(gameTitle);
controlPanel.add(gameScore);
controlPanel.add(hard);
controlPanel.add(gameLives);
controlPanel.add(normal);
controlPanel.add(reset);
controlPanel.add(easy);
controlPanel.add(quit);
// Action Listener, where I'm caling the reset method.
reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
reset();
}
});
return controlPanel;
}
}
You can refer to the "outer this" from a nested class with the following syntax:
reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Director.this.reset();
}
});
Yes, you can refer to the outer class by specifying it with the class name as noted in DSquare's good answer (1+ to it), but I urge you not to fling JFrame's at the user as you're program is trying to do. I recommend:
Instead of opening and closing multiple JFrames, use only one JFrame as the main application's window.
If you need helper windows, such as modal windows to get critical information that is absolutely needed, before the program can progress, use modal dialogs such as JDialogs or JOptionPanes.
If you need to swap GUI's, instead of swapping JFrames, swap "views" inside the JFrame via a CardLayout.
Gear your code towards creating these JPanel views and not JFrames as it will make your Swing GUI's much more flexible and portable.
For my homework extra credit I am creating a JTabbedPane and adding two Jpanels. I feel like I am very close, but it still does not compile. When I run it, both JPanels open, but the JTabbedPane does not. I get a lot of Unknown Source errors. I suspect that at this point my issue in in the JPanels themselves because they started out being JFrames and I have tried (unsuccessfully I think) to convert the JFrames to JPanels.
JTabbedPaneAssignment is supposed to create the JTabbedPane and populate the two panes with the apps DayGui on one tab and OfficeAreaCalculator on the other. I only include the JTabbedPaneAssignment and DayGui classes here. I apologize if its too much code, I have trimmed off a lot of what I consider extraneous, but there may still be too much.
Here is the calling class JTabbedPaneAssignment
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JTabbedPaneAssignment extends JPanel
{
public JTabbedPaneAssignment()
{
//super(new GridLayout(1, 1));
JTabbedPane tabbedPane = new JTabbedPane();
DayGui pnlDay = new DayGui();
OfficeAreaCalculator pnlOffice = new OfficeAreaCalculator ();
this.add(tabbedPane);
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
tabbedPane.add(panel1,"First panel");
tabbedPane.add(panel2,"Second panel");
//JComponent panel1 = makeTextPanel("Pane #1");
panel1.setPreferredSize(new Dimension(300, 150));
tabbedPane.addTab("DayGui", panel1);
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
//JComponent panel2 = makeTextPanel("Pane #2");
panel2.setPreferredSize(new Dimension(410, 50));
tabbedPane.addTab("OfficeAreaCalculator", panel2);
tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
add(tabbedPane);
}
protected JComponent makeTextPanel(String text)
{
JPanel panel = new JPanel(false);
JLabel filler = new JLabel(text);
filler.setHorizontalAlignment(JLabel.CENTER);
panel.setLayout(new GridLayout(1, 1));
panel.add(filler);
return panel;
}
// Create JTabbedPane
private static void createAndShowGUI()
{
// Create and set up the window.
JFrame frame = new JFrame("JTabbedPane");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTabbedPaneAssignment(), BorderLayout.CENTER);
JTabbedPane DayGui = new JTabbedPane();
JTabbedPane OfficeAreaCalculator = new JTabbedPane();
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Here is DayGui class. It started out as a JFrame, but I am trying to convert it to a JPanel. I think my issue is in this section of code, but I don't know
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//public class DayGui extends JPanel
public class DayGui extends JPanel
{
private JPanel dayPanel;
private JButton cmdGood;
private JButton cmdBad;
public DayGui()
{
//dayPanel = new JPanel("Messages");
cmdGood = new JButton("Good");
cmdBad = new JButton("Bad");
Container c = dayPanel.getRootPane();
c.setLayout(new FlowLayout());
c.add(cmdGood);
c.add(cmdBad);
dayPanel.setSize(300, 150);
ButtonsHandler bhandler = new ButtonsHandler();
cmdGood.addActionListener(bhandler);
cmdBad.addActionListener(bhandler);
dayPanel.setVisible(true);
dayPanel.getRootPane().setBackground(Color.CYAN);
}
class ButtonsHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == cmdGood)
JOptionPane.showMessageDialog(null, "Today is a good day!",
"Event Handler Message",
JOptionPane.INFORMATION_MESSAGE);
if (e.getSource() == cmdBad)
JOptionPane.showMessageDialog(null, "Today is a bad day!",
"Event Handler Message",
JOptionPane.INFORMATION_MESSAGE);
}
}
}
You have been very ambiguous with your question, and you've posted way more code than anyone here has time to trawl through.
I've made a very small but working JTabbedPane example for you to see the smallest amount of work you need to get it working.
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
public class JTabbedPaneExample extends JFrame{
public JTabbedPaneExample(String title){
super(title);
setSize(800,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JTabbedPane tabbedPane = new JTabbedPane();
JPanel panelOne = new JPanel();
JPanel panelTwo = new JPanel();
tabbedPane.add(panelOne,"First panel");
tabbedPane.add(panelTwo,"Second panel");
add(tabbedPane);
}
public static void main(String[] args){
new JTabbedPaneExample("JTP Example").setVisible(true);
}
}
Then running, this code looks like:
If you repeat the same process in your code, and you've still got errors, then the problem is not with your JTabbedPane, but something else.
Okay, here goes a second time. Now you've got the DayGui class up, we notice that you're trying to use dayPanel before you've initialised it. i.e. nowhere do you say dayPanel = new JPanel();. This resulted in a NullPointerException being thrown in your code, screwing up your normal course of exection. Fix this and your DayGui class would run fine at runtime.
Among your codebase, you also do some very funky things, namely start using something but never getting around to finishing it up. An example of this is you extending JPanel, but resorting to using a member variable of type JPanel to do the rest of the work. The suggestion is to scrap the instance variable all together and use the methods you've inherited from extending JPanel.
Now lets move onto your JTabbedPaneAssignment class. Although not terrible, the code is not very readable and it repeats itself in many places (adding your tabbedpanel multiple times). If you were to take this code further into a larger project, maintenance and debugging would quickly become a problem.
For the purposes of showing you how much clutter you had in your code, I've quickly rewritten your provided code to be compilable, and should roughly do what you're working on.
JTabbedPaneAssignment:
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
public class JTabbedPaneAssignment extends JPanel
{
public JTabbedPaneAssignment()
{
final JTabbedPane tabbedPane = new JTabbedPane();
final DayPanel dayPanel = new DayPanel();
final JPanel officePanel = new JPanel();
tabbedPane.add("DayGui", dayPanel);
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
tabbedPane.add("OfficeAreaCalculator", officePanel);
tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
add(tabbedPane);
}
// Create JTabbedPane
private static void createAndShowGUI()
{
// Create and set up the window.
JFrame frame = new JFrame("JTabbedPane");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTabbedPaneAssignment(), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
DayGui - renamed as DayPanel:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class DayPanel extends JPanel {
public DayPanel() {
super();
setBackground(Color.CYAN);
final JButton goodButton = new JButton("Good");
final JButton badButton = new JButton("Bad");
ActionListener listener = new DayPanel.ButtonsHandler();
goodButton.addActionListener(listener);
badButton.addActionListener(listener);
add(goodButton);
add(badButton);
}
class ButtonsHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
final String command = ((JButton) e.getSource()).getActionCommand();
if (command.equals("Good")) {
showMessage("Today is a good day!");
} else if (command.equals("Bad")) {
showMessage("Today is a bad day!");
}
}
// Show popup message
private void showMessage(String message) {
JOptionPane.showMessageDialog(null, message,
"Event Handler Message", JOptionPane.INFORMATION_MESSAGE);
}
}
}
So what is different in these? Basically, I've removed your NullPointerException you were getting in DayGui. Any other changes I've made are with the intention than you try and keep your code clutter free, so you really know what is going on in your code.
Hope this helps.
When I run it, both JPanels open, but the JTabbedPane does not. I get
a lot of Unknown Source errors.
Well, based on your code and your import section:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
This lines won't compile (unless DayGUI and OfficeAreaCalculator classes are in the same package than your JTabbedPaneAssignment class):
DayGui pnlDay = new DayGui();
OfficeAreaCalculator pnlOffice = new OfficeAreaCalculator ();
This is the only error I've got trying to compile and run your example. I changed lines below:
tabbedPane.addTab( "DayGui", new JPanel());
tabbedPane.addTab("Office Calculator", new JPanel());
And it worked like a charm.
Update
Based on your recent edit (adding your DayGui class, thank you) you have couple of mistakes in your code.
DayGui : this class extends of JPanel so you need to add your components directly on this class, you don't need this panel:
private JPanel dayPanel;
You need to set the layout manager, buttons and background directly on DayGuiclass, like this:
public DayGui() {
cmdGood = new JButton("Good");
cmdBad = new JButton("Bad");
setLayout(new FlowLayout());
add(cmdGood);
add(cmdBad);
setSize(300, 150);
ButtonsHandler bhandler = new ButtonsHandler();
cmdGood.addActionListener(bhandler);
cmdBad.addActionListener(bhandler);
setBackground(Color.CYAN);
}
JTabbedPaneAssignment : I think you're trying to add panel1 and panel2 as tabs but you use add method instead addTab:
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
tabbedPane.add(panel1,"First panel");
tabbedPane.add(panel2,"Second panel");
Also this line:
tabbedPane.addTab("DayGui", panel1);
Should be:
tabbedPane.addTab("DayGui", pnlDay);
Finally in this line you are adding panel2 for a second time and that's not correct:
tabbedPane.addTab("OfficeAreaCalculator", panel2); //I'd comment this line
If you make suggested changes you'll see something like this (BTW the CYAN color almost made me blind :P):
Hope this be helpful and sorry for the extension.