How to add a JPanel to a JFrame object? - java

Beginner programming student here. Trying to simply create JFrame object that allows me to click on the boundaries of the window and display the coordinates where I click. However, whenever I click a new location, the previous coordinates need to disappear. I have been told that one way to do this is by adding a JPanel to the center of the JFrame object. However when I do so I am getting an error that says that I am adding a window to a container. I may be extending something incorrectly from what I have read but I can't seem to figure it out.
public class Proj07 {
public static void main(String[] args){
new Proj07Runner();
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Proj07Runner{
GUI gui = new GUI();
}
class MyFrame extends JFrame{
int XCoor;
int YCoor;
public void paint(Graphics g){
g.drawString("x = " + XCoor + ", y = " + YCoor, XCoor, YCoor);
}
}
class GUI{
public GUI(){
MyFrame displayWindow = new MyFrame();
displayWindow.setSize(300,100);
displayWindow.setTitle("Insert name here");
displayWindow.addWindowListener(new WProc1());
JPanel myPanel = new JPanel();
displayWindow.getContentPane().add(myPanel, "Center");
displayWindow.setVisible(true);
}
}
class MouseProc extends MouseAdapter{
public void mousePressed(MouseEvent e){
((MyFrame)e.getComponent()).XCoor = e.getX();
((MyFrame)e.getComponent()).YCoor = e.getY();
e.getComponent().repaint();
}
}
class WProc1 extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
Thank you guys for your help!

I am not 100% sure but I think the problem is where you put the listener:
You need to do everything on the JPanel, not the frame that is the container, so you should replace the declares with:
MyFrame displayWindow = new MyFrame();
displayWindow.setSize(300,100);
displayWindow.setTitle("Insert name here");
displayWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel myPanel = new JPanel();
myPanel.setSize(300,100);
myPanel.addMouseListener(new myMouse)
displayWindow.getContentPane().add(myPanel, "Center");
displayWindow.setVisible(true);
And then create a mouseListener instead of a mouseAdapter to add in the JPanel.
Also remove the last WindowsAdapter thing, just use exitonclose.
Edit:
When it comes down to what the frame should do it should only contain the panel, so you also need to move everything you were doing on the frame to the panel (such as the public void paint() and stuff).
I would go as far as saying that if you want to add multiple panels on a frame, you should consider putting all panels inside another panel (as a container) and then putting that panel inside the frame.

Related

why does simply switching from Frame to JFrame cause such a big difference?

This code displays x and y points based on where you click. I want to add a JPanel so that the frame does not start measuring from the title bar which is unreachable to the user.
Every time I switch from Frame to JFrame I get this:
example
The previous click does not disappear... What is the easiest way to fix this or am i able to add a JPanel on a Frame?
Below is my code:
************************************************************/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Color;
public class Proj07Runner {
Proj07Runner(){
System.out.println(
"Terminal text");
GUI gui = new GUI(); //instantiate a GUI
}//end main
}
**Here is where switching from Frame to JFrame causes the change**
class MyFrame extends JFrame{
int clickX;
int clickY;
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.drawString(
"" + clickX + ", " + clickY, clickX, clickY);
}//end paint()
}
class GUI {
public GUI(){//constructor
//Create a new JFrame object, set size, title, etc.
MyFrame displayWindow = new MyFrame();
JPanel myPanel = new JPanel();
displayWindow.setSize(300,100);
displayWindow.setTitle("Title");
myPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
displayWindow.setVisible(true);
//Instantiate and register an anonymous Listener;
// object which will terminate the program when the;
// user closes the JFrame.
displayWindow.addWindowListener(new WProc1());
myPanel.addMouseListener(
new MouseProc(displayWindow));
displayWindow.addMouseListener(
new MouseProc(displayWindow));
}
}
//This listener class monitors for mouse presses and;
// displays the coordinates of the mouse pointer when the
// mouse is pressed on the source object. Note that this
// class extends is an adapter class.
class MouseProc extends MouseAdapter{
MyFrame refToWin; //save a reference to the source here
MouseProc(MyFrame inWin){//constructor
refToWin = inWin;//save ref to window
}//end constructor
//Override the mousePressed method to determine and;
// display the coordinates when the mouse is pressed.
public void mousePressed(MouseEvent e){
//Get X and Y coordinates of mouse pointer and store
// in an instance variable of the JFrame object
refToWin.clickX = e.getX();
refToWin.clickY = e.getY();
//refToWin.clearRect(0,0,300,100);
// Force the JFrame object to be repainted in order to
// display the coordinate information.
refToWin.repaint();
}//end mousePressed()
}
//The following listener is used to terminate the program
// when the user closes the frame. Note that this class
// extends an adapter class.
class WProc1 extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
The coordinates look awkward because the MouseListener is on the Frame, not the Panel. The coordinates will always be in the component's coordinate system that the listener is attached to.
So if you do the rendering in the JPanel, why not attach the MouseListener to that JPanel?
While AWT is a heavy weight UI framework (every AWT component has some native UI representation such as X Widget or a Windows 'window'), Swing is a lightweight framework. Only the root component JWindow, JFrame or JDialog have native representations, the rest is within the JVM. When mixing components you need to know about this difference.
See also https://en.wikipedia.org/wiki/Abstract_Window_Toolkit#Mixing_AWT_and_Swing_components
Ummmm, I just learned that the problem I was referring to may have been fixed since Java 6...
Somehow I felt like creating a small demo using Swing only:
package com.mycompany.test;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestPanel extends JPanel {
private Point clickPosition;
public TestPanel() {
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
clickPosition = e.getPoint();
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (clickPosition != null) {
g.setColor(Color.BLACK);
g.drawLine(clickPosition.x-5, clickPosition.y, clickPosition.x+5, clickPosition.y);
g.drawLine(clickPosition.x, clickPosition.y-5, clickPosition.x, clickPosition.y+5);
g.drawString(String.format("(%d, %d)", clickPosition.x, clickPosition.y), clickPosition.x+5, clickPosition.y-5);
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TestPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}

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

how to set window size without extending JFrame?

i just started studying gui in java. i am now able to create windows with specific sizes while extending JFrame. however, i came to read posts from here that it is better not to extend JFrame. then i tried to create a window by setting the size in the JPanel instead, but the setSize doesn't seem to work (my code must lack something)
here's my code for my frame
import javax.swing.JFrame;
public class MyFrame{
private JFrame mainFrame;
private MyPanel mainPanel;
public MyFrame(){
mainFrame = new JFrame();
mainPanel = new MyPanel(50, 50);
mainFrame.add(mainPanel);
mainFrame.setVisible(true);
}
}
and here's my code for my panel
import javax.swing.JPanel;
public class MyPanel extends JPanel{
public MyPanel(int i, int j){
setSize(i, j);
}
}
i tried adding frame.pack() in my Frame class, because i thought the frame, not having it's size set, is too small for the panel to be seen -i was wrong
what's lacking in my code?
what's lacking in my code?
A preferred size for the custom component (Panel) for starters. #Override getPreferredSize() to return a logical value.
Then pack() the frame to ensure it is the smallest size needed to display the panel and any other components.
So, something like this:
import javax.swing.*;
public class Application {
private JFrame frame;
private CustomPanel panel;
public Application() {
frame = new JFrame();
// next 2 lines, just a good idea
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// at 50x50, the title bar on Windows is wider!
panel = new CustomPanel(200, 200);
frame.add(panel);
// make the frame smallest it can be and still show components
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new Application();
}
};
SwingUtilities.invokeLater(r);
}
}
class CustomPanel extends JPanel {
public CustomPanel(int w, int h) {
setPreferredSize(new java.awt.Dimension(w, h));
}
}

Java JPanel Drawing rectangle drawRect(); what to do next, or which component of Java will suit better?

I have drawn a rectangle using a JPanel
My main objective is to store my Requirement Engineering chapter into a JPanel or a JFrame
import java.awt.*;
import javax.swing.*;
class RequirementEngineering extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent();
g.drawRect(10,10,60,60);
g2.drawString("Feasibility study", 20, 20); //rectangle is my main objective, I will look after the string later
}
public static void main(String[] args)
{
}
}
how do I display the JPanel? I know, JApplet doesn't require a main method, but how do we represent JPanel in main() method?
I have this doubt for long, and other posts are confusing me further, Could I have a direct question
My main question being "How to add JFrame to JPanel" pertaining my current coding
thanks in advance
see if you need to use a Window based app, you can do as:
JPanel customPanel = new RequirementEngineering();
JFrame frame = new JFrame("my window");
frame.getContentPane().add(customPanel );
frame.setSize(300,200);
frame.setVisible(true);
If you need in Applet,
public class JAppletExample extends JApplet {
public void init() {
Container content = getContentPane();
JPanel customPanel = new RequirementEngineering();
content.add(customPanel );
}
And you can run it using appletViewer or in any Web Browser such as IE.

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