Mysterious one time Casting Exception - java

I am trying to use the PropertyChangeSupport of JComponent class.
But when I am executing the following code, Clicking on the menu button first time gives Runtime casting Exception, but then it runs fine always.
FrameListener.java
import javax.swing.*;
import java.beans.*;
import java.awt.*;
import java.awt.event.*;
public class FrameListener extends JFrame implements ActionListener, PropertyChangeListener
{
JLabel lblMessage;
JMenuItem changeFont;
FontSource fe = new FontSource(this,"Font Editor");
public FrameListener(){
super("Hello World");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ;
increaseReadability() ;
changeFont.addActionListener(this);
fe.addPropertyChangeListener(this);
setSize(400,200);
setVisible(true);
}
private void increaseReadability(){
JPanel panel = new JPanel();
Font f = new Font("Times New Roman",Font.BOLD,24);
lblMessage = new JLabel("HELLO WORLD",SwingConstants.CENTER);
lblMessage.setFont(f);
panel.add(lblMessage);
JMenuBar actionBar = new JMenuBar();
JMenu edit = new JMenu("Edit");
changeFont = new JMenuItem("Font");
actionBar.add(edit);
edit.add(changeFont);
add(actionBar,BorderLayout.NORTH);
add(panel,BorderLayout.CENTER);
}
public void propertyChange(PropertyChangeEvent pcevent){
Object obj = pcevent.getNewValue() ;
System.out.println(obj.getClass()) ;
//Statement occuring problem 1st time
Font newFt = (Font)obj;
lblMessage.setFont(newFt);
}
public void actionPerformed(ActionEvent evt){
fe.setVisible(true);
}
public static void main(String argv[]) {
new FrameListener();
}
}
FontSource.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.beans.*;
public class FontSource extends JDialog implements ActionListener {
private Font newFont = new Font("Times New Roman",Font.BOLD,12);
JComboBox cbfType,cbfStyle,cbfSize;
JButton btnOk,btnCancel;
//protected PropertyChangeSupport changes = new PropertyChangeSupport(this);
public Font getNewFont(){
return newFont;
}
public void setNewFont(Font f){
Font old = newFont;
try{
//this statement calls the propertyChange() of FrameListener
//if u are removing comments, replace the following statement with
// changes.firePropertyChange("Font Changed",old,f);
firePropertyChange("Font Changed",old,f);
newFont = f;
}
catch(Exception e){
System.out.println(e);
}
}
public FontSource(Frame fr,String title){
super(fr,title);
// getting font family from the graphics environment.
GraphicsEnvironment gf = GraphicsEnvironment.getLocalGraphicsEnvironment();
String myfont[] = gf.getAvailableFontFamilyNames();
cbfType = new JComboBox(myfont);
add(cbfType);
String fontStyle[] = {"PLAIN","ITALIC","BOLD",};
cbfStyle = new JComboBox(fontStyle);
add(cbfStyle);
String fontSize[] = {"10","12","14","16","18","20","24","26","28","36","48","72"};
cbfSize = new JComboBox(fontSize);
add(cbfSize);
btnOk =new JButton("OK");
btnCancel =new JButton("Cancel");
add(btnOk);
add(btnCancel);
// adding action listener
btnOk.addActionListener(this);
btnCancel.addActionListener(this);
// setting layout and size for the dialog
setLayout(new FlowLayout());
setSize(170,170);
}
public void actionPerformed(ActionEvent ae){
if(ae.getSource()==btnOk){
String type = (String) cbfType.getSelectedItem();
String style = (String)cbfStyle.getSelectedItem();
int s = 0;
int size = Integer.parseInt((String)cbfSize.getSelectedItem());
if(style=="PLAIN")
s= Font.PLAIN;
else {
if(style =="BOLD")
s= Font.BOLD;
else
s= Font.ITALIC;
}
Font f = new Font(type,s,size);
setNewFont(f);
}
else{
this.setVisible(false);
}
}
/*
public void addPropertyChangeListener(PropertyChangeListener l){
System.out.println("attachement done...");
changes.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l){
changes.removePropertyChangeListener(l);
}
*/
}
But If i use my own PropertyChangeSupport (remove the comments in FontSource.java), then it's working perfectly.
I tried my best, but not getting this.
Thnx in advance :--)

If you implement PropertyListener, you will receive all of the property changes for the component(s) with which you register. There can be many types, whose values will be determined by the type of property change.
The implementation of Component method of setFont will fire a property change with the name of "font". If you test for that name, you should be fine:
public void propertyChange(PropertyChangeEvent pcevent){
Object obj = pcevent.getNewValue() ;
System.out.println(obj.getClass()) ;
//Problem should not occur with this call.
if (pcevent.getPropertyName().equals("font")){
Font newFt = (Font)obj;
lblMessage.setFont(newFt);
}
}

My guess...
The property change listening is not distinguishing by property name. Since you are listening to all of the properties of FontSource then you will undoubtedly see things that are not a Font.
In propertyChange() you can print the property name in the event to be sure that's the problem.
Solution is to register for just the property in which you are interested or to check the property name in the propertyChange() method.

Finally i got it.
The answer is displayed, when u compile and execute the following files.
FontSource.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.beans.*;
public class FontSource extends JDialog{
public FontSource(Frame fr,String title){
super(fr,title);
setSize(600, 400) ;
JTextArea area = new JTextArea() ;
area.setEditable(false) ;
add(new JScrollPane(area)) ;
String str = "If u look at the command prompt, then it is very clear," + "\n" +
"that, only on your first click on JMenuItem (font)," + "\n" +
"u get an output on cmd, for next future clicks on JMenuItem (font), u get no output on cmd." + "\n\n" +
"Reason : On first click, ActionListener attached to JMenuItem (font) invokes," + "\n" +
"fe.setVisible(true), which internally calls setBackground method of Component class only once." + "\n" +
"Now, setBackground method calls firePropertyChange(\"background\", oldValue, newValue)," + "\n" +
"which in turn also gets executed once." + "\n\n" +
"Now, solution to this is clearly mentioned in the reply" + "\n" +
"provided by akf for my question asked on stackoverflow. cheers :-)" ;
area.setText(str) ;
}
}
FrameListener.java
import javax.swing.*;
import java.beans.*;
import java.awt.*;
import java.awt.event.*;
public class FrameListener extends JFrame implements ActionListener, PropertyChangeListener
{
JLabel lblMessage;
JMenuItem changeFont;
FontSource fe = new FontSource(this,"Font Editor");
public FrameListener(){
super("Hello World");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) ;
increaseReadability() ;
changeFont.addActionListener(this);
fe.addPropertyChangeListener(this);
setSize(400,200);
setVisible(true);
}
private void increaseReadability(){
JMenuBar actionBar = new JMenuBar();
JMenu edit = new JMenu("Edit");
changeFont = new JMenuItem("Font");
actionBar.add(edit);
edit.add(changeFont);
add(actionBar,BorderLayout.NORTH);
}
public void propertyChange(PropertyChangeEvent pcevent){
Object obj = pcevent.getNewValue() ;
System.out.println(obj.getClass() + ", " + pcevent.getPropertyName()) ;
}
public void actionPerformed(ActionEvent evt){
fe.setVisible(true);
}
public static void main(String argv[]) {
new FrameListener();
}
}

Related

How to run Java Applet program from windows cmd?

I have a Java program below which should ask the user to input a number in the applet window and process further on the basis of given. But the problem is that i am not able to run this java code through cmd
i know my main method is empty but i dont know what to put in it?
CODE
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class Table extends Applet {
private Label msg;
TextField number;
public void init()
{
setLayout(new FlowLayout());
Label heading = new Label("Multiplication Table");
number = new TextField(10);
Button button = new Button(" Press ");
msg = new Label("");
add(heading);
add(number);
add(button);
add(msg);
button.addActionListener(new ButtonListener());
}
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String str=" ";
int n = Integer.parseInt(number.getText());
if(n%2==0 && n>=11 && n<=90)
{
for(int i=1;i<=10;i++){
str = str+ n*i+" ";
}
}
else {
str = "Try Again! Number must be even and between 11-90";
}
msg.setText(str);
}
}
public static void main(String[] args) { }
}

if statements,lables and combo boxes

Ok my code has to pick route combo box (check) display in label(check) have a return and single ticket combobox(check) need it to display text(check) my problem is it only prints text related to one of my statments hope someone can tell me how to fix my if statments. The lable changes on a button .It reads code by lable.So far it only prints 15 and wont print 20 unless i had another label but this wouldnt make sense for the program
package learning;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList.*;
import java.util.Arrays.*;
import java.util.List.*;
#SuppressWarnings("unused")
public class test {
String[] items = {"Tipperary_to_cork","Cork_to_Dublin","Limerick_to_Tipperary","Dublin_to_Cork"};
JComboBox c = new JComboBox(items);
JButton b = new JButton("From");
JLabel l = new JLabel();
String[] items2 = {"window","aisle"};
JComboBox m = new JComboBox(items2);
JButton n = new JButton("Seat");
JLabel o = new JLabel();
String[] items3 = {"Single","return"};
JComboBox x = new JComboBox(items3);
JButton y= new JButton("Ticket");
JLabel z = new JLabel("choose Ticket");
String[] items4 = {"1","2","3","4","5","6","7","8","9","10"};
JComboBox<?> xx = new JComboBox(items4);
JButton yy = new JButton("seat");
JLabel zz = new JLabel("Choose a seat");
JLabel hh = new JLabel("cost");
JButton ccc = new JButton("comfirm");
JLabel hhh = new JLabel("");{
}
public test(){
frame();
}
public void frame(){
JFrame wolf = new JFrame();//frame
wolf.setVisible(true);
wolf.setSize(350,350);
wolf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
JPanel p = new JPanel();
p.add(hh);
p.add(c);//
p.add(b);//
p.add(l);//lable1
p.add(m);//
p.add(n);//
p.add(o);//lable 2
p.add(x);//
p.add(y);//
p.add(z);//lable 2
p.add(xx);//
p.add(yy);//
p.add(zz);//lable 2
p.add(ccc);
p.add(hhh);
wolf.add(p);
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String s = c.getSelectedItem().toString();
l.setText(s);
}
});
n.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String s = m.getSelectedItem().toString();
o.setText(s);
}
});
y.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String s = x.getSelectedItem().toString();
z.setText(s);
}
});
yy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String s = xx.getSelectedItem().toString();
zz.setText(s);
}
});
}
{
if(l.getText().equals("Tipperary_to_cork")&&(z.getText().equals("single"))){
ccc.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
hh.setText("15"); //***
}});
if(l.getText().equals("Tipperary_to_cork")&&(z.getText().equals("return"))){
ccc.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
hh.setText("20"); //****
}
});
}}}
public static void main(String[]args){
new test();
}
}
You want to check "if some condition" when you click the button. So, start with one simple if statement inside one of the actionPerformed methods. You shouldn't add an action listener inside an if statement, you should always perform an action, and determine the event inside that action.
For example
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String s = c.getSelectedItem().toString();
if (s.equals("Tipperary to cork")) {
// TODO: do something
}
}
});
Original answer
These line just happen to work because you have if(false==false)
if(l.equals("Tipperary to cork")==(z.equals("single"))) { ... }
if(l.equals("Tipperary to cork")==(z.equals("return"))) { ... }
The reason they evaluate to false is because you are comparing a JLabel.equals(String). You should use l.getText().equals("text here"), but...
The problem is that you have those if statements inside the constructor for your class, meaning that they are the first thing that is evaluated in your code. You should move the corrected if statements into the ActionListeners for the respective buttons.
Additional note: You seem to want "Tipperary to cork" AND "single". In that case, use && in place of ==. Alternatively, you could do this (psuedocode intentional)
if "Tipperary to cork" {
if "single" { ... }
else if "return" { ... }
}
In reality, though, you should compare c.getSelectedItem().toString() instead of the text of the label, but that's your decision.

Java ActionListener in another class - accessing objects from main class

i am writing a simple BMI calculator program. The application includes ActionListener, which handles button click, check if textfields are filled in and executes calculations.
For now, the ActionListener method is as a subclass of a main class. And it looks like this:
BMICalc.java
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class BMICalc extends JFrame {
private JMenuBar menuBar1;
private JMenu jMenu1;
private JMenuItem jMenuItem1, jMenuItem2;
private JButton jButton1;
private JPanel mainPanel, jPanel1;
private JLabel jLabel1, jLabel2;
private JTextField jTextField1, jTextField2;
private BMICalc() {
super("BMI Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(250, 300));
setLocationRelativeTo(null);
setLayout(new BorderLayout(10, 10));
mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
add(mainPanel);
jPanel1 = new JPanel(new GridLayout(6,2));
mainPanel.add(jPanel1, BorderLayout.CENTER);
menuBar1 = new JMenuBar();
jMenu1 = new JMenu("Help");
menuBar1.add(jMenu1);
jMenuItem1 = new JMenuItem("The purpose");
jMenu1.add(jMenuItem1);
jMenuItem2 = new JMenuItem("About");
jMenu1.add(jMenuItem2);
setJMenuBar(menuBar1);
jLabel1 = new JLabel("Enter weight in [kg]:");
jPanel1.add(jLabel1);
jTextField1 = new JTextField("");
jPanel1.add(jTextField1);
jLabel2 = new JLabel("Enter height in [cm]:");
jPanel1.add(jLabel2);
jTextField2 = new JTextField("");
jPanel1.add(jTextField2);
jButton1 = new JButton("Calculate");
mainPanel.add(jButton1, BorderLayout.SOUTH);
Handler handler = new Handler();
jButton1.addActionListener(handler);
jMenuItem1.addActionListener(handler);
jMenuItem2.addActionListener(handler);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
BMICalc bmicalc = new BMICalc();
bmicalc.setVisible(true);
}
});
}
private class Handler implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (event.getSource() == jButton1) {
if (jTextField1.getText().equals("") || jTextField2.getText().equals("")) {
JOptionPane.showMessageDialog(null, "All fields must be filled in!", "Error", JOptionPane.INFORMATION_MESSAGE);
}
else {
Calculations calcs = new Calculations();
calcs.calculateBMI(jTextField1.getText(), jTextField2.getText());
JOptionPane.showMessageDialog(null, "Your BMI: " +calcs.returnBMI());
}
}
else if (event.getSource() == jMenuItem1) {
JOptionPane.showMessageDialog(null, "The program calculates BMI based on information entered by user." , "The purpose of this program", JOptionPane.INFORMATION_MESSAGE);
}
else if (event.getSource() == jMenuItem2) {
JOptionPane.showMessageDialog(null, "BMI Calc v. 1.0 " , "About", JOptionPane.INFORMATION_MESSAGE);
}
}
}
}
Calculations.java
public class Calculations {
private double BMI;
private int weight, height;
public void calculateBMI(String sWeight, String sHeight) {
weight = Integer.parseInt(sWeight);
height = Integer.parseInt(sHeight);
BMI = weight/(height*height*0.0001);
}
public String returnBMI() {
return String.format("%.2f", BMI);
}
}
It works just fine, but I would like to make the code 'clenaer' and make the Handler a class, not a subclass, in another file. I've created a Handler.java and moved the whole Handler subclass, but the class doesn't see the jTextFields and jButton, as they are private (and as far as I'm concerned, they should be).
How can I separate ActionListener class, access these jObjects in it and still be fair with privacy stuff?
Thank you very much for answers.
You can pass the objects you need to the Handler class using the constructor:
public class Handler {
private JButton button;
private JTextField textField;
public Handler(JButton button, JTextField textField) {
this.button = button;
this.textField = textField;
}
}
And when you instantiate the class you just pass in the two variables you want:
Handler handler = new Handler(jButton1, jTextField1);
Explanation:
your Handler class is inner class of of BMICalc. When a nested class is not static (see also difference between static and non-static nested classes) it means that objects of those class exist within an object of the parent class. That's why your Handler class see private fields.
This is no problem for us when the class is static. You just have to pass in those variables to the Handler somehow (constructor or setter fields) and then you can reuse your class for other button-text field combinations.
Edit: Yet another way:
If your handler is to be used here, and only here, and nowhere else in the code, you could instantiate anonymous Handler and assign it to the field (no need to reuse somewhere else). So, in example:
jMenuItem1.addActionListener(new Handler() {
#Override
public void actionPerformed(ActionEvent event) {
JOptionPane.showMessageDialog(null, "The program calculates BMI based on information entered by user." , "The purpose of this program", JOptionPane.INFORMATION_MESSAGE);
}
});
jMenuItem2.addActionListener(new Handler() {
#Override
public void actionPerformed(ActionEvent event) {
JOptionPane.showMessageDialog(null, "BMI Calc v. 1.0 " , "About", JOptionPane.INFORMATION_MESSAGE);
}
});
Now you don't have to create one huge Handler with a lot of fields and ifs...
Note that the class Handler that you show is not a subclass of Main. To be a subclass means it inherits. What you have is an inner class.
You need to pass the references to the handler so it can refer to them. For example:
public class Handler implements ActionListener {
private final JTextField jTextField1;
private final JButton jButton1;
public Handler(final JTextField textField, final JButton button)
{
this.jTextField1 = textField;
this.jButton1 = button;
}
}
And create it like this:
Handler handler = new Handler(jTextField1, jButton1);
If you want to protect those JTextField and JMenuItem from the others classes while having the handler in another classe, then you need to add some methods to the BMICalc class:
public boolean isButton1(ActionEvent event) {
return event.getSource() == jButton1;
}
public boolean isJMenuItem1(ActionEvent event) {
return event.getSource() == jMenuItem1;
}
public boolean isJMenuItem2(ActionEvent event) {
return event.getSource() == jMenuItem2;
}
public String getJButton1Text() {
return this.jButton1.getText();
}
public String getJTextField1Text() {
return jTextField1.getText();
}
public String getJTextField2Text() {
return jTextField2.getText();
}
Then you need to have the following Handler class:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
public class Handler implements ActionListener {
private final BMICalc calc;
public Handler(BMICalc calc) {
this.calc = calc;
}
public void actionPerformed(ActionEvent event) {
if (calc.isButton1(event)) {
if (calc.getJTextField1Text().equals("") || calc.getJTextField2Text().equals("")) {
JOptionPane.showMessageDialog(null, "All fields must be filled in!", "Error", JOptionPane.INFORMATION_MESSAGE);
}
else {
Calculations calcs = new Calculations();
calcs.calculateBMI(calc.getJTextField1Text(), calc.getJTextField2Text());
JOptionPane.showMessageDialog(null, "Your BMI: " +calcs.returnBMI());
}
}
else if (calc.isJMenuItem1(event)) {
JOptionPane.showMessageDialog(null, "The program calculates BMI based on information entered by user." , "The purpose of this program", JOptionPane.INFORMATION_MESSAGE);
}
else if (calc.isJMenuItem2(event)) {
JOptionPane.showMessageDialog(null, "BMI Calc v. 1.0 " , "About", JOptionPane.INFORMATION_MESSAGE);
}
}
}
And change on line in the BMICalc :
Handler handler = new Handler(this);
But as the handler is supposed to handle only button and input of this view (and BMICalc class), it would make more sense (for me) to keep this Handler class private and inside the BMICalc class).
Hope this helps !

Java JTextField information access from another class

I am using a gui with JTextFields to collect some information and then a JButton that takes that infomration and writes it to a file, sets the gui visibility to false, and then uses Runnable to create an instance of another JFrame from a different class to display a slideshow.
I would like to access some of the information for the JTextFields from the new JFrame slideshow. I have tried creating an object of the previous class with accessor methods, but the values keep coming back null (I know that I have done this correctly).
I'm worried that when the accessor methods go to check what the variables equal the JTextFields appear null to the new JFrame.
Below is the sscce that shows this problem.
package accessmain;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class AccessMain extends JFrame implements ActionListener
{
private static final int FRAMEWIDTH = 800;
private static final int FRAMEHEIGHT = 300;
private JPanel mainPanel;
private PrintWriter outputStream = null;
private JTextField subjectNumberText;
private String subjectNumberString;
public static void main(String[] args)
{
AccessMain gui = new AccessMain();
gui.setVisible(true);
}
public AccessMain()
{
super("Self Paced Slideshow");
setSize(FRAMEWIDTH, FRAMEHEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
//Begin Main Content Panel
mainPanel = new JPanel();
mainPanel.setBorder(new EmptyBorder(0,10,0,10));
mainPanel.setLayout(new GridLayout(7, 2));
mainPanel.setBackground(Color.WHITE);
add(mainPanel, BorderLayout.CENTER);
mainPanel.add(new JLabel("Subject Number: "));
subjectNumberText = new JTextField(30);
mainPanel.add(subjectNumberText);
mainPanel.add(new JLabel(""));
JButton launch = new JButton("Begin Slideshow");
launch.addActionListener(this);
mainPanel.add(launch);
//End Main Content Panel
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
if(actionCommand.equals("Begin Slideshow"))
{
subjectNumberString = subjectNumberText.getText();
if(!(subjectNumberString.equals("")))
{
System.out.println(getSubjectNumber());
this.setVisible(false);
writeFile();
outputStream.println("Subject Number:\t" + subjectNumberString);
outputStream.close();
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass();
testClass.setVisible(true);
}
});
}
else
{
//Add warning dialogue here later
}
}
}
private void writeFile()
{
try
{
outputStream = new PrintWriter(new FileOutputStream(subjectNumberString + ".txt", false));
}
catch(FileNotFoundException e)
{
System.out.println("Cannot find file " + subjectNumberString + ".txt or it could not be opened.");
System.exit(0);
}
}
public String getSubjectNumber()
{
return subjectNumberString;
}
}
And then creating a barebones class to show the loss of data:
package accessmain;
import javax.swing.*;
import java.awt.*;
public class AccessClass extends JFrame
{
AccessMain experiment = new AccessMain();
String subjectNumber = experiment.getSubjectNumber();
public AccessClass()
{
System.out.println(subjectNumber);
}
}
Hardcoding the accessor method with "test" like this:
public String getSubjectNumber()
{
return "test";
}
Running this method as below in the new JFrame:
SelfPaceMain experiment = new SelfPaceMain();
private String subjectNumber = experiment.getSubjectNumber();
System.out.println(subjectNumber);
Does cause the system to print "test". So the accessor methods seem to be working. However, trying to access the values from the JTextFields doesn't seem to work.
I would read the information from the file I create, but without being able to pass the subjectNumber (which is used as the name of the file), I can't tell the new class what file to open.
Is there a good way to pass data from JTextFields to other classes?
pass the argument 'AccessMain' or 'JTextField' to the second class:
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
AccessClass testClass = new AccessClass(AccessMain.this); //fixed this
testClass.setVisible(true);
}
});
Then reading the value of 'subjectNumber'(JTextField value) from the 'AccessMain' or 'JTextField' in the second class:
public class AccessClass extends JFrame
{
final AccessMain experiment;
public AccessClass(AccessMain experiment)
{
this.experiment = experiment;
}
public String getSubjectNumber(){
return experiment.getSubjectNumber();
}
}
Also, you should try Observer pattern.
A simple demo of Observalbe and Observer
Observable and Observer Objects

Need to get input from a radio button in a JFrame, and use the selected input in another class

I need to create an application where I need to get a user input from a radio button and then use the selected filename in a different class.I'm not sure how to implement this, beacuse everytime I try to place a getString() method in the MyAction class it gives me a null value. thanks!!
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
public class SelectRadioButton{
public SelectRadioButton(){
// Directory path here
String path = "W:\\materials";
JFrame frame = new JFrame("Material Selection");
JPanel panel = new JPanel(new GridLayout(0, 4));
ButtonGroup bg = new ButtonGroup();
String files;
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
JRadioButton first;
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
files = listOfFiles[i].getName();
if (files.endsWith(".mtl") || files.endsWith(".MTL"))
{
first = new JRadioButton(files);
panel.add(first,BorderLayout.CENTER);
panel.revalidate();
bg.add(first);
first.addActionListener(new MyAction);
}
}
}
frame.add(panel, BorderLayout.NORTH);
frame.getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
frame.setSize(1000, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class MyAction implements ActionListener{
//String m;
public void actionPerformed(ActionEvent e){
String m =e.getActionCommand();
String[] split = m.split("\\.");
m=split[0];
JOptionPane.showMessageDialog(null,"Your Selection is"+m+" radio button.");
}
/*
public String getString(){
return m;
}
*/
}
}
Obviously, the m variable only will be set when the specific radio button receive a click event. If you don't want to change your code so much, do something like this:
public class MyAction implements ActionListener{
String m;
public MyAction(String radioButtonLabel){
m = radioButtonLabel;
}
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(null,
"Your Selection is"+m+" radio button.");
}
public String getString(){
return m;
}
}
And replace the:
first.addActionListener(new MyAction());
by:
first.addActionListener(new MyAction(files));
And improve the names of your variables... it is a little bit confusing!
Hope it helps.
UPDATE
To get the selected radio button:
public static JRadioButton getSelection(ButtonGroup group) {
for (Enumeration e = group.getElements(); e.hasMoreElements();) {
JRadioButton b = (JRadioButton) e.nextElement();
if (b.getModel() == group.getSelection()) {
return b;
}
}
return null;
}

Categories