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);
Related
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.
My JPanel and JTextField are for some reason not appearing. The programs only task is to add a number to the counter every time the button is clicked. No compiling errors nor console issues. Simply not showing up??
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Swing
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
final JFrame mainFrame = new JFrame ("Counter (Program 1/2)");
mainFrame.setVisible(true);
mainFrame.setSize(400, 200);
mainFrame.setLayout(new BorderLayout());
mainFrame.setLocationRelativeTo(null);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton countButton = new JButton("Count up");
mainFrame.add(countButton, BorderLayout.SOUTH);
countButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JTextField clicks = new JTextField(BorderLayout.CENTER);
JPanel firstPanel = new JPanel();
mainFrame.add(firstPanel);
mainFrame.add(clicks, BorderLayout.NORTH);
int counter = 1;
counter++;
String textField = String.valueOf(counter);
clicks.setText(textField);
}
});
}
});
}
}
Don't add the JTextField and JPanel inside the ActionListener. This makes no sense since you'll be re-adding new components each time the button is pressed. Instead add them on GUI creation, before calling setVisible(true) on the GUI. Then update the text field's text in the ActionListener.
As a side recommendation: try to make your class more object oriented by giving it fields, a constructor, and getting most all of that code out of the static main method.
Your mistakes:
Add clicks and firstpanel to the frame in run method, not in the actionPerformed
BorderLayout.CENTER should be pass as a parameter to add method, not to the text field constructor.
Define count as static. This is not the best way but in your situation it is the easiest way.
Call mainFrame.setVisible(true); after you added all your components.
Here is the working code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Swing {
public static int counter = 1;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final JFrame mainFrame = new JFrame("Counter (Program 1/2)");
mainFrame.setSize(400, 200);
mainFrame.setLayout(new BorderLayout());
mainFrame.setLocationRelativeTo(null);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton countButton = new JButton("Count up");
mainFrame.add(countButton, BorderLayout.SOUTH);
final JTextField clicks = new JTextField(String.valueOf(counter));
JPanel firstPanel = new JPanel();
mainFrame.add(firstPanel, BorderLayout.CENTER);
mainFrame.add(clicks, BorderLayout.NORTH);
countButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
counter++;
String textField = String.valueOf(counter);
clicks.setText(textField);
}
});
mainFrame.setVisible(true);
}
});
}
}
I'm having a problem trying to change JPanels by using buttons. I have a JFrame with 2 panels, 1 of them is for the buttons, which i want them to always be showed. The other one is the one that i will be switching everytime i press one ot the buttons of the other panel. The problem is that everytime i press them nothing really ever displays, i keep my buttons but the other panel that i call does not appear.
Code for one of the buttons is as follows
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
ReparacaoPanel r = new ReparacaoPanel(this, this.jPanel1);
this.getContentPane().remove(this.jPanel1);
this.getContentPane().add(r);
//this.setContentPane(r);
this.visiblePanel.setVisible(false);
this.visiblePanel = r;
this.pack();
this.setVisible(true);
r.setLocation(200, 200);
this.getContentPane().revalidate();
this.repaint();
}
If i try to use "this.setContentPane(r);" (it sets the frame to only show the panel) the panel shows. But when i try to call it as i'm trying to do in the code above nothing is showed apart from the panel that has the buttons.
I have no idea what i'm doing wrong, it does not seem to be a problem with the JPanel that i'm trying to call as it shows if used alone.
Anyone can help me out?
Consider this working example for switching manually between panels. Which produces this output.
.........
Some tiny NumberPanel
Every new instance shows another number in the center.
import javax.swing.JPanel;
public class NumberPanel extends JPanel {
private static int counter = 0;
public NumberPanel() {
setLayout(new BorderLayout(0, 0));
JLabel lblNewLabel = new JLabel("" + counter++);
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
add(lblNewLabel);
}
}
Setting up a frame
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.SOUTH);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.getContentPane().remove(numberPanel);
numberPanel = new NumberPanel();
frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
frame.pack();
}
});
panel.add(btnNewButton);
numberPanel = new NumberPanel();
frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
frame.pack();
}
Testprogram
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestPanelSwitch {
private JFrame frame;
private NumberPanel numberPanel;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TestPanelSwitch window = new TestPanelSwitch();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public TestPanelSwitch() {
initialize();
}
private void initialize() {
// see above
}
}
Back to the Question
I think you only need to pack your frame, like in the anonymous ActionListener.
frame.getContentPane().remove(numberPanel);
numberPanel = new NumberPanel();
frame.getContentPane().add(numberPanel, BorderLayout.CENTER);
frame.pack();
EDIT
As leonidas mentioned it is also possible to revalidate the frame. This requires only to replace the upper call to pack by theese.
frame.invalidate();
frame.validate();
What am I missing here?
public class abc extends JFrame {
private JButton save = new JButton("Save");
public abc() {
JPanel p = new JPanel();
save.addActionListener(new SaveL());
p.add(save);
Container cp = getContentPane();
p = new JPanel();
p.setLayout(new GridLayout(2, 1));
cp.add(p, BorderLayout.NORTH);
}
}
class SaveL implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Hello"); // nothing happens
}
}
Why doesn't my ActionListener work here
You are creating a JPanel, adding your JButton to it, then creating a new JPanel and adding that panel to your JFrame. You need to be adding the original panel to your content pane.
Your code is completely messed up. You instantiate your JPanel p twice, your button is declared "open" but is actually "save". You mix GridLayout with BorderLayour constraints. The following code works:
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;
public class abc extends JFrame {
private JButton save = new JButton("Save");
public abc() {
JPanel p = new JPanel();
save.addActionListener(new SaveL());
p.add(save);
p.setLayout(new GridLayout(2, 1));
add(p);
}
public static void main(String[] args) {
abc abc = new abc();
abc.pack();
abc.setVisible(true);
}
}
class SaveL implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Hello"); // nothing happens
}
}
Your code is re-creating the panel. It's losing the button.
I changed it to:
public class abc extends JFrame{
private JButton save = new JButton("Save");
public abc() {
JPanel p = new JPanel();
save.addActionListener(new SaveL());
p.add(save);
Container cp = getContentPane();
cp.add(p, BorderLayout.NORTH);
}
}
class SaveL implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Hello"); // nothing happens
}
}
and it worked
private JButton open = new JButton("Save");
save.addActionListener(new SaveL());
Did u declare your save as open?
here is how should my program be. In first frame, there is a textfield1 where a user input text and when he press a button, a new frame will be display with a textfield2 that displays the inputted text from the textfield1. please help me with the syntax. i'm still a beginner in java. much thanks guys.
First Frame:
textfield= new JTextField();
textfield.setPreferredSize( new Dimension(200,30) ) ;
textfield.setSize( textfield.getPreferredSize() ) ;
textfield.setLocation(95,198) ;
textfield.setSize(175,28);
cont.add(textfield);
public void actionPerformed(ActionEvent e) {
this.setVisible(false);
new Frame2().setVisible(true); //displays the 2nd frame right?
}
now i don't know what to do on my 2nd frame or where to start because i can't get the variable from the first frame
You can pass the desired variables in a constructor of Frame2:
Frame2 frame2 = new Frame2(textfield.getText());
frame2.setVisible(true);
All you need to do is - Define new constructor for second frame with textfield2:
public Frame2(String toDisplay){
textfield2 = new JTextField(toDisplay);
}
Try this:
(just copy into a new file named FrameTest.java in the default package)
import java.awt.Dimension;
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.JTextField;
public class FrameTest extends JFrame {
public static void main(String[] args) {
JFrame frame = new FrameTest();
frame.pack();
frame.setVisible(true);
}
public FrameTest() {
JPanel panel = new JPanel();
final JTextField textField = new JTextField();
textField.setPreferredSize(new Dimension(100, 20));
panel.add(textField);
JButton button = new JButton("press me");
panel.add(button);
setContentPane(panel);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
FrameTest.this.setVisible(false);
Frame2 secondFrame = new Frame2(textField.getText());
secondFrame.pack();
secondFrame.setVisible(true);
}
});
}
class Frame2 extends JFrame {
public Frame2(String text) {
getContentPane().add(new JTextField(text));
}
}
}