Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last month.
Improve this question
I'm trying to use the actionPerformed method to print a message to the corresponding buttons (in this case b1/b2/b3). I have no idea where exactly in the code the issue lies.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class B_HangMan implements ActionListener {
JButton b1;
JButton b2;
JButton b3;
public static void main(String[] args) {
JPanel mainPanel = new JPanel();
JFrame frame1 = new JFrame();
frame1.setSize(900, 500);
frame1.setLocation(500, 200);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setVisible(true);
frame1.add(mainPanel);
mainPanel.setLayout(null);
// button 1
JButton b1 = new JButton("1");
b1.setBounds(20, 20, 90, 90);
b1.addActionListener(new B_HangMan());
mainPanel.add(b1);
// button 2
JButton b2 = new JButton("2");
b2.setBounds(130, 20, 90, 90);
b2.addActionListener(new B_HangMan());
mainPanel.add(b2);
// button 3
JButton b3 = new JButton("3");
b3.setBounds(240, 20, 90, 90);
b3.addActionListener(new B_HangMan());
mainPanel.add(b3);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
System.out.println("button 1 was clicked");
}
if (e.getSource() == b2) {
System.out.println("button 2 was clicked");
}
if (e.getSource() == b3) {
System.out.println("button 3 was clicked");
}
}
}
The console should display which one was pressed when clicking on the different buttons. Nothing happens instead.
The comment, by #MadProgrammer, is telling you why nothing happens when you click on any of the buttons, namely that your code contains shadowing (not to be confused with hiding). In other words, you have local variables with the same declaration as member variables.
I don't know how you are learning Swing but it is a vast API and the quintessential tutorial is this one:
Creating a GUI With Swing
which is part of Oracle's Java tutorials.
There are also several books devoted entirely to Swing.
mainPanel.setLayout(null);
You usually don't need to use a null layout. I believe that FlowLayout is appropriate for displaying your buttons.
Also, since Java 8, you can implement ActionListener with a method reference.
Here is my rewrite of your code which aims to show you several other features of Swing, apart from fixing your problem whereby clicking on any of the buttons does nothing.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class HangmanB {
private void buildAndShowGui() {
JFrame frame = new JFrame("Hangman");
URL url = getClass().getResource("hangman16.png");
try {
Image img = ImageIO.read(url);
frame.setIconImage(img);
}
catch (IOException xIo) {
xIo.printStackTrace();
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createButtonsPanel(), BorderLayout.PAGE_START);
frame.setSize(900, 500);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JButton createButton(String text, int mnemonic, ActionListener listener) {
JButton b = new JButton(text);
b.setPreferredSize(new Dimension(90, 90));
b.setMnemonic(mnemonic);
b.addActionListener(listener);
return b;
}
private JPanel createButtonsPanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING, 20, 5));
panel.setBorder(BorderFactory.createEmptyBorder(12, 8, 0, 0));
panel.add(createButton("1", KeyEvent.VK_1, this::handleButton1));
panel.add(createButton("2", KeyEvent.VK_2, this::handleButton2));
panel.add(createButton("3", KeyEvent.VK_3, this::handleButton3));
return panel;
}
private void handleButton1(ActionEvent event) {
System.out.println("button 1 was clicked");
}
private void handleButton2(ActionEvent event) {
System.out.println("button 2 was clicked");
}
private void handleButton3(ActionEvent event) {
System.out.println("button 3 was clicked");
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new HangmanB().buildAndShowGui());
}
}
Here is a screen capture of the GUI when I run the above code:
Related
I have a JPanel with a CardLayout and two cards. I want the layout to flip the cards each time the mouse enters or exits the panel.
This works fine unless one of the cards is a component that listens for mouse events. Consider the following example:
JPanel cardLayoutPanel = new JPanel(layout);
JButton button = new JButton("listening!");
JLabel label = new JLabel("not listening.");
cardLayoutPanel.add(button);
cardLayoutPanel.add(label);
layout.last(cardLayoutPanel);
cardLayoutPanel.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
System.out.println("entered!");
layout.next(cardLayoutPanel);
}
#Override
public void mouseExited(MouseEvent e) {
System.out.println("exited!");
layout.next(cardLayoutPanel);
}
});
The problem is that, if the MouseEvent is catched by a child component, it is not processed by the parent as a read in many SO-questions related to this topic.
I tried different things like redispatching the event or just ignoring the exit event if the event if the event coordinates are still in the panel.
The first solution does not work at all, the second neither since then the mouse entered event does not occur anymore.
How can i solve this?
The only solution that I see right now would be to completely remove the listener from the child component and perform the collision and event handling on my own in the parents mouse mouse listener, but this would be a mess and not the intended way to do this, i guess.
Any help or ideas appreciated.
EDIT: here is a complete short compilable example:
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class CardLayoutTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel content = new JPanel();
content.setBorder(new EmptyBorder(new Insets(50, 50, 50, 50)));
CardLayout layout = new CardLayout();
JPanel cardLayoutPanel = new JPanel(layout);
JButton button = new JButton("listening!");
JLabel label = new JLabel("not listening.");
cardLayoutPanel.add(button);
cardLayoutPanel.add(label);
layout.last(cardLayoutPanel);
cardLayoutPanel.addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
System.out.println("entered!");
layout.next(cardLayoutPanel);
}
#Override
public void mouseExited(MouseEvent e) {
System.out.println("exited!");
layout.next(cardLayoutPanel);
}
});
content.add(cardLayoutPanel);
frame.add(content);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
I modified your example slightly and got it to work. The key (at least in this example), was to have the button share the same mouseListener with the cardLayoutPanel. I do not know if this is a universal solution but it does work here. I also made the following changes:
added a private innner class for the mouseListener.
Increased the size of the cardLayoutPanel.
Added color borders to the Label and Button.
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class CardLayoutTest {
JButton button = new JButton("listening!");
JPanel cardLayoutPanel = new JPanel();
CardLayout layout = new CardLayout();
public static void main(String[] args) {
new CardLayoutTest().start();
}
public void start() {
JFrame frame = new JFrame();
JPanel content = new JPanel();
content.setBorder(new EmptyBorder(
new Insets(50, 50, 50, 50)));
cardLayoutPanel.setLayout(layout);
cardLayoutPanel
.setPreferredSize(new Dimension(200, 200));
button.addActionListener(
ae -> System.out.println("IT WORKS!"));
button.removeMouseMotionListener(
button.getMouseMotionListeners()[0]);
button.removeMouseListener(
button.getMouseListeners()[0]);
MyMouseListener ml = new MyMouseListener();
button.addMouseListener(ml);
button.setBorder(new LineBorder(Color.red, 2));
JLabel label = new JLabel("not listening.");
label.setBorder(new LineBorder(Color.blue, 2));
cardLayoutPanel.add(button);
cardLayoutPanel.add(label);
layout.last(cardLayoutPanel);
cardLayoutPanel.addMouseListener(ml);
content.add(cardLayoutPanel);
frame.add(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private class MyMouseListener extends MouseAdapter {
#Override
public void mouseEntered(MouseEvent e) {
System.out.println("entered!");
layout.next(cardLayoutPanel);
}
public void mouseClicked(MouseEvent e) {
if (e.getSource() instanceof JButton) {
JButton b = (JButton)(e.getSource());
b.doClick();
}
}
#Override
public void mouseExited(MouseEvent e) {
System.out.println("exited!");
layout.next(cardLayoutPanel);
}
}
}
It is not quiet a good solution but i managed to achieve what i want by calling the flip event when entering the parent component. This works since i have enough space between my panels with this property.
I did not, however, managed to achieve this effect with glass panes as suggested in a comment. Maybe I was doing it wrong, but the events did not arrive at the components properly, even some instanceof checks failed out of nowhere.
If someone knows how to do this properly I would be glad to see.
This question already has answers here:
Java ActionListener error: incompatible types
(4 answers)
Closed 4 years ago.
I've just recently started learning code in Java. I encountered a problem with adding a listener.I have been struggling with this problem for an hour but I couldn't find the solution.Could someone make a look and see whats wrong please. Here's my code:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.HeadlessException;
import java.awt.event.ItemEvent;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MultiListenerFrame extends JFrame {
JPanel panel;
JLabel label;
JCheckBox button1;
JCheckBox button2;
JCheckBox button3;
public MultiListenerFrame() throws HeadlessException {
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setSize(600,500);
panel = new JPanel();
panel.setLayout(new FlowLayout());
add(BorderLayout.NORTH, panel);
button1 = new JCheckBox("button1");
button2 = new JCheckBox("button2");
button3 = new JCheckBox("button3");
panel.add(button1);
panel.add(button2);
panel.add(button3);
button1.addActionListener(this); // here is my problem
}
public void itemStateChanged(ItemEvent e) {
Object source = e.getItemSelectable();
if(source == button1) {
label.setText("Hello");
} else if (source == button2) {
label.setText("world");
} else if(source == button23) {
label.setText("!!!");
}
}
public static void main(String[] args) {
MultiListenerFrame frame = new MultiListenerFrame();
frame.setVisible(true);
}
}
You're not adding an ActionListener. this refers to your MultiListenerFrame class.
Define a listener somewhere and add that:
this.button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO something
}
});
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 6 years ago.
ok so thats what ive got
jTextField1.setBounds(136, 24, 17, 17);
jTextField1.setEditable(false);
jTextField1.setText("x");
jTextField1.setBorder(javax.swing.BorderFactory.createEmptyBorder());
jTextField1.setHorizontalAlignment(SwingConstants.CENTER);
jTextField1.setFont(new Font("Dialog", Font.PLAIN, 16));
jTextField1.setBackground(Color.WHITE);
jTextField1.setOpaque(false);
cp.add(jTextField1);
[...]
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "+") {
plus = true; // [...]
If e.getActionCommand() = + i want to change the text of the jTextField. Is that possible? What alternatives are there?
thx in advance
EDIT: Well you already used the setText() method of the JTextField. To be able to access the JTextField from within the ActionPerformed() Method of the ActionListener the JTextField is made global.
The ActionLister and its code could look like this:
package jTextField;
import java.awt.Color;
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 SetTextOfJTextField extends JFrame implements ActionListener{
boolean plus = false;
JPanel panel = new JPanel();
JTextField jTextField1;
public static void main(String[] args){
new SetTextOfJTextField();
}
public SetTextOfJTextField(){
this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
jTextField1 = new JTextField(10);
jTextField1.setEditable(false);
jTextField1.setText("x");
jTextField1.setBorder(javax.swing.BorderFactory.createEmptyBorder());
jTextField1.setBackground(Color.WHITE);
jTextField1.addActionListener(this);
jTextField1.setEditable(true); // this is necessary so the text can be changed by the user!
JButton button = new JButton("OK");
button.addActionListener(this);
/* configure JFrame / Jpanel*/
panel.add(jTextField1);
panel.add(button);
this.add(panel);
this.pack();
this.setSize(200,200);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
System.out.println("ouch! dont click me!");
if (jTextField1.getText().equals("+")) {
plus = true;
System.out.println("received plus!");
// change text of jTextField1
jTextField1.setText("hi i am new text!");
}
else{
jTextField1.setText("");
}
}
}
Now run the code. If you enter a + sign in the Textfield and press OK the Text will change. Press the OK button once more and the text will be reset.
Happy coding!
Write a program that shows a window with three button. Each button has a name like “Red” , “Green” and “Blue”. In this window, there is also a label. The label contains an icon. This icon must be a CompositeIcon where in the beginning is empty. Every time you press on a button you can see a square with the button color like for an example “press blue button -> a blue square appears on the window”.
So far I have this. I have the three buttons with their color name. I every time I press one of the buttons it does not work. What do I need to do?
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ActionTester{
public static void main(String[] args){
JFrame frame = new JFrame();
final JTextField textField = new JTextField();
JButton RedButton = new JButton("Red");
RedButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
SquareIcon red = new SquareIcon(20,Color.RED);
CompositeIcon ci = new CompositeIcon();
ci.addIcon(red);
}
});
JButton GreenButton = new JButton("Green");
GreenButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
SquareIcon green = new SquareIcon(20,Color.GREEN);
CompositeIcon ci = new CompositeIcon();
ci.addIcon(green);
}
});
JButton BlueButton = new JButton("Blue");
BlueButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
SquareIcon blue = new SquareIcon(20,Color.BLUE);
CompositeIcon ci = new CompositeIcon();
ci.addIcon(blue);
}
});
frame.setLayout(new FlowLayout());
frame.add(RedButton);
frame.add(GreenButton);
frame.add(BlueButton);
frame.add(textField);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
All you need to do is to create one Square Object that you change in the ActionListener like:
final JPanel sqr = new JPanel();
JButton RedButton = new JButton("Red");
RedButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
sqr.setBackground(Color.RED);
}
});
And dont forget to add sqr to the frame
On another note, please avoid using imports like
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
In my project it came down to
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
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;
Some IDEs can sort you imports automaticly so you dont need to bother with the most common imports anymore
the buttons itself work but you never add the compositeicon to your frame. therefore nothing is displayed
im trying to add an ActionListener to my buttons for my calculator Im making. The problem is that Im being presented an error when I try to make an ActionListener. I tried in one class then I created a listener class just to see if that would help. Here is my code:
package main;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public abstract class Main extends JFrame implements Listener{
public static void main(String[] args) throws IOException{
//Main variables
String dis = "0";
double ans = Double.parseDouble(dis);
//Making frames
JFrame frame = new JFrame("Calculator");
JPanel panel = new JPanel();
//Buttons
JButton enter = new JButton("Enter");
JButton sub = new JButton("-");
JButton add = new JButton("+");
JButton div = new JButton("÷");
JButton mult = new JButton("*");
JTextField text = new JTextField(dis);
//Font
Font bigFont = text.getFont().deriveFont(Font.PLAIN, 30f);
Font butf = text.getFont().deriveFont(Font.PLAIN, 20f);
//Methods
panel.setLayout(new FlowLayout());
panel.add(text);
panel.setSize(590, 100);
text.setColumns(22);
text.setFont(bigFont);
text.setHorizontalAlignment(JTextField.RIGHT);
text.setEditable(false);
enter.setForeground(Color.RED);
sub.setForeground(Color.RED);
div.setForeground(Color.RED);
mult.setForeground(Color.RED);
add.setForeground(Color.RED);
//Buttons Methods
enter.setBounds(470, 450, 100, 150);
sub.setBounds(470, 350, 100, 90);
div.setBounds(470, 250, 100, 90);
mult.setBounds(470, 150, 100, 90);
add.setBounds(470, 50, 100, 90);
enter.setFont(butf);
sub.setFont(butf);
div.setFont(butf);
mult.setFont(butf);
add.setFont(butf);
//Frame
frame.add(div);
frame.add(mult);
frame.add(sub);
frame.add(enter);
frame.add(add);
frame.add(panel);
frame.setSize(600, 650);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
//extra
text.setSize(1000, 100);
//Actions
}
}
package main;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public interface Listener extends ActionListener {
//Throwing error here 'Cant instantiate the type ActionListener'
ActionListener al = new ActionListener();
public default void actionPerformed(ActionEvent e){
}
}
Anyone know how to fix this error?
To declare an ActionListener use
public class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//dostuff
}
}
ActionListener is a interface, it can't be instantiated, without provide a concrete implementation of it's contract
interfaces can't contain instance fields
Simply speaking, it should look more like...
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public interface Listener extends ActionListener {
public default void actionPerformed(ActionEvent e) {
}
}
You may also like to have a closer look at
How to Write an Action Listeners
What Is an Interface?
The Interfaces trail
In Swing, you should make sure that your UI is only created and manipulated from within the context of the Event Dispatching Thread. Have a look at Initial Threads for more details
You're also going to be very disappointed with the results of your layout, have a look at Laying Out Components Within a Container for better solutions