Recently I've attempted to make a simple program that would require moving a button across the screen several times, but in order to do this I have to be able to access the JPanel from certain parts of the code which I don't seem to be able to do, or find an alternative method. Here is a small program that should pinpoint the problems I'm having.
public class ButtonMover extends JFrame
{
public static void main(String[] args) {
new ButtonMover();
}
JButton actionButton;
public ButtonMover() {
JPanel buttonMoverPanel = new JPanel();
buttonMoverPanel.setLayout(new GridBagLayout());
this.add(buttonMoverPanel);
this.setSize(500,500);
this.setResizable(true);
this.setVisible(true);
JButton actionButton = new JButton("Testing Button");
buttonMoverPanel.add(actionButton);
ClickListener c = new ClickListener();
actionButton.addActionListener(c);
}
private class ClickListener
implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == actionButton)
buttonMoverPanel.add(new JLabel("Testing Label"));
//insert code to move button here
}
}
}
The |buttonMoverPanel.add(new JLabel("Testing Label"));| line is the only part that doesn't work, because I seem unable to make a reference to buttonMoverPanel from that area. While it doesn't actually cause any errors, it prevents actionButton from doing anything.
If you need to access a variable, here your buttonMoverPanel, then don't hide it by declaring it in a method or constructor making it only visible in that method or constructor. No, declare it in the class so that it is visible throughout the class.
So again, one improvement for this code is to declare the buttonMoverPanel in the class just the same as you're currently doing with your actionButton JButton.
Edit: you're shadowing your actionButton variable -- you're re-declaring it in the constructor, so that the button added to the GUI is not referred to by the actionButton class field. Don't re-declare it in the class.
In other words the line indicated creates a completely new actionButton variable, one that is only visible in the constructor:
JButton actionButton;
JPanel buttonMoverPanel = new JPanel();
public ButtonMover() {
buttonMoverPanel.setLayout(new GridBagLayout());
this.add(buttonMoverPanel);
this.setSize(500, 500);
this.setResizable(true);
this.setVisible(true);
JButton actionButton = new JButton("Testing Button"); // ****** here
The solution is to not re-declare the variable to rather to use the class field:
JButton actionButton;
JPanel buttonMoverPanel = new JPanel();
public ButtonMover() {
buttonMoverPanel.setLayout(new GridBagLayout());
this.add(buttonMoverPanel);
this.setSize(500, 500);
this.setResizable(true);
this.setVisible(true);
actionButton = new JButton("Testing Button"); // ****** Note the difference???
make buttonMoverPanel as class lavel variable as below..
public class ButtonMover extends JFrame
{
public static void main(String[] args) {
new ButtonMover();
}
JButton actionButton;
JPanel buttonMoverPanel ;
public ButtonMover() {
buttonMoverPanel = new JPanel();
buttonMoverPanel.setLayout(new GridBagLayout());
this.add(buttonMoverPanel);
this.setSize(500,500);
this.setResizable(true);
this.setVisible(true);
JButton actionButton = new JButton("Testing Button");
buttonMoverPanel.add(actionButton);
ClickListener c = new ClickListener();
actionButton.addActionListener(c);
}
private class ClickListener
implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == actionButton)
buttonMoverPanel.add(new JLabel("Testing Label"));
//insert code to move button here
}
}
}
Related
I have a button in a simple application I'm making which will increment a variable by one once pressed. This is it's code:
public class GUI implements ActionListener {
int clicks = 0;
int autoClickLevel = 0;
JLabel label;
JFrame frame;
JPanel panel;
public GUI() {
JButton button = new JButton("Click me!");
button.addActionListener(this);
panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(60, 100, 30, 100));
panel.setLayout(new GridLayout(0, 1));
panel.add(button);
frame.add(panel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
public static void main(String[] args) {
new GUI();
}
#Override
public void actionPerformed(ActionEvent e) {
clicks++;
}
I would like to know how to make a separate button (which I have already made, and it shows up; JButton button2 = new JButton("Click me too!");) which changes a separate variable. button2.addActionListener(this); [plus different ways of doing it,] instead increments the clicks variable instead of a separate clicks2 variable.
My code is a bit of a mess regarding this, and this second button's script doesn't work at all. I'm also fairly new to Java so I'm not much good at figuring out this either. What's a good way to make the second button increment the other variable?
Have different ActionListeners. You can do this like this:
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do something
}
});
Or you could define the ActionListener as its own class.
I've hit a problem in getting a JPanel to update.
My simple program uses a custom JPanel which displays a label and a textfield. A Jbutton on the main panel is used to replace the JPanel with a new JPanel. The initial panel shows up fine but when the button is pressed the panel is not updated with a new MyPanel. I can tell that a new object is being created as count is being incremented.
public class SwingTest extends JFrame{
private JPanel mp;
private JPanel vp;
private JButton button;
public static void main(String[] args) {
SwingTest st = new SwingTest();
}
public SwingTest() {
vp = new MyPanel();
mp = new JPanel(new BorderLayout());
mp.add(vp, BorderLayout.CENTER);
button = new JButton("Change");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
vp = new MyPanel();
vp.revalidate();
}
});
mp.add(button, BorderLayout.SOUTH);
this.add(mp);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setSize(250, 150);
pack();
setVisible(true);
}
}
and my custom panel....
public class MyPanel extends JPanel{
private JLabel label;
private JTextField tf;
static int count = 0;
public MyPanel(){
count++;
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
setPreferredSize(new Dimension(400, 200));
c.gridx = 0;
c.gridy = 0;
label = new JLabel(String.valueOf(count));
tf = new JTextField(10);
add(label,c);
c.gridx = 1;
add(tf, c);
}
}
You state:
A Jbutton on the main panel is used to replace the JPanel with a new JPanel.
And yet this code:
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
vp = new MyPanel();
vp.revalidate();
}
});
and yet this code does not do this at all. All it does is change the JPanel referenced by the vp variable, but has absolutely no effect on the JPanel that is being displayed by the GUI, which suggests that you're confusing reference variable with reference or object. To change the JPanel that is displayed, you must do exactly this: add the new JPanel into the container JPanel into the BorderLayout.CENTER (default) position, then call revalidate() and repaint() on the container.
e.g.,
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
// vp = new MyPanel();
// vp.revalidate();
mp.remove(vp); // remove the original MyPanel from the GUI
vp = new MyPanel(); // create a new one
mp.add(vp, BorderLayout.CENTER); // add it to the container
// ask the container to layout and display the new component
mp.revalidate();
mp.repaint();
}
});
Or better still -- use a CardLayout to swap views.
Or better still -- simply clear the value held by the JTextField.
For more on the distinction between reference variable and object, please check out Jon Skeet's answer to this question: What is the difference between a variable, object, and reference?
I'm new in Java programming language and I try to write a simple code
public class TextPanel extends JPanel {
private JTextArea textArea;
public TextPanel() {
textArea = new JTextArea();
setLayout(new BorderLayout());
setVisible(true);
add(new JScrollPane(textArea), BorderLayout.CENTER);
}
public String getTextAreaText() {
String text = textArea.getText();
return text;
}
}
And I added an action listener to star button (startBtn) but when I run the program nothing is shown in console even if i put a System.out.println(textPanel.getTextAreaText()) in actionPerformed() method (code below).
public class Toolbar extends JPanel {
private JButton startBtn;
private JButton stopBtn;
private TextPanel textPanel;
public Toolbar() {
startBtn = new JButton("Start");
stopBtn = new JButton("Stop");
textPanel = new TextPanel();
setLayout(new FlowLayout(FlowLayout.LEFT));
add(startBtn);
add(stopBtn);
startBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println(textPanel.getTextAreaText());
}
});
}
}
I need help to fix this.
Java programs require a public static main method to run. Your code does not have this, and so there is no start point for your program.
Swing GUI's require that components be placed in a top-level window such as a JFrame and that this window be displayed for the components to be seen. Your code does not have this.
You will want to read the Java and Swing tutorials as all of this is very well explained there, complete with sample code.
For decent resources, please check out the info section of your Java and Swing tags:
Java info
Swing info
So consider adding a main method that creates your JFrame and adds components to the JFrame, something like:
private static void createAndShowGui() {
JFrame frame = new JFrame("My JFrame");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// add your components to your JFrame here
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
// the main method which Java uses as the starting point for your program
public static void main(String[] args) {
// let's call our Swing GUI in a thread-safe manner
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
Edit
Your code also shows possible variable shadowing. You create a TextPanel object inside of your Toolbar class, but you add this TextPanel to nothing. This suggests that you may have a TextPanel object elsewhere that is being displayed (and we can only guess because it appears that you're not showing enough code for us to know for sure). If so, then pressing your start button will get the text from a non-displayed Toolbar's JTextArea. Instead consider passing a TextPanel reference into Toolbar, something like this:
class Toolbar extends JPanel {
private JButton startBtn;
private JButton stopBtn;
private TextPanel textPanel;
public Toolbar() {
startBtn = new JButton("Start");
stopBtn = new JButton("Stop");
// textPanel = new TextPanel(); // *** note change
setLayout(new FlowLayout(FlowLayout.LEFT));
add(startBtn);
add(stopBtn);
startBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
if (textPanel != null) {
System.out.println(textPanel.getTextAreaText());
}
}
});
}
// **** note this method ****
public void setTextPanel(TextPanel textPanel) {
this.textPanel = textPanel;
}
}
And then when creating your objects, pass in your reference:
private static void createAndShowGui() {
Toolbar toolBar = new Toolbar();
TextPanel textPanel = new TextPanel();
toolBar.setTextPanel(textPanel); // ****** passing in my reference *******
JFrame frame = new JFrame("Add New Lines");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(textPanel);
frame.getContentPane().add(toolBar, BorderLayout.PAGE_START);
frame.pack();
frame.setLocationByPlatform(true);
frame.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.
I am trying to get a JLabel to appear when a JButton is clicked. I have added an action listener and added the component to the layout. I am using the label1.setVisible(true) when the JButton is clicked in actionPerformed. I still can't get it work. Can some look at my code?
public class LearnAppMain extends JFrame implements ActionListener {
// Define variables
public JButton button1;
public JLabel label1;
public JTextField field1;
private Image image1;
private String apple = "apple.jpg";
public LearnAppMain() {
ImageIcon image1 = new ImageIcon(this.getClass().getResource(apple));
JLabel label1 = new JLabel(image1);
button1 = new JButton("A");
button1.addActionListener(this);
field1 = new JTextField(10);
// Create layout
setLayout(new FlowLayout());
// create Container
final Container cn = getContentPane();
cn.add(button1);
cn.add(field1);
cn.add(label1);
// setLayout(new FlowLayout());
setSize(250, 250);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (e.getSource() == button1) {
label1.setVisible(true);
field1.setText("Apple");
}
}
}
I have my main method in another class file. The error I get leads me to the label1.setVisible(true);
Every question I've seen they say to do this, but I'm wondering if there is something else that needs to be added.
There were a couple of issues here:
Your label1 was hidden by doing JLabel label in the constructor. You basically declared another variable called label1 in your constructor that hid the one in the class itself.
Your label was visible on the startup - I used label.setVisible(false) for the test, but you might want otherwise
I also put the creation of Image aside as I did not have an image, so uncomment that and change as appropriate.
Here's a complete working version:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LearnAppMain extends JFrame implements ActionListener {
// Define variables
public JButton button1;
public JLabel label1;
public JTextField field1;
private Image image1;
private String apple = "apple.jpg";
public LearnAppMain() {
//ImageIcon image1 = new ImageIcon(this.getClass().getResource(apple));
//JLabel label1 = new JLabel(image1);
label1 = new JLabel("hello");
label1.setVisible(false);
button1 = new JButton("A");
button1.addActionListener(this);
field1 = new JTextField(10);
// Create layout
setLayout(new FlowLayout());
// create Container
final Container cn = getContentPane();
cn.add(button1);
cn.add(field1);
cn.add(label1);
// setLayout(new FlowLayout());
setSize(250, 250);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (e.getSource() == button1) {
label1.setVisible(true);
field1.setText("Apple");
}
}
public static void main(String[] args) {
new LearnAppMain();
}
}
I'd suggest using separate (usually inner-class) ActionListener instances instead of overriding actionPerformed. See e.g. this for a similar example if you are interested:
http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/events/BeeperProject/src/events/Beeper.java
Also, if you are using this in a bigger application (i.e. not just experimenting or for prototyping), make sure all Swing code is run on EDT.
You typically use SwingUtilities.invokeLater for that purpose.
Hope this helps.
first you don't add the image first itself to JLabel.
just create the object and leave it like..
ImageIcon image1 = new ImageIcon(this.getClass().getResource(apple));
JLabel label1 = new JLabel("");
label1.setVisible(true);
then do the modification in the action performed
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button1)
{
field1.seticon(image1);
field1.revalidate();
}
it will definitely works
clientDetail.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e){
d.getContentPane().removeAll();
g = new GridBagLayout();
gc = new GridBagConstraints();
d.setLayout(g);
JLabel message= new JLabel(" Message");
addComponent(message,5,1,1,2);
JTextArea Message = new JTextArea();
addComponent(Message,5,1,1,2);
d.setVisible(true);
d.setVisible(true);
d.pack();
}
private void addComponent(Component component, int i, int i0, int i1, int i2) {
gc.gridx=i;
gc.gridy=i0;
gc.gridheight=i1;
gc.gridwidth=i2;
g.setConstraints(component, gc);
add(component);
}
});
Recep.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
}
});