I'm trying to learn Java Swing. Right now, I'm making a simple program and I need to make a button. I have two classes: driver and swing.
I create the button and import the javax.swing.JButton and added the button. Finally, the button added to the panel but Idk why I just get the panel?
Can anyone help me, please? Here's my code:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Swing extends JFrame {
private JFrame f;
private JButton button;
private JLabel label;
private JPanel panel;
public Swing() {
}
public Swing(String titleName) {
creatButton();
creatFrame(titleName);
}
public void creatButton() {
JButton btn = new JButton("click me");
JPanel panel = new JPanel();
panel.add(btn);
btn.setBounds(50, 100, 95, 30);
add(panel);
}
private void creatFrame(String title) {
JFrame f = new JFrame(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setSize(400, 500);
f.setLayout(null);
}
}
public class Driver {
public static void main (String [] args) {
new Swing ("calculator");
}
}
Okay,lets start with...
JButton btn = new JButton("click me");
JPanel panel = new JPanel();
panel.add(btn);
btn.setBounds(50, 100, 95, 30);
add(panel);
You:
Create a button
Create a panel
You add the button to panel
You add the panel to the frame
And then...
JFrame f = new JFrame("calculator");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new
f.setVisible(true);
You create a brand new instance of JFrame and show it, but it has nothing on to it?! 😱!
Instead, you should avoid extending from JFrame and maybe use JPanel instead, something like...
public class Swing extends JPanel {
private JButton button;
private JLabel label;
public Swing() {
creatButton();
add(button);
}
public void creatButton() {
JButton btn = new JButton("click me");
}
}
Then you can just create a window (or other container) and add it to it
JFrame f = new JFrame(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Swing());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
As a general rule, JFrame is a really poor extension point, it's a complex, compound component and locks you into a single use case. It's generally a better idea to start with something JPanel which provides you with a lot more flexibility and a lot less complexity and is easily reusable.
You really, really, really need to avoid null layouts
creatFrame is creating a new JFrame different than the frame itself (your Swing class extending JFrame).
Remove the line:
JFrame f = new JFrame(title);
and call the methods over this instead of f.
Related
I've been looking around, including in the Java documentation, but there isn't a clear answer that I've found for my question : I would like to switch from one JFrame to another at the click of a button; that is, have the old JFrame close while the new one opens. I've heard of "CardLayout" but I'm not so sure how it works. Would anyone mind explaining it, or some other method?
Thanks
Here is an example of a CardLayout
As you've heard other say, don't use multiple JFrames.
import javax.swing.*;
import java.awt.*;
public class MainFrame
{
static JPanel homeContainer;
static JPanel homePanel;
static JPanel otherPanel;
static CardLayout cl;
public MainFrame()
{
JFrame mFrame = new JFrame("CardLayout Example");
JButton showOtherPanelBtn = new JButton("Show Other Panel");
JButton backToHomeBtn = new JButton("Show Home Panel");
cl = new CardLayout(5, 5);
homeContainer = new JPanel(cl);
homeContainer.setBackground(Color.black);
homePanel = new JPanel();
homePanel.setBackground(Color.blue);
homePanel.add(showOtherPanelBtn);
homeContainer.add(homePanel, "Home");
otherPanel = new JPanel();
otherPanel.setBackground(Color.green);
otherPanel.add(backToHomeBtn);
homeContainer.add(otherPanel, "Other Panel");
showOtherPanelBtn.addActionListener(e -> cl.show(homeContainer, "Other Panel"));
backToHomeBtn.addActionListener(e -> cl.show(homeContainer, "Home"));
mFrame.add(homeContainer);
cl.show(homeContainer, "Home");
mFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
mFrame.setLocationRelativeTo(null);
mFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
mFrame.pack();
mFrame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(MainFrame::new);
}
}
You don't need to use a CardLayout for anything in this case. In fact, JFrame's don't have layouts.
Here's some code to illustrate that idea (assuming you're using Java 8; otherwise, add the final modifier to oldFrame and newFrame:
JFrame parent = new JFrame();
JDialog oldFrame = new JDialog("My Old Frame's Title");
JDialog newFrame = new JDialog("My New Frame's Title");
JPanel panel = new JPanel();
JButton myButton = new JButton();
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
oldFrame.dispose(); //closes your old frame
newFrame.setVisible(true); //opens your new frame
}
});
panel.add(myButton);
oldFrame.add(panek);
oldFrame.setVisible(true);
Whenever you click your button, the old frame closes, and the new one opens.
Components are not displayed in my JFrame using Swing.
Actually my aim is:
Add Frame
In the frame add panel
Panel cantains 3 buttons
But it didn't show.
Here is my code
public class Panels
{
JFrame frame;
JPanel panel;
private JButton addButton;
private JButton modifyButton;
private JButton deleteButton;
Panels()
{
initGUI();
launchFrame();
}
public void initGUI()
{
frame = new JFrame();
panel = new JPanel();
addButton = new JButton("Add");
modifyButton = new JButton("Modify");
deleteButton = new JButton("Delete");
}
public void launchFrame()
{
addButton.setBounds(130,50,225,25);
addButton.setBounds(150,50,225,25);
addButton.setBounds(170,50,225,25);
addButton.setBounds(190,50,225,25);
panel.add(addButton);
panel.add(modifyButton);
panel.add(deleteButton);
panel.setLayout(null);
panel.setBackground(Color.RED);
frame.add(panel);
frame.setTitle("My Frame with Panel");
frame.setSize(600,400);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Here is main for calling Panels class
When run on main function Frame is shown without controllers (ie 3 buttons not shown)
public class Main
{
public static void main(String[] args)
{
Panels obj_panel=new Panels();
}
}
This is the main problem
frame.setLayout(null);
When you set the layout to null, that means that all of its components must have boundaries set. You try to add the panel, without any boundaries. You only set the boundaries for the buttons in the panel. If you remove the above line, it works.
Other Issues I'd really take a look at:
Don't use null layouts at all. Instead make use of layout managers, and let them handle the sizing and positioning for you. This results in a a much more manageable and flexible UI. Please take some time to learn the different layout managers. Start at Laying out Components Within a Container
All Swing apps should run on a special thread known as the Event Dispatch Thread (EDT). Please take some time to read Initial Threads to learn how you can accomplish this.
Here is a refactor (fixing the "Other issues") with no null layout, just using layout managers, margins, and borders, and the code in the main shows how to run the program on the Event Dispatch Thread
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
Panels obj_panel = new Panels();
}
});
}
}
class Panels {
private JFrame frame;
private JPanel panel;
private JButton addButton;
private JButton modifyButton;
private JButton deleteButton;
Panels() {
initGUI();
launchFrame();
}
private void initGUI() {
frame = new JFrame(); // default layout manager is BorderLayout
panel = new JPanel(); // default layout manager is FlowLayout
addButton = new JButton("Add");
modifyButton = new JButton("Modify");
deleteButton = new JButton("Delete");
}
private void launchFrame() {
JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 10, 10));
buttonPanel.setBackground(Color.RED);
buttonPanel.add(addButton);
buttonPanel.add(modifyButton);
// add margin to left and right of delete button
// other buttons will follow suit because of GridLayout
deleteButton.setMargin(new Insets(0, 50, 0, 50));
buttonPanel.add(deleteButton);
// create some space at the top for the buttonPanel
buttonPanel.setBorder(new EmptyBorder(20, 0, 0, 0));
panel.add(buttonPanel);
panel.setBackground(Color.RED);
frame.add(panel);
frame.setTitle("My Frame with Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
I've been doing some GUI stuff to practice for finals and I think I've gotten the basics down. However, every time I try to add a JTextField to my JPanel, my JButton gets erased and the entire interface disappears. Ultimately, I wanted the text area to change when I clicked the button but I can't even see the text area. I know I probably made a really novice mistake so don't kill me please. The code below doesn't work- however once I strip off the JTextField it runs fine.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.JTextField;
public class test5 {
private JFrame f;
private JPanel p;
private JButton b1;
private JTextField jt;
public test5 () {
gui();
}
public void gui () {
f = new JFrame();
f.setVisible(true);
f.setSize(600,400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jt = new JTextField(20);
jt.setEditable(false);
p = new JPanel();
p.setBackground(Color.YELLOW);
b1 = new JButton("TEST");
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "Hey, hey, hey!");
jt.setText("Hello");
}
});
p.add(b1);
p.add(jt);
f.add(p, BorderLayout.SOUTH);
}
public static void main (String args[]) {
test5 test = new test5();
}
}
You should add all components to the frame BEFORE you make the frame visible. Try the following:
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
For school I had to make a JFrame and within that One button and Two textfields. Whatever you put in Textfield one have to get into textfield two when the button is pressed. I got the code to the point I should see the textfields and the button when i run the program. For whatever reason it doesn't.
My come so far:
package helloworld;
import javax.swing.*;
import java.awt.event.*;
public class HelloWorld extends JFrame {
public static void main(String[] args) {
JFrame frame = new HelloWorld();
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Hello World Button App");
JPanel panel = new JPanel();
frame.setContentPane(panel);
fram.setVisible(true);
}
}
class panel extends JPanel {
public JButton btn1 = new JButton("Klick!");
public JTextField txt1 = new JTextField(10);
public JTextField txt2 = new JTextField(10);
public panel() {
add(btn1);
add(txt1);
add(txt2);
}
}
I am not yet allowed to post images but I will provide a link to the picture down here
I am sorry if this question allready exests but i couldnt's find a similar question.
I am new to programming so please dont yell at me when I forgot something or wrote something wrong in it!
Here i have modified your code a bit, but did in a similar way.
I won't extend JFrame until and unless i don't want to do something creative, but you always CAN.
You had already extended JFrame , so no worth of calling methods with frame.foo()
but simply foo() , and most important JFrame frame = new HelloWorld() , will make no sense, if you have already extended you class with JFrame:
import javax.swing.*;
public class HelloWorld extends JFrame{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new HelloWorld().setVisible(true);
}
});
}
public HelloWorld()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Hello World Button App");
panel pan= new panel();
add(pan.panel);
pack();
setVisible(true);
}
}
class panel {
private JButton btn1 = new JButton("Klick!");
private JTextField txt1 = new JTextField(10);
private JTextField txt2 = new JTextField(10);
JPanel panel;
public panel() {
panel = new JPanel();
panel.add(btn1);
panel.add(txt1);
panel.add(txt2);
}
}
Also, you can also extend your panel class with JPanel :
public HelloWorld()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Hello World Button App");
panel pan= new panel();
add(pan);
pack();
setVisible(true);
}
}
class panel extends JPanel {
private JButton btn1 = new JButton("Klick!");
private JTextField txt1 = new JTextField(10);
private JTextField txt2 = new JTextField(10);
public panel() {
add(btn1);
add(txt1);
add(txt2);
}
}
That is because your class name is panel not JPanel
Modify this:
panel panel = new panel();
frame.setContentPane(panel);
frame.setVisible(true);
You should try to use names for your Class that are not so confusing, and try to declare them with uppercase.
Example:
Class Panel extends JPanel {}
Object:
Panel panel = new Panel()
Here you can clearly read which one is the class name and which is the object (instance of that class) of that class.
You declared a class called panel that you are not using anywhere. Please replace the line bwlow:
JPanel panel = new JPanel();
with:
SomePanel panel = new SomePanel();
Then, your class panel becomes SomePanel to follow correct class naming.
Some thoughts to help you:
Name your classes following the Java style
Don't use public fields
Set layouts on your panels. This time it worked for you as the default is FlowLayout.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class File
{
private JFrame frame1;
private JPanel panel1;
private JPanel panel2;
private JLabel labelWeight;
private JLabel labelHeight;
File()
{
frame1 = new JFrame();
panel1 = new JPanel();
panel2 = new JPanel();
labelWeight = new JLabel("Weight :");
labelHeight = new JLabel("Height :");
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
panel1.setLayout(new FlowLayout());
panel1.add(labelWeight);
panel2.setLayout(new FlowLayout());
panel2.add(labelHeight);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
frame1.setLayout(new BoxLayout(frame1,BoxLayout.X_AXIS));
panel1.setAlignmentY(0);
panel2.setAlignmentY(0);
frame1.add(panel1);
frame1.add(panel2);
frame1.setSize(400, 200);
frame1.setDefaultCloseOperation(frame1.EXIT_ON_CLOSE);
frame1.setVisible(true);
}
public static void main (String args[])
{
new File();
}
}
It gives BoxLayout Sharing error at runtime
Generally, LayoutManagers are set on a JPanel. I guess JFrame implements this method to forward it to the content pane of the frame. I would suggest you try:
Container contentPane = frame1.getContentPane();
contentPane.setLayout(new BoxLayout(contentPane,BoxLayout.X_AXIS));
If you still have problems take a look at the Swing tutorial on How to Use Box Layout for working examples.
Swing components should be created in the Event Dispatch Thread. Try this in your main():
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new File();
}
});
But your problem may be the same as this question.