How to reference JFrame - java

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.

Related

Java FlowLayout

I am writing some Java code that allows the user to see a frame with JLabel, JTextField and JButton.
I want the JLabel to be called "Count" and I have a problem with FlowLayout.
I want the interface to look like this:
Instead, I have this:
This is my code:
package modul1_Interfate_Grafice;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Exercitiu04 implements ActionListener {
private JFrame frame;
private JLabel labelCount;
private JTextField tfCount;
private JButton buttonCount;
private int count = 0;
public void go() {
frame = new JFrame("Java Counter");
labelCount = new JLabel("Counter");
labelCount.setLayout(new FlowLayout());
frame.getContentPane().add(BorderLayout.CENTER, labelCount);
tfCount = new JTextField(count + " ", 10);
tfCount.setEditable(false);
labelCount.add(tfCount);
buttonCount = new JButton("Count");
labelCount.add(buttonCount);
buttonCount.addActionListener(this);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(350, 150);
frame.setLocation(400, 200);
}
#Override
public void actionPerformed(ActionEvent event) {
count++;
tfCount.setText(count + "");
}
public static void main(String[] args) {
Exercitiu04 a = new Exercitiu04();
a.go();
}
}
Solve it.
Instead of labelCount.setLayout(new FlowLayout());` i should have had
frame.setLayout(new FlowLayout());
From description of JLabel class,
JLabel is:
A display area for a short text string or an image, or both.
But here: labelCount.add(tfCount) and here labelCount.add(buttonCount) you're trying to put a textfield and a button into a label. In this case, positions of button and textfield are controlled by FlowLayout but position of the text in the label is not.
Instead of this, you should put all of your elements in common JPanel, like this:
...
frame = new JFrame("Java Counter");
frame.setLayout(new BorderLayout());
JPanel wrapper = new JPanel(); // JPanel has FlowLayout by default
labelCount = new JLabel("Counter");
labelCount.setLayout(new FlowLayout());
wrapper.add(labelCount);
tfCount = new JTextField(count + " ", 10);
tfCount.setEditable(false);
wrapper.add(tfCount);
buttonCount = new JButton("Count");
buttonCount.addActionListener(this);
wrapper.add(buttonCount);
frame.add(BorderLayout.CENTER, wrapper);
...
And, like MasterBlaster said, you should put swing methods in EDT.
There are only two things you should know about FlowLayout:
a) It is a default layout manager of the JPanel component
b) It is good for nothing.
This trivial layout cannot be achieved with FlowLayout.
When doing layouts in Swing, you should familiarize yourself
with some powerful layout managers. I recommend MigLayout and
GroupLayout.
package com.zetcode;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
/*
Simple UI with a MigLayout manager.
Author Jan Bodnar
Website zetcode.com
*/
public class MigLayoutCounterEx extends JFrame {
public MigLayoutCounterEx() {
initUI();
}
private void initUI() {
JLabel lbl = new JLabel("Counter");
JTextField field = new JTextField(10);
JButton btn = new JButton("Count");
createLayout(lbl, field, btn);
setTitle("Java Counter");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void createLayout(JComponent... arg) {
setLayout(new MigLayout());
add(arg[0]);
add(arg[1]);
add(arg[2]);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MigLayoutCounterEx ex = new MigLayoutCounterEx();
ex.setVisible(true);
});
}
}
The example is trivial. You just put the three components into the
cells.
Screenshot:
You shouldn't use setSize when dealing with FlowLayout. Instead use pack(). It makes the window just about big enough to fit all your components in. That should tidy things up for you

Change attribute in other jframe when a button is clicked in another JFrame

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

frame.getContentPane().add(); not working properly?

I've been having some (very annoying) trouble with these scripts that I've created.
Sburb.java
import java.awt.Color;
import javax.swing.*;
public class Sburb
{
public static void main (String[] args)
{
JFrame frame = new JFrame ("Welcome to Sburb");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
spirograph page = new spirograph();
progressbar bar = new progressbar();
frame.getContentPane().add(page);
frame.getContentPane().add(bar);
frame.pack();
frame.setVisible(true);
frame.setResizable(true);
}
}
progressbar.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class progressbar extends JPanel
{
JProgressBar current;
JTextArea out;
JButton find;
Thread runner;
int num = 1;
progressbar()
{
super();
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel pane = new JPanel();
pane.setLayout(new FlowLayout());
current = new JProgressBar(0, 2000);
current.setStringPainted(false);
pane.add(current);
//setContentPane(pane);
}
public void iterate() {
while (num < 2000) {
current.setValue(num);
try {
Thread.sleep(300);
} catch (InterruptedException e) { }
num += 5;
}
}
// public static void main(String[] arguments) {
// progressbar frame = new progressbar();
// frame.pack();
// frame.setVisible(true);
// frame.iterate();
// }
}
spirograph.java
import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class spirograph extends JPanel
{
private ImageIcon image;
private JLabel label;
private JLabel frame = new JLabel();
private JPanel panel = new JPanel();
spirograph()
{
this.setOpaque(true);
this.setBackground(Color.BLACK);
setLayout(new FlowLayout());
image = new ImageIcon(getClass().getResource("Gate.gif"));
label = new JLabel(image);
add(label);
progressbar bar = new progressbar();
}
}
I'm trying to call the file "progressbar" to the Sburb file but when I do, it gives me just the simple JFrame of this (not fixed):
http://imgur.com/1aAmPwJ
And when I get rid of the "frame.getContentPane().add(bar);" in Sburb.java, it gives me this (fixed, kind-of):
http://imgur.com/15aGtT2
How do I fix this? I've looked everywhere and yet I still can't figure it out! I also can't seem to figure out how to align the bar directly below the gif.
frame.getContentPane().add(page);
frame.getContentPane().add(bar);
The content pane of a JFrame is a set to a BorderLayout which can only accept one component in any one of the border layout constraints. Given no constraints were supplied here, the JRE will try to put them both in the CENTER.
For this, and a variety of other reasons, I would advise to ignore the existing content pane, arrange the entire GUI (as many panels as it consists of) into another panel (let's call it ui) then call
frame.setContentPane(ui);

JPanels not added to JTabbedPane

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.

JFrame inside another JFrame

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.

Categories

Resources