I'm a complete beginner to Java, and I'm finding some answers a bit too technical for me (even the most basic tutorials seem to give me syntax errors when I run the code). How, in really simple terms do I add a JButton to a JFrame? I've got as far as:
import javax.swing.JButton;
import javax.swing.JFrame;
public class JF {
public static void main(String[] args) {
JFrame myFrame = new JFrame();
/*some pretty basic code to initialize the JFrame i.e.
myFrame.setSize(300, 200);
This is as far as I got
*/
}
}
I would seriously appreciate some help!
Creating a new JFrame
The way to create a new instance of a JFrame is pretty simple.
All you have to do is:
JFrame myFrame = new JFrame("Frame Title");
But now the Window is hidden, to see the Window you must use the setVisible(boolean flag) method. Like this:
myFrame.setVisible(true);
Adding Components
There are many ways to add a Component to a JFrame.
The simplest way is:
myFrame.getContentPane().add(new JButton());//in this case we are adding a Button
This will just add a new Component that will fill the JFrame().
If you do not want the Component to fill the screen then you should either make the ContentPane of the JFrame a new custom Container
myFrame.getContentPane() = new JPanel();
OR add a custom Container to the ContentPane and add everything else there.
JPanel mainPanel = new JPanel();
myFrame.getContentPane().add(mainPanel);
If you do not want to write the myFrame.getContentPane() every time then you could just keep an instance of the ContentPane.
JPanel pane = myFrame.getContentPane();
Basic Properties
The most basic properties of the JFrame are:
Size
Location
CloseOperation
You can either set the Size by using:
myFrame.setSize(new Dimension(300, 200));//in pixels
Or packing the JFrame after adding all the components (Better practice).
myFrame.pack();
You can set the Location by using:
myFrame.setLocation(new Point(100, 100));// starting from top left corner
Finally you can set the CloseOperation (what happens when X is pressed) by
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
There are 4 different actions that you can choose from:
DO_NOTHING_ON_CLOSE //Nothing happens
HIDE_ON_CLOSE //setVisible(false)
DISPOSE_ON_CLOSE //Closes JFrame, Application still runs
EXIT_ON_CLOSE //Closes Application
Using Event Dispatch Thread
You should initialize all GUI in Event Dispatch Thread, you can do this by simply doing:
class GUI implements Runnable {
public static void main(String[] args) {
EventQueue.invokeLater(new GUI());
}
#Override
public void run() {
JFrame myFrame = new JFrame("Frame Title");
myFrame.setLocation(new Point(100, 100));
myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
myFrame.getContentPane().add(mainPanel);
mainPanel.add(new JButton("Button Text"), BorderLayout.CENTER);
myFrame.pack();
myFrame.setLocationByPlatform(true);
myFrame.setVisible(true);
}
}
//I hope this will help
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
public class JF extends JFrame
{
private JButton myButton;//Here you begin by declaring the button
public JF()//Here you create you constructor. Constructors are used for initializing variable
{
myButton = new JButton();//We initialize our variable
myButton.setText("My Button"); //And give it a name
JPanel panel1 = new JPanel();//In java panels are useful for holding content
panel1.add(myButton);//Here you put your button in the panel
add(panel1);//This make the panel visible together with its contents
setSize(300,400);//Set the size of your window
setVisible(true);//Make your window visible
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
JFrame frame = new JF();
frame.setTitle("My First Button");
frame.setLocation(400,200);
}
}
Related
So, i created an object of class "CustomPanel" that creates a JPanel with a GridLayout and a label inside of it then I added it to my JFrame. It works fine showing the label "HELLO", but when I change the layout manager of the jpanel to (null) it doesn't show anything. I know, I know using null layout is a very bad practice but I just want to know why it isn't showing the components.
Main class:
import javax.swing.JFrame;
public class MainMenu extends javax.swing.JFrame{
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Size the window.
frame.setSize(500, 500);
CustomPanel panel = new CustomPanel();
frame.getContentPane().add(panel);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
CustomPanel class with GridLayout (This works fine):
import java.awt.GridLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CustomPanel extends JPanel{
public CustomPanel() {
initUI();
}
public final void initUI() {
// create the panel and set the layout
JPanel main = new JPanel();
main.setLayout(new GridLayout());
// create the labels
JLabel myLabel = new JLabel("HELLO");
// add componets to panel
main.add(myLabel);
this.add(main);
}
}
CustomPanel class with Null layout (This doesn't work):
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CustomPanel extends JPanel{
public CustomPanel() {
initUI();
}
public final void initUI() {
// create the panel and set the layout
JPanel main = new JPanel();
main.setLayout(null);
// create the labels
JLabel myLabel = new JLabel("HELLO");
myLabel.setBounds(10, 10, myLabel.getPreferredSize().width, myLabel.getPreferredSize().height);
// add componets to panel
main.add(myLabel);
this.add(main);
}
}
The jlabel is correctly set inside the jpanel so it should be showing in the upper-left side of the jframe, but it doesn't.
What is causing this? what am I missing?.
The problem is that when you don't use a proper layout manager the main JPanel has a preferred size of 0,0, and won't display within the container that it is placed within. The CustomPanel that holds the main JPanel uses FlowLayout and will use its contained component's preferred sizes to help size and position these components, but since main has no layout, adding the JLabel to main does not increase the preferred size as it should -- yet another reason to use layouts, and CustomPanel will display main as just a sizeless dot. You could of course get around this by giving main a preferred size via main.setPreferredSize(...), but then you'd be solving a kludge with a kludge -- not good. Another possible solution is to change CustomPanel's layout to something else that might expand the main JPanel that it holds, perhaps giving CustomPanel a BorderLayout. In this situation, adding main to CustomPanel in a default fashion will place the main JPanel into the BorderLayout.CENTER position, expanding it to fill CustomPanel, and the JLabel will likely be seen.
The proper solution, of course, is to avoid use of null layouts whenever possible.
I know this question has been asked a lot and I have done my research but still can not find anything. Below is proof of this before anyone gets upset:
I found this link:
https://coderanch.com/t/563764/java/Blank-Frame-Panel
and this:
Adding panels to frame, but not showing when app is run
and this:
Why shouldn't I call setVisible(true) before adding components?
and this:
JPanel not showing in JFrame?
But the first question says use repaint which I tried with no fix and the second and third to last questions talk about putting setVisible after components added which I have.
The last one talks about making the users JPanelArt a extension (done so) of JPanel instead of JFrame and not to make a frame in a frame constructor (also have not done)
When ever I run this I just get a blank frame, as if the panel was never added in.
I apologise if I have missed something in those links. Anyway below is my classes:
GUI.java (extends JFrame)
package javaapplication2;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GUI extends JFrame{
public GUI(String name) {
super(name);
getContentPane().setLayout(null);
JPanel myPanel1 = new GUIPanel();
myPanel1.setLocation(20, 20);
getContentPane().add(myPanel1);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setResizable(true);
}
public static void main(String[] args) {
JFrame frame = new GUI("Game");
frame.setVisible(true);
}
}
GUIPanel.java (extends JPanel)
package javaapplication2;
import java.awt.*;
import javax.swing.*;
public class GUIPanel extends JPanel {
JButton start;
JButton inspect1;
JButton inspect2;
JButton inspect3;
JButton suspect;
public GUIPanel() {
setLayout(new BorderLayout());
start = new JButton("Start Game");
inspect1 = new JButton("Inspect 1");
inspect2 = new JButton("Inspect 2");
inspect3 = new JButton("Inspect 3");
suspect = new JButton("Choose Suspect");
add(start, BorderLayout.WEST);
add(inspect1, BorderLayout.WEST);
add(inspect2, BorderLayout.WEST);
add(inspect3, BorderLayout.WEST);
add(suspect, BorderLayout.WEST);
}
}
I know it is very simple, but that is because I am following a tutorial from my lecturer to get the hang of things as I previously used a GUI builder which someone in this community pointed out to me is not good to start with (very correct!)
The issue lies in your GUI class when you call getContentPane().setLayout(null). Because of this method call, your JFrame is not displaying anything. If you remove it, your elements should show up.
I also noticed that you were setting each JButton to have a constraint of BorderLayout.WEST. This will most likely put your JButtons on top of each other and render only one of them.
I want to know how to put put console output into a JFrame. For example, putting this output into a JFrame:
import static java.lang.System.out;
public class frame{
public static void main(String [] args){
out.println("hello");
}
}
How is it possible?
You need to set up the JFrame first.
JFrame frame = new JFrame("title");
Then, set the properties of the JFrame:
frame.setSize(1280,720); //Sets the program's size
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Tells the program to exit on close
frame.setResizable(true); //Tells the program if resizing is enabled
Then, create a panel to store the components:
JPanel p = new JPanel();
After that, you must add the panel to the JFrame like so:
frame.add(p);
Then, with that done, you can use the components supplied in the swing framework, and add them to the panel. A reference for these components can be found here: http://docs.oracle.com/javase/tutorial/uiswing/components/componentlist.html.
To create a component, use the following code:
JLabel label = new JLabel();
Then, use it's build in functions to change it:
label.setText("new text");
Then, once again, to add a component to a panel, use the panel's add() method:
panel.add(label);
Those are just the basics of making a GUI with java. A full tutorial can be viewed here:
http://docs.oracle.com/javase/tutorial/uiswing/
Good Luck!
I can help you with this, but let me please fix some syntax errors you have. When you put the import, an import can't be static (that I know of) and when you want to print out something using "System.out.print" or "System.out.println" you MUST include the "System" part of the line. If you want to add text to a a JFrame use the JLabel to import both just do this bit of code:
import javax.swing.*;
That should import all of your swing elements such as JLabel and JFrame and JPanel, and try this code it will make a window that will have a button and a label. The button doesn't do anything in this code:
import javax.swing.*;
public class main{
public static void main(String[] args)
{
/*
* Creates the frame, makes it visible, and makes
* appear in the center of the screen. While also making it have a close operation
*/
JFrame frame = new JFrame("Button");
frame.setVisible(true);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
//Creates the panel, and adds it to the frame
JPanel panel = new JPanel();
frame.add(panel);
//Creates the label and adds it to the panel, also sets the text
JLabel label = new JLabel();
label.setText("Welcome" + "\n" + "\n");
panel.add(label);
//Creates the button and adds it to the panel
JButton button1 = new JButton("Button 1");
panel.add(button1);
}
}
1.If you want to use JFrame you have to extend your class to a subclass of JFrame:
public class frame extends JFrame {}
2.a)If you want to put Text in your Frame use JLabel and add it to your frame:
JLabel hello = new JLabel("Hello");
add(hello);
2.b)If you want a console output just call System.out.println() in the constructor
Here is a small example class:
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Frame extends JFrame {
public static void main(String args[]) {
new Frame();
}
Frame() {
System.out.println("Hello");
JLabel hello = new JLabel("Hello");
add(hello);
this.setSize(100, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
have a look to the oracle lessons... or any java book!
If that is the case, I don't want to get into GUI just yet. (Learning from a book) Can I convert my current project to a jar file and have it automatically open a command prompt window upon double click?
I am just now learning the basics of java GUI. I have this weird situation that I can't really explain.
I have a GUI class, where I build a simple JFrame. If I use .setVisible(true) within the constructor everything works fine, if I use it outside, nothing loads (the window is visible, but the buttons and what not aren't).
Why is this happening ?
public class GUI extends JFrame {
private JTextField humanYears_TextField = new JTextField(3);
private JTextField dogYears_TextField = new JTextField(3);
private JButton convert_Button = new JButton("Convert");
private JLabel greeting = new JLabel ("Dog years to Human years!");
public GUI () {
JFrame window = new JFrame();
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(this.greeting);
content.add(new JLabel("Dog Years: "));
content.add(this.dogYears_TextField);
content.add(this.convert_Button);
content.add(new JLabel("Human Years: "));
content.add(this.humanYears_TextField);
window.setContentPane(content);
pack(); // aplica contentPane-ul
window.setLocationRelativeTo(null);
window.setTitle("Dog Year Converter");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true); // IF IT'S HERE IT WORKS
}
}
public static void main(String[] args) {
GUI dogYears = new GUI();
//dogYears.setVisible(true); // IF IT'S HERE
//NOTHING EXCEPT THE WINDOW LOADS
}
Why is this happening ?
In this example it doesn't matter, but what if I want to make a window visible only if I click a button or something ?
1) You create 2 instances of JFrame the first from extending JFrame on the class and the second from JFrame window=... You than go on to call setVisible(..) on the window and in your main you attempt to call setVisible(...) on your dogYears.
Solution
You should only create one JFrame per Swing GUI. Get rid of the extends JFrame (and the code that goes with it), as its not good practice to extend JFrame in Swing. Thus of course you wont be able to call setVisible(true) in your constructor which is fine either call it after creating the GUI in the constructor or make a method like setVisible in GUI class which will be a wrapper for your JFrames setVisble(boolean b) method.
Other suggestions
Always create your Swing components on the Event Dispatch Thread which you should do in via SwingUtilitites.invokeLater(Runnable r) block. Have a read on Concurrency in Swing.
Remember to call pack before setting JFrame visible and after adding components.
setLocationRelativeTo(..) should come after pack().
Better to use JFrame.DISPOSE_ON_CLOSE unless using Timers.
Also no need for setContentPane simply call add(..) on JFrame instance.
Here is your code with above mentioned fixes:
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GUI {
private JTextField humanYears_TextField = new JTextField(3);
private JTextField dogYears_TextField = new JTextField(3);
private JButton convert_Button = new JButton("Convert");
private JLabel greeting = new JLabel("Dog years to Human years!");
private JFrame window = new JFrame();
private JPanel content = new JPanel();
public GUI() {
content.setLayout(new FlowLayout());
content.add(this.greeting);
content.add(new JLabel("Dog Years: "));
content.add(this.dogYears_TextField);
content.add(this.convert_Button);
content.add(new JLabel("Human Years: "));
content.add(this.humanYears_TextField);
window.add(content);
window.setTitle("Dog Year Converter");
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.pack();
window.setLocationRelativeTo(null);
//window.setVisible(true); //works here now
}
//our wrapper method so we can change visibility of our frame from outside the class
void setVisible(boolean visible) {
window.setVisible(visible);
}
public static void main(String[] args) {
//Create Swing components on EDT
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
GUI dogYears = new GUI();
dogYears.setVisible(true);//works here too
}
});
}
}
You've got two JFrames, the GUI class itself and the internal variable "window". Use only one.
Make sure that GUI does not extend JFrame (there's no need for this), and give the class a public void setVisible(boolean) method that sets the window to visible.
public class GUI {
private JTextField humanYears_TextField = new JTextField(3);
private JTextField dogYears_TextField = new JTextField(3);
private JButton convert_Button = new JButton("Convert");
private JLabel greeting = new JLabel ("Dog years to Human years!");
private JFrame window = new JFrame();
public GUI () {
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(this.greeting);
content.add(new JLabel("Dog Years: "));
content.add(this.dogYears_TextField);
content.add(this.convert_Button);
content.add(new JLabel("Human Years: "));
content.add(this.humanYears_TextField);
window.setContentPane(content);
pack(); // aplica contentPane-ul
window.setLocationRelativeTo(null);
window.setTitle("Dog Year Converter");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// window.setVisible(true); // IF IT'S HERE IT WORKS
}
public void setVisible(boolean visible) {
window.setVisible(visible);
}
}
You have two different instances :-)
in your constructor:
JFrame window = new JFrame();
window.setVisible(true); // IF IT'S HERE IT WORKS
in your main:
GUI dogYears = new GUI();
dogYears.setVisible(true);
// dogYears != local var window in constructor
Which might get me starting on not extending classes, but using them.
Your class GUI extends from a JFrame, but in the constructor, you are initializing another JFrame, which results in having two different JFrames.
Try this:
public class GUI {
private JTextField humanYears_TextField = new JTextField(3);
private JTextField dogYears_TextField = new JTextField(3);
private JButton convert_Button = new JButton("Convert");
private JLabel greeting = new JLabel ("Dog years to Human years!");
public GUI () {
JFrame window = new JFrame();
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(this.greeting);
content.add(new JLabel("Dog Years: "));
content.add(this.dogYears_TextField);
content.add(this.convert_Button);
content.add(new JLabel("Human Years: "));
content.add(this.humanYears_TextField);
window.setContentPane(content);
pack(); // aplica contentPane-ul
window.setLocationRelativeTo(null);
window.setTitle("Dog Year Converter");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
// main
}
you are creating an instance of JFrame in constructor of GUI which also extends JFRame.
Now you are creating different components and added them on 'window' object.
As you know a frame is set as visible= false and undecorated=false.
So to set a particular JFrame instance you need to call setVisible() method on that instance.
Here you are just creating an instance of GUI and didn't added any component on it.
write a statement in constructor as following rather than "window.setContentPane(content);":
setContentPane(content);
and then call setVisible() method on your instance of GUI class i.e d*ogYears.setVisible(true);*!!
I know this is something very simple, but as a complete Java newbie I'm missing it and someone pointing it out would be infinitely helpful. I've stared at the screen and moved things around and still nothing.
Screenshot:
http://i.imgur.com/dwH60.png
This is all that comes up when this is run.
fullGUI.java:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
public class fullGUI extends JFrame
{
JFrame frame = new JFrame(); //creates frame
public fullGUI() // constructor
{
//setLayout(new BorderLayout());
//add(new shipGrid(), BorderLayout.NORTH);
//add(new shipGrid(), BorderLayout.NORTH);
add(new JRadioButton("Horizontal"), BorderLayout.WEST);
add(new JRadioButton("Vertical"), BorderLayout.WEST);
add(new JTextArea("Instructions to player will go here"), BorderLayout.CENTER);
frame.setSize(400,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Battleship!");
frame.pack(); //sets appropriate size for frame
frame.setVisible(true);
}
}
...called by...
test.java
public class test
{
public static void main(String[] args)
{
new fullGUI();
}
}
name classes in Java from a capital letter
FullGUI already extends JFrame, so no need to create another JFrame inside it
call getContentPane.add() to add to JFrame
use SwingUtilities.invokeLater
So overall something like this
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
public class FullGUI extends JFrame
{
public FullGUI() // constructor
{
getContentPane().add(new JRadioButton("Horizontal"), BorderLayout.WEST);
getContentPane().add(new JRadioButton("Vertical"), BorderLayout.WEST);
getContentPane().add(new JTextArea("Instructions to player will go here"), BorderLayout.CENTER);
setSize(400,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Battleship!");
pack(); //sets appropriate size for frame
setVisible(true);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new FillGU();
}
});
}
Problem is that you are extending JFrame in your class and creating new object "frame". You're adding components such as JRadioButton or JTextArea into fullGUI and other settings of the JFrame are applicable to frame object. It's up to you which approach you're going to choose, but pick one of them. You can extend JFrame and your class will be a child of JFrame which means you can call all public or protected methods from parent class, no need to create new instance of JFrame. Other way is to not extend JFrame and you have to create new JFrame object instead.
frame.pack() is causing your JFrame to resize according to its contents.
If you have frame.setSize(400,600), even if you don't add anything to its content pane,
the frame will be displayed with size 400x600.
But when you call frame.pack(), the frame will resize. In your case, your frame's content pane does not contain anything. Therefore the pack() method resizes it to only your title bar.
As Nikolay Kuznetsov said in earlier answer, you have extended Jframe in fullGUI so no need to create new Jframe in that class, because every instance of FullGUI will be a new frame.
With you code what happened is that you have created a Frame, say frame1 and instance of fullGUI(In main Method) say frame2, these are two different frames. In the Constructor you have added those controls to the frame2 (add()==this.add()) and said frame1.setvisible(true);
Adding controls to one frame and displaying altogether different frame is the reason why you were unable to see anything on output scree though you would have maximized the screen.