I started a new project, all the code is right (I think) and no window is appearing. There are no compilation errors, whenever I run the program nothing happens.
import javax.swing.*;
import java.awt.*;
public class Frame extends JFrame{
public static String title = "Tower Defense";
public static Dimension size = new Dimension(700, 550);
public static void main(String args[]){
Frame frame = new Frame();
}
public Frame() {
setTitle(title);
setSize(size);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void init(){
setVisible(true);
}
}
You never call init() method. How can your frame be visible?
Just change your main method to:
public static void main(String args[]){
Frame frame = new Frame();
frame.init();
}
You never make a call to init() in your frame constructor:
public Frame() {
setTitle(title);
setSize(size);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
**init();**
}
init() method will never be called in your program.
Set the visibility in your Frame() Constructor itself.
import javax.swing.*;
import java.awt.*;
public class Frame extends JFrame{
public static String title = "Tower Defense";
public static Dimension size = new Dimension(700, 550);
public static void main(String args[]){
Frame frame = new Frame();
}
public Frame(){
setTitle(title);
setSize(size);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Related
I am new(ish) to Java Swing but I have not been able to find an elegant solution to my issue so I thought I'd raise a question here.
I am trying to make my current JPanel change to another JPanel based on a button click event from within the current JPanel. In essence just hiding one panel and displaying the other. I feel this can be done within my MainFrame class however I'm not sure how to communicate this back to it. Nothing I am trying simply seems to do as desired, I'd appreciate any support. Thanks
App.java
public static void main(final String[] args) {
MainFrame mf = new MainFrame();
}
MainFrame.java
public class MainFrame extends JFrame {
public MainFrame(){
setTitle("Swing Application");
setSize(1200, 800);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
// First Page Frame switch
getContentPane().add(new FirstPage());
}
}
FirstPage.java
public class FirstPage extends JPanel {
public FirstPage() {
setVisible(true);
JButton clickBtn = new JButton("Click");
clickBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
// Change to SecondPage JPanel here.
}
});
add(clickBtn);
}
}
SecondPage.java
public class SecondPage extends JPanel {
public SecondPage() {
setVisible(true);
add(new JLabel("Welcome to the Second Page"));
}
}
Any more information needed, please ask thanks :)
I think the best way is to use CardLayout. It is created for such cases. Check my example:
public class MainFrame extends JFrame {
private CardLayout cardLayout;
public MainFrame() {
super("frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cardLayout = new CardLayout();
getContentPane().setLayout(cardLayout);
getContentPane().add(new FirstPage(this::showPage), Pages.FIRST_PAGE);
getContentPane().add(new SecondPage(this::showPage), Pages.SECOND_PAGE);
setLocationByPlatform(true);
pack();
}
public void showPage(String pageName) {
cardLayout.show(getContentPane(), pageName);
}
public static interface PageContainer {
void showPage(String pageName);
}
public static interface Pages {
String FIRST_PAGE = "first_page";
String SECOND_PAGE = "second_page";
}
public static class FirstPage extends JPanel {
public FirstPage(PageContainer pageContainer) {
super(new FlowLayout());
JButton button = new JButton("next Page");
button.addActionListener(e -> pageContainer.showPage(Pages.SECOND_PAGE));
add(button);
}
}
public static class SecondPage extends JPanel {
public SecondPage(PageContainer pageContainer) {
super(new FlowLayout());
add(new JLabel("This is second page."));
JButton button = new JButton("Go to first page");
button.addActionListener(e -> pageContainer.showPage(Pages.FIRST_PAGE));
add(button);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true));
}
}
CardLayout is the right tool for the job.
You can simply create the ActionListener used to swap pages in JFrame class, and pass a reference of it to FirstPage:
import java.awt.CardLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
public MainFrame(){
setTitle("Swing Application");
setSize(1200, 800);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationByPlatform(true);
//Create card layout and set it to the content pane
CardLayout cLayout = new CardLayout();
setLayout(cLayout);
//create and add second page to the content pane
JPanel secondPage = new SecondPage();
add("SECOND",secondPage);
//create an action listener to swap pages
ActionListener listener = actionEvent ->{
cLayout.show(getContentPane(), "SECOND");
};
//use the action listener in FirstPage
JPanel firstPage = new FirstPage(listener);
add("FIRST", firstPage);
cLayout.show(getContentPane(), "FIRST");
setVisible(true);
}
public static void main(String[] args) {
new MainFrame();
}
}
class FirstPage extends JPanel {
public FirstPage(ActionListener listener) {
JButton clickBtn = new JButton("Click");
clickBtn.addActionListener(listener);
add(clickBtn);
}
}
class SecondPage extends JPanel {
public SecondPage() {
add(new JLabel("Welcome to the Second Page"));
}
}
I have two JFrames (frameA and FrameB). frameB can only be opened from frameA and when I open frameB, frameA must be left open. frameB has got a button (Close_frameA). I would like when the button is clicked to close frameA.
How can i do it?
First of all, is each JFrame made by a different class( I would assume so because I don't know any other way to make two frames).
Possible solution to try:
in frame A, create a "static variable":
//lets call the class that create frameA ClassA
public class ClassA extends JFrame {
static JFrame frameA;
instead of doing
JFrame frameA=new JFrame("Name of the frame");
in the public static void main(String[] args).Then, in the public static void main(String[] args) program, do
//the static JFrame assigned before
frameA= new JFrmae("Nameof the frame");
this lets the program in frameB to read "frameA" with the following code in ClassB(lets call the class that make frameB ClassB):
JFrame frameA= ClassA.frameA;
then, still in ClassB, we can do
frameA.dispose();
I hope you understand(please comment for what you don't understand if you don't), and i hope it works.
Code:
import javax.swing.JFrame;
public class ClassA {
static JFrame frameA;
public ClassA(){
//a useless constructor because I am not adding any Listeners(don't worry about it)
}
public static void main(String[] args){
frameA=new JFrame("Name");
//your ordinary things(some peiople put these in the constructor)
frameA.setSize(300,300);
frameA.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameA.setVisible(true);
//runs ClassB
new ClassB();
}
}
and
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class ClassB extends JFrame implements ActionListener{
static JButton close=new JButton("close");
public ClassB(){
//your ordinary thigns
add(close);
setSize(300,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
close.addActionListener(this);
System.out.println("what?");
}
public static void main(String[] args){
JFrame frameB=new JFrame("Clae Frame A");
}
#Override
public void actionPerformed(ActionEvent arg0) {
if(arg0.equals("close")){
JFrame frameA=ClassA.frameA;
frameA.dispose();
}
}
}
You can use below two class: TJFrame and OpenFrame to close a JFrame class with a button in another JFrame
public class TJFrame {
public static OpenFrame openWindow;
public static void main(String[] args) {
JFrame frame = new JFrame("Swing Frame");
JButton button = new JButton("Open");
frame.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
openWindow = new OpenFrame();
openWindow.setVisible(true);
}
});
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setSize(350, 200);
frame.setVisible(true);
}}
public class OpenFrame extends JFrame{
JPanel back_panel;
public JButton button = new JButton("Cross");
public OpenFrame() {
back_panel = new JPanel();
setContentPane(back_panel);
this.setSize(350, 200);
button.setBounds(380, 10, 20, 20);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
dispose();
}
});
back_panel.add(button);
}}
During a JFrame test program, I realized that I can't put this:
setSize(450, 300);
setResizable(false);
setVisible(true);
On the top of the constructor, otherwise it doesn't work as it should. However it works if I put it in the bottom like so:
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class GameWindow extends JFrame {
private GameGraphics gameGraphics;
public GameWindow() {
super("Fellice");
gameGraphics = new GameGraphics();
gameGraphics.setBackground(Color.BLACK);
add(gameGraphics, BorderLayout.CENTER);
setSize(450, 300);
setResizable(false);
setVisible(true);
}
}
It doesn't work if I put it after calling the superclass, but why? I have attempted to put these:
setSize(450, 300);
setResizable(false);
setVisible(true);
One by one on the top to see which was causing the problem, and it seems to to be a this combination:
setSize(450, 300);
setVisible(true);
That doesn't work at the top. However, in one of my other programs it works perfectly fine:
#SuppressWarnings("serial")
public class Client extends JFrame {
private JTextField messageField;
private JTextArea chatWindow;
public Client(String host) {
super("Messenger");
setSize(300, 400);
setVisible(true);
chatWindow = new JTextArea();
chatWindow.setEditable(false);
messageField = new JTextField();
// .. actions etc.
add(new JScrollPane(chatWindow), BorderLayout.CENTER);
add(messageField, BorderLayout.SOUTH);
}
*edit
Working code:
#SuppressWarnings("serial")
public class GameWindow extends JFrame {
private GameGraphics gameGraphics;
public GameWindow() {
super("Fellice");
gameGraphics = new GameGraphics();
gameGraphics.setBackground(Color.BLACK);
add(gameGraphics, BorderLayout.CENTER);
setSize(450, 300);
setResizable(false);
setVisible(true);
}
}
Glitched code (Screen appears blank):
#SuppressWarnings("serial")
public class GameWindow extends JFrame {
private GameGraphics gameGraphics;
public GameWindow() {
super("Fellice");
setSize(450, 300);
setResizable(false);
setVisible(true);
gameGraphics = new GameGraphics();
gameGraphics.setBackground(Color.BLACK);
add(gameGraphics, BorderLayout.CENTER);
}
}
Code:
import java.awt.Dimension;
import javax.swing.*;
public class Game extends JFrame {
private static final long serialVersionUID = -7919358146481096788L;
JPanel a = new JPanel();
public static void main(String[] args) {
new Game();
}
private Game() {
setTitle("Insert name of game here");
setLocationRelativeTo(null);
setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
a.setPreferredSize(new Dimension(600, 600));
add(a);
pack();
setVisible(true);
}
}
So I set the preferred size of the JPanel to 600 by 600 and pack the frame, but the frame's size is still 0 by 0.
Why is this and how do I fix it?
As you said, pack() will try and arrange the window so that every component is resized to its preferredSize.
The problem is that it seems that the layout manager is the one trying to arrange the components and their respective preferredSizes. However, as you set the layout manager as being null, there is no one in charge of that.
Try commenting the setLayout(null) line, and you're gonna see the result. Of course, for a complete window, you're going to have to choose and set a meaningful LayoutManager.
This works fine to me:
import java.awt.Dimension;
import javax.swing.*;
public class Game extends JFrame {
private static final long serialVersionUID = -7919358146481096788L;
JPanel a = new JPanel();
public static void main(String[] args) {
new Game();
}
private Game() {
setTitle("Insert name of game here");
setLocationRelativeTo(null);
//setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
a.setPreferredSize(new Dimension(600, 600));
add(a);
pack();
setVisible(true);
}
}
pack() queries the preferred size of the parent container over that of the child so you would have to use:
setPreferredSize(new Dimension(600, 600));
Another note is to call
setLocationRelativeTo(null);
after pack() has been called to calculate center coordinates :)
OK, just spotted the null layout there, why not use the default BorderLayout of JFrame?
Your problem is setLayout(null), becase the docs say for pack():
Causes this Window to be sized to fit the preferred size and layouts of its subcomponents
thus with no layout it does not execute correctly.
This seems to work fine for me:
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends JFrame {
JPanel panel = new JPanel();
private void createAndShowGUI() {
setTitle("FrameDemo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setPreferredSize(new Dimension(600, 600));
add(panel);
//setLayout(null); //wont work with this call as pack() resizes according to layout manager
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Game().createAndShowGUI();
}
});
}
}
Code :
import javax.swing.*;
import java.awt.*;
public class firstGUI extends JPanel {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
Image image = new ImageIcon("dist.jpg").getImage();
g.drawImage(image,0,0, this);
}
}
Compiles perfectly, but when I run it, it just shows a form. No picture(or any other operation in paintComponent) shows up. Is there something I'm missing?
Your paintComponent method is an instance method of your firstGUI class (a JPanel). The problem is that you are not creating an instance of firstGUI and adding it to the frame.
The following replacement main method instantiates firstGUI and adds it to the contentPane of the frame:
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.getContentPane().add(new firstGUI());
frame.setVisible(true);
}