I wanted to change text in a JTextField by using actionlistener on a button.
there is a radiobutton group and Sort.SWITCH changes its value according to radiobutton selected.
So when sort button is pressed the text in Output field must change from "Output" to "Some text"..
but the error is that Output field cannot be accessed from innerclass. Plz tell me the proper way to do that. thanks..
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Sort extends JFrame
{
...
}
class q2 extends Sort
{
public static void main(String[] args)
{
...
JTextField Output = new JTextField(50);
Output.setText("Output");
ResultPanel.add(Output);
SortButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a)
{
if (Sort.SWITCH == 1)
{
Output.setText("Some Text");
}
else if ...
...
} });
}}
To access your variable from inside the anonymous class, define the variable as a field (instead of a local variable), or as final:
public static void main(String[] args){
//...
final JTextField Output = new JTextField(50);
Anonymous inner-classes may only access fields or final variables from the defining class.
Define Output as a class field:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Sort extends JFrame
{
...
}
class q2 extends Sort
{
public JTextField Output;
public static void main(String[] args)
{
...
Output = new JTextField(50);
Output.setText("Output");
ResultPanel.add(Output);
SortButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent a)
{
if (Sort.SWITCH == 1)
{
Output.setText("Some Text");
}
else if ...
...
} });
}
}
Related
Given the following scenario:
one has a JComboBox and a JTextField
the latter has an InputVerifier providing its own error message.
the textField is the current focus owner and its input does not satisfy the inputVerifier (Here: Less than 3 characters).
Now you click on the combo, which will fire the InputVerifier.
The InputVerifier in turn will show its error message.
You acknowledge the error message and, lo and behold, the combo's popup appears, ready to accept a selection.
To me this is an undesired behaviour, and I would prefer to have no other
component change its input until the inputVerifier is satisfied. Paticularly
in the described scenario the JComboBox could have its own ActionListener
changing the whole situation in case of a new selection.
The following code solves this problem by applying a PopupMenuListener, which
checks a boolean in the verifier telling its state, and then decides whether to
show the popup or not.
What I would like to do now is to write an extended JComboBox class implementing this functionality and accepting all kinds of (extended) InputVerifiers. But I
am already stuck in my test code here, for I don't see a way how to give the
PopupMenuListener access to the verifers' boolean 'satisfied' in a general way.
Passing just an InputVerifier as parameter would need casting later, which
unmakes the generality. - Or is there any "variable" casting?
Any idea is welcome, even if it is a completely different approach to the initial problem.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.*;
public class DisableComboPopupByVerifier extends JFrame {
public static final long serialVersionUID = 100L;
JComboBox<String> cmb;
public DisableComboPopupByVerifier() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(450, 240);
setLocationRelativeTo(null);
setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2));
cmb= new JComboBox<>(new String[]{"AA", "BB", "CC"});
cmb.setPreferredSize(new Dimension(43, 20));
MyMinLenVerifier verifier= new MyMinLenVerifier(this, 3);
MyPopupListener popupListener= new MyPopupListener(verifier);
cmb.addPopupMenuListener(popupListener);
add(cmb);
JTextField tf1= new JTextField(5);
tf1.setInputVerifier(verifier);
add(tf1);
JTextField tf2= new JTextField(5);
tf2.setInputVerifier(verifier);
add(tf2);
SwingUtilities.invokeLater(() -> tf1.requestFocusInWindow());
setVisible(true);
}
static public void main(String args[]) {
EventQueue.invokeLater(DisableComboPopupByVerifier::new);
}
class MyMinLenVerifier extends InputVerifier {
boolean satisfied;
int minlen;
Component parent;
public MyMinLenVerifier(Component parent, int minlen) {
this.minlen= minlen;
this.parent= parent;
}
public boolean verify(JComponent input) {
String s= ((JTextField)input).getText();
if (s.length()>=minlen) {
satisfied= true;
}
else {
satisfied= false;
JOptionPane.showMessageDialog(parent,
"Enter at least "+minlen+" characters.",
"Error", JOptionPane.ERROR_MESSAGE);
}
return satisfied;
}
}
class MyPopupListener implements PopupMenuListener {
//** To accept all kinds of verifiers the specific one here needs to be replaced
by the super class InputVerifier, which, however, makes casting necessary to access the boolean 'satisfied' below.
**//
MyMinLenVerifier verifier;
public MyPopupListener(MyMinLenVerifier verifier) {
this.verifier= verifier;
}
public void popupMenuCanceled(PopupMenuEvent e) {
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
//** boolean 'satisfied' is a requirement in all passed verifiers. **//
if (!verifier.satisfied) {
BasicComboPopup popup= (BasicComboPopup)cmb.getUI()
.getAccessibleChild(cmb, 0);
SwingUtilities.invokeLater(() -> {
popup.setVisible(false);
// This restauration of the button background is not reliable!
MetalComboBoxButton btn= (MetalComboBoxButton)cmb.getComponent(0);
btn.getModel().setPressed(false);
btn.repaint();
((JComboBox)e.getSource()).repaint();
});
}
}
}
}
For lack of a better idea I overrode toString() in MyMinLenVerifier
#Override
public String toString() {
return "satisfied:"+satisfied;
}
And the MyPopupListener class looks now like this:
class MyPopupListener implements PopupMenuListener {
InputVerifier verifier;
public MyPopupListener(InputVerifier verifier) {
this.verifier= verifier;
}
.
.
.
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
if (verifier.toString().endsWith("false")) {
...
I'm currently in a java class and I'm trying to work on build a my first interface. The one below is not the one I'm working on, but a test one so I can figure out how to do what I want to do. Here is the code, the question will follow:
package test;
import java.awt.*;
import java.awt.event.*;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.*;
/**
*
* #author StrifeX
*/
public class Test {
public static class buttonTest extends JFrame {
private int number;
private JButton push;
public ButtonTest(){
setLayout(new GridBagLayout ());
//Creates an instance of the layout
GridBagConstraints panel = new GridBagConstraints();
// Establishes the pixels suronding each object within the layout
panel.insets = new Insets (5, 5, 5, 5);
//create the withdraw button and its properties
push = new JButton("push");
panel.fill = GridBagConstraints.HORIZONTAL;
panel.gridx = 0;
panel.gridy = 0;
panel.gridwidth = 1;
add(push, panel);
MyEvent buttonClick = new MyEvent();
push.addActionListener(buttonClick);
}//end constructor
public class MyEvent implements ActionListener {
public void actionPerformed (ActionEvent buttonClick){
String operation = buttonClick.getActionCommand();
if(operation.equals("Withdraw")){
JOptionPane.showMessageDialog( null, "test" );
}
}
}
}//end button test
public static class TestObject{
int testField;
public void testObject(){
testField = 10;
}
public void setterMethod(int newInt){
this.testField = newInt;
}
public int getterMethod(){
return this.testField;
}
}
public static void main(String[] args)
{
TestObject obj1 = new TestObject();
buttonTest button = new buttonTest();
// Establish basic parameters for the GUI
button.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.setLocationRelativeTo(null);
button.setVisible(true);
button.setSize(450, 350);
button.setTitle("Change the Balance");
}
}
What I want to do is build an object, then use that objects methods with the GUI button. I can build the object, and pass it to the constructor that make the GUI (buttonTest), but the Event class cant see that object, and from the little I know, I can't pass it to the event class, but maybe the actionPerformed method like this:
public void actionPerformed (ActionEvent buttonClick, testObject thing)
However, when I tried to do that, I received and error that said
buttonTest.event is not abstract and does not override abstract method
actionPerformed(actionEvent) in ActionListener.
Any help would be greatly appreciated. Thank you.
The problem is wrongly defined the following:
public void actionPerformed (ActionEvent buttonClick, testObject thing)
The correct definition will be:
public void actionPerformed (ActionEvent buttonClick)
Getting passed all your previous issues and getting to the heart of the question
Passing objects to a gui in java
You basically need to pass the TestObject to all the classes which need access to it.
Start by modifying your MyEvent class to take a reference to TestObject
public class MyEvent implements ActionListener {
private TestObject obj;
public MyEvent(TestObject obj) {
this.obj = obj;
}
#Override
public void actionPerformed(ActionEvent buttonClick) {
String operation = buttonClick.getActionCommand();
// Now you have acces to obj
if (operation.equals("Withdraw")) {
JOptionPane.showMessageDialog(null, "test");
}
}
}
This will require you to modify your ButtonTest class to allow it to pass the TestObject through to the event handler...
public static class ButtonTest extends JFrame {
//...
public ButtonTest(TestObject obj) {
//...
MyEvent buttonClick = new MyEvent(obj);
//...
And finally, you create and pass the object to the instance of ButtonTest which needs it
public static void main(String[] args) {
TestObject obj1 = new TestObject();
ButtonTest button = new ButtonTest(obj1);
// Establish basic parameters for the GUI
button.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.setLocationRelativeTo(null);
button.setVisible(true);
button.setSize(450, 350);
button.setTitle("Change the Balance");
}
I have 2 classes, the first class is where I am creating GUI and all of the components needed. Including the buttons. This is being done outside of the main method and in there own respective methods. I want to .addActionListener, but from another class outside of this one. I do not want to use inner classes.
Here is the classes containing Main and the Gui components and the button.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class PasswordGeneratorGui {
private JFrame interfaceFrame;
private JPanel interfacePanel;
private JMenuBar interfaceMenuBar;
private JMenu interfaceMenu;
private JMenuItem interfaceMenuItemFile;
private JButton interfaceButtonGenerate;
public static void main(String[] args) {
new PasswordGeneratorGui();
}
public PasswordGeneratorGui() {
createInterfacePanel();
createInterfaceFrame();
createInterfaceMenuBar();
createInterfaceMenu();
createInterfaceMenuItem();
createInterfaceButton();
PasswordGeneratorButtonHandler b = new PasswordGeneratorButtonHandler();
interfaceFrame.add(interfacePanel);
interfaceFrame.setVisible(true);
}
public void createInterfacePanel() {
interfacePanel = new JPanel();
interfacePanel.setLayout(null);
}
public void createInterfaceFrame() {
interfaceFrame = new JFrame();
interfaceFrame.setTitle("Password Generator");
interfaceFrame.setBounds(50, 50, 700, 400);
interfaceFrame.setResizable(false);
interfaceFrame.setJMenuBar(interfaceMenuBar);
}
public void createInterfaceMenuBar() {
interfaceMenuBar = new JMenuBar();
interfaceMenuBar.setBounds(0, 0, 700, 20);
interfaceMenuBar.setVisible(true);
interfacePanel.add(interfaceMenuBar);
}
public void createInterfaceMenu() {
interfaceMenu = new JMenu("File");
interfaceMenuBar.add(interfaceMenu);
}
public void createInterfaceMenuItem() {
interfaceMenuItemFile = new JMenuItem("Exit");
interfaceMenu.add(interfaceMenuItemFile);
}
**public void createInterfaceButton() {
interfaceButtonGenerate = new JButton("Generate");
interfaceButtonGenerate.setBounds(0, 358, 700, 20);
interfaceButtonGenerate.addActionListener();
interfacePanel.add(interfaceButtonGenerate);
}**
}
Here is the class for the ActionListener
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PasswordGeneratorButtonHandler implements ActionListener {
PasswordGeneratorButtonHandler generate = new PasswordGeneratorButtonHandler();
public PasswordGeneratorButtonHandler() {
}
public void interfaceButtonGenerateHandler(ActionEvent event) {
System.exit(1);
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
I just want to be able to call the AcitonListener method from the second class. I have tried initiating a new instance of the class and calling it however I think I wasn't quite going in the correct direction.
I'm a little confused about what your asking. You said
I just want to be able to call the AcitonListener method from the second class
Taken literally this means that while you're inside of the PasswordGeneratorButtonHandler class, you want to call the actionPerformed() method. If so, just use this.actionPerformed(), where this is a special keyword in java, representing the current instance of your class.
If however you want to add your handler to the button you created in the first class, which seems like what you might want to do, then you just need to call the JButton#addActionListener() method.
public PasswordGeneratorGui() {
createInterfacePanel();
createInterfaceFrame();
createInterfaceMenuBar();
createInterfaceMenu();
createInterfaceMenuItem();
createInterfaceButton();
PasswordGeneratorButtonHandler b = new PasswordGeneratorButtonHandler();
interfaceButtonGenerate.addActionListener(b); // Add handler to button
interfaceFrame.add(interfacePanel);
interfaceFrame.setVisible(true);
}
Also, inside of the PasswordGeneratorButtonHandler class, you instantiate an instance of the class called generate. This is unnecessary.
I have the class BossInfo which extends JPanel and has a few components like JLabel, JTextField. My main method is in another file ("DamageCalculator").
Basically, a value is entered into a JTextField via an action listener and I'd like to pass that value to a different file (to use it in calculations). I'm having a lot of trouble with the logic. Here is my class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BossInfo extends JPanel {
private JLabel bossLabel, resultLabel;
private JTextField bossHp;
String bossHpText = new String("");
int valRecd = 0;
public BossInfo() {
//Labels
bossLabel = new JLabel("Boss HP: (Hit Enter to set)");
resultLabel = new JLabel("---");
//Text field for user input of boss hp
bossHp = new JTextField(15);
bossHp.addActionListener(new TempListener());
//add components
add(bossLabel);
add(bossHp);
add(resultLabel);
} //end BossInfo object
public void setVal(int valRecd) {
this.valRecd = valRecd;
}
private class TempListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
int hp;
bossHpText = bossHp.getText();
hp = Integer.valueOf(bossHpText);
dc.setVal(hp);
resultLabel.setText(bossHpText);
}//end action performed
}//end TempListener
} //end class BossInfo
How can I use bossHpText in another class? The "actionPerformed" gets mad if it's any return type other than void so I'm not sure it's meant to return anything.
EDIT: Code updated based on suggestions.
Have a variable valRecd in the MainClass.
On your actionPerformed, call the setter method for this valRecd, e.g,
MainClass obj = new MainClass(); //in your constructor.
public void actionPerformed(ActionEvent event) {
int hp;
bossHpText = bossHp.getText();
hp = Integer.parseInt(text);
obj.setVal(hp); //add this line.
resultLabel.setText(bossHpText);
}
where setVal might be something like this:
public void setVal(int valRecd) {
this.valRecd = valRecd;
}
In my online Java class, I need to write a program that counts the number of mouse clicks on a button within a frame. Here is my code:
import java.awt.*;
import java.awt.event.*;
public class option1 extends Frame {
option1() {
setTitle("Final Project Option 1");
setSize(300,300);
show();
}
public static void main(String[] args) {
option1 test = new option1();
int a = 0;
String s1 = "" + a;
Frame objFrame;
Button objButton1;
Label objLabel1;
objFrame = new option1();
objButton1 = new Button("Button");
objLabel1 = new Label();
objLabel1.setBounds(150,220,50,30);
objButton1.setBounds(40,35,50,50);
objLabel1.setText(s1);
objButton1.addMouseListener(new MyMouseListener()); //line 29
objFrame.add(objLabel1);
objFrame.add(objButton1);
}
public class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
a++; //line 36
}
}
}
When compiling, I get two errors. One error is on line 29, which is "non-static variable this cannot be referenced from a static context", and the other is on line 36, which is "cannot find symbol".
So, what exactly am I doing wrong? I would appreciate responders telling exactly what I need to do to fix the problem, and avoiding using technical terms since I'm rather new to programming.
I see two issues, namely your inner class should be static (to use it without an instance of option1 which should probably be Option1 to fit with Java naming conventions) and you need to define and initialize a. Something like
public static class MyMouseListener extends MouseAdapter {
int a = 0; //<-- add this.
public void mouseClicked(MouseEvent me) {
a++;
}
}
Also, I suggest you consider using the more modern JFrame instead of the older Frame.
Edit
You'll need to save a reference to your MouseListener like
MyMouseListener mml = new MyMouseListener();
objButton1.addMouseListener(mml);
Then you can get it the a like
System.out.println(mml.a);
Finally, your original approach of "" + a would be "0".
Generally, as soon as you possibly can, get out of the main method into a non-static context...
public class option1 extends Frame {
private int a = 0;
private Label objLabel1;
option1() {
setTitle("Final Project Option 1");
setSize(300,300);
Button objButton1;
objButton1 = new Button("Button");
objLabel1 = new Label();
objLabel1.setBounds(150,220,50,30);
objButton1.setBounds(40,35,50,50);
objLabel1.setText(Integer.toString(a));
objButton1.addMouseListener(new MyMouseListener()); //line 29
add(objLabel1);
add(objButton1);
show();
}
public static void main(String[] args) {
option1 test = new option1();
}
public class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
a++; //line 36
objLabel1.setText(Integer.toString(a));
}
}
}
Generally speaking, AWT is out-of-date (by some 15 years) and you really should be trying to use Swing or JavaFX instead.
Buttons should use ActionListener, as a mouse is not the only way a button might be triggered
You might like to have a read through Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others
I just tried to make your code working. But there is some issues regarding the standard Java coding. But you should consider previous answers concerning the coding style.
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class Main {
public static void main(String[] args) {
final Frame mainFrame = new OptionOne();
Button button = new Button("Button");
final Label label = new Label();
label.setBounds(150, 220, 50, 30);
label.setText("0");
button.setBounds(40, 35, 50, 50);
label.addPropertyChangeListener(label.getText(), new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
mainFrame.addNotify();
}
});
button.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
int value = Integer.parseInt(label.getText());
label.setText(String.valueOf(value + 1));
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
mainFrame.add(label);
mainFrame.add(button);
}
}
class OptionOne extends Frame {
OptionOne() {
setTitle("Final Project Option 1");
setSize(300, 300);
show();
}
}