focusGained and focusLost don't work? - java

I wanted to make a program that allows the user to add to a file, search for, delete and load from a file animals in a zoo and information about them. So far the buttons delete and search don't work, so pay no attention to them. The problem is that focusGained and focusLost don't seem to work. I tried every solution I found so far, but I couldn't fix them. So, all help is appreciated. If you have any ideas about how to write the Search and Delete classes, please suggest!
This is the main program:
package GUI_Try;
import java.awt.event.*;
import java.util.ArrayList;
import java.io.*;
import javax.swing.*;
import java.awt.*;
public class GUI_ZOO extends JFrame{
ArrayList <ANIMAL> animal= new ArrayList<ANIMAL>();
TextField name,ID,country;
Button add = new Button("add"),
save = new Button("save"),
//delete = new Button("delete"),
//search = new Button("search"),
load = new Button("load");
String sName="",sID="",sCountry="";
JPanel pc;
JScrollPane scrPanName;
JTextArea text;
GUI_ZOO(){
super("Zoo \"Sofia\" ");
setBounds(80, 80, 600, 500);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
GUI_DELETE delObj = new GUI_DELETE();
GUI_SEARCH searchObj = new GUI_SEARCH();
GUI_ADD addObj = new GUI_ADD(sName,name,sID,ID,text,animal,sCountry,country);
pc = new JPanel();
pc.setLayout(new FlowLayout());
text = new JTextArea(20,10);
scrPanName = new JScrollPane(text);
name = new TextField("Name",15);
country = new TextField("Country",15);
ID = new TextField("ID",5);
text.setEditable(false);
pc.add(name);
pc.add(ID);
pc.add(country);
pc.add(add);
pc.add(save);
pc.add(load);
pc.add(search);
pc.add(delete);
ID.addActionListener(addObj);
name.addActionListener(addObj);
country.addActionListener(addObj);
add.addActionListener(addObj);
save.addActionListener(new Save());
load.addActionListener(new Load());
delete.addActionListener(delObj);
search.addActionListener(searchObj);
name.addFocusListener(new Focus()) ;
country.addFocusListener(new Focus()) ;
ID.addFocusListener(new Focus()) ;
add("North",pc);
add("Center",scrPanName);
setVisible(true);
}
class Focus implements FocusListener{
public void focusGained (FocusEvent e){
try{
TextField src = (TextField)e.getSource();
if(src.getText().equals("Name") ){
name.setText("");
}
if(src.getText().equals("ID") ){
ID.setText("");
}
if(src.getText().equals("Country") ){
country.setText("");
}
}
catch(ClassCastException ignored){
}
}
public void focusLost (FocusEvent e){
try{
TextField src = (TextField)e.getSource();
if(src.getText().equals("") ){
name.setText("Name");
}
if(src.getText().equals("") ){
ID.setText("ID");
}
if(src.getText().equals("") ){
country.setText("Country");
}
}
catch(ClassCastException ignored){
}
}
}
class Save implements ActionListener{
public void actionPerformed(ActionEvent e){
try{
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("zoo.dat"));
os.writeObject(animal);
os.close();
}
catch(FileNotFoundException ex){
System.out.println("Can't save the file zoo.dat");
}
catch(IOException ex){}
}
}
class Load implements ActionListener{
public void actionPerformed(ActionEvent e){
try{
ObjectInputStream os = new ObjectInputStream(new FileInputStream("zoo.dat"));
animal = (ArrayList<ANIMAL>) os.readObject();
os.close();
text.setText("");
for(ANIMAL a:animal){
text.append(a.name+"\t"+a.ID+"\t"+a.country+"\n");
}
}
catch(FileNotFoundException ex){
System.out.println("Can't find the file zoo.dat");
}
catch(IOException ex){
ex.printStackTrace();//?
}
catch (ClassNotFoundException e1) {
e1.printStackTrace();//?
}
}
}
public static void main(String arg[]){
new GUI_ZOO();
}
}
I divided the program, so the class GUI_ADD would be here:
package GUI_Try;
import java.awt.event.*;
import java.util.ArrayList;
import java.io.*;
import javax.swing.*;
import java.awt.*;
public class GUI_ADD implements ActionListener{
String sNamel;
TextField namel;
String sIDl;
TextField IDl;
String sCountryl;
TextField countryl;
JTextArea textl;
ArrayList <ANIMAL> animall;
public GUI_ADD(String sName,TextField name,String sNumber,TextField ID,
JTextArea text,ArrayList <ANIMAL> animal,String sCountry,TextField country){
sNamel = sName;
sCountryl = sCountry;
IDl = ID;
namel = name;
sIDl = sNumber;
countryl = country;
textl = text;
animall = animal;
}
public void actionPerformed(ActionEvent e){
sNamel=namel.getText();
sIDl=IDl.getText();
sCountryl=countryl.getText();
if((sNamel.length()==0)||(sNamel=="Name")){
JOptionPane.showMessageDialog(null, "Type a name, please.");
return;
}
if(sIDl.length()==0){
JOptionPane.showMessageDialog(null, "Type an ID, please.");
return;
}
if(sCountryl.length()==0){
JOptionPane.showMessageDialog(null, "Type a country of origin, please.");
return;
}
animall.add(new ANIMAL(sNamel,sIDl,sCountryl));
textl.append(sNamel+"\t"+sIDl+"\t"+sCountryl+"\n");
namel.setText("");
IDl.setText("");
countryl.setText("");
}
}
And this is the interface:
package GUI_Try;
import java.io.*;
class ANIMAL implements Serializable {
String name, ID, country;
public ANIMAL(String name, String ID, String country){
this.name = name;
this.ID = ID;
this.country = country;
}
}

You donot need to implements FocusListener in both classes. Its redundant here.
public class GUI_ZOO extends JFrame implements FocusListener{
class Focus implements FocusListener{
And the reason for FocusGained and FocusLost did not work:
TextField name,ID,country;
You have used java.awt.TextField,
JTextField src = (JTextField)e.getSource();
But you are trying to get source from JTextField. In your program you donot have any JTextField's right!.
Change it to:
TextField src = (TextField)e.getSource();

Your problem (one of many) is mixing AWT and Swing components.
You create name, ID, and country as TextField, and then try to cast them as JTextField in your Focus listener. But, you protect against a ClassCastException, by suppressing it, so you don't even see evidence of this problem anymore.
try {
JTextField src = (JTextField) e.getSource();
// ... omitted
} catch(ClassCastException ignored) {
// No-op
}
You want (need) to use JTextField and JButton Swing objects, not the AWT objects, in your Swing program.
An additional problem with your focusLost method. If the the JTextField that loses focus is blank, you will overwrite your name, ID and country text fields ... not just the blank ones!

Related

How to call a variable from a keylistener to a different class [closed]

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 8 years ago.
Improve this question
I'm trying to build a payroll system and I'm having trouble using the variable in and action listener to my condition, somehow it cant see the variable I've declared in actionlistener, I've tried using calling it in a class but wasn't sure what I did wrong cause it didn't work. Thank you in advance!
Here is my code:
import java.io.File; import java.io.FileNotFoundException; import
java.util.ArrayList; import java.util.List; import
java.util.Scanner; import javax.swing.*; import java.awt.*; import
java.awt.event.*;
#SuppressWarnings("serial")
public class kapoy extends JFrame{
public static JTextField text1;
public static JTextField text2;
public JLabel label1;
public JLabel label2;
public JPanel panel1;
public JPanel panel2;
public JPanel panel3;
public JPanel panel4;
public kapoy() {
text1 = new JTextField();
text1.setPreferredSize(new Dimension(50,20));
text2 = new JTextField();
text2.setPreferredSize(new Dimension(50,20));
label1 = new
JLabel("Inpute Employee ID: ");
label2 = new JLabel("Input workedDays: ");
panel1 = new JPanel();
panel1.setLocation(0,0);
panel1.setSize(300,40);
panel1.setBackground(Color.blue);
panel1.add(label1);
panel1.add(text1);
add(panel1);
panel2 = new JPanel();
panel2.setLocation(0,40);
panel2.setSize(300,40);
panel2.setBackground(Color.red);
panel2.add(label2);
panel2.add(text2);
add(panel2);
panel3 = new JPanel();
panel3.setLocation(0,80);
panel3.setSize(400,200);
panel3.setBackground(Color.green);
add(panel3);
panel4 = new JPanel();
panel4.setLocation(300,0);
panel4.setSize(100,80);
panel4.setBackground(Color.yellow);
add(panel4);
setSize(410,300);
setLayout(null);
setTitle("Pay Roll by Migz"); }
public static void main(String[] args) {
kapoy cn = new kapoy(); cn.setVisible(true);
text1.addKeyListener(new KeyAdapter(){
public void keyReleased(KeyEvent e)
{
try {
/**Cant use this-->**/int x = Integer.parseInt(text1.getText());
} catch (NumberFormatException nfe) {
text1.setText("");
}
} });
try {
File f = new File("D:/Users/DAVID Family/Desktop/Employees.txt");
Scanner sc = new Scanner(f);
List<Employee> people = new ArrayList<Employee>();
while(sc.hasNextLine()){
String line = sc.nextLine();
String[] details = line.split(" ");
int Id = Integer.parseInt(details[0]);
String name = details[1];
int rate = Integer.parseInt(details[2]);
Employee p = new Employee(Id, name, rate);
/**in here-->**/if (x == Id){
people.add(p);
}
}
for(Employee p: people){
System.out.println(p.toString());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
class Employee{
private int Id;
private String name;
private int rate;
public Employee(int Id, String name, int rate){
this.Id = Id;
this.setName(name);
this.rate = rate;
}
public int getId() {
return Id; }
public void setId(int Id)
{
this.Id = Id; }
/public void setName(String
name) {
this.name = name; }
public String getName() {
return name; }
public int getrate() {
return rate; }
public void setrate(int rate) {
this.rate = rate; }
public String toString(){
return this.Id + " " + this.name + " " + this.rate; } }
The variable you have defined int x = Integer.parseInt(text1.getText()); is the local variable of method keyReleased as you have defined it inside the method, so the scope of this variable will always be within that method only.
It means you will only be able to use this variable inside method only, not outside it.
If you want to use it in your class, i.e. outside that method, then you should try with some instance variable.
Check this link
Don't use KeyListeners to modify the state of fields, this could cause concurrent modification exceptions, the underlying Document could be modified before your KeyListener is notified and doesn't take into account what would happen in the user pastes text into your field.
Instead, make use of DocumentFilter if you want to restrict what is entered into the field in real time and/or a DocumentListener if you want to be notified when changes occur to the field's Document
Take a look at Implementing a Document Filter, DocumentFilter Examples and Listening for Changes on a Document for more details
You also need to understand that you are operating within in a event driven environment. This means that user actions can occur at any time and in any order. The only thing you can do is wait until some event occurs and respond to.
This means that something like...
kapoy cn = new kapoy();
cn.setVisible(true);
int x = -1;
text1.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
try {
x = Integer.parseInt(text1.getText());
} catch (NumberFormatException nfe) {
text1.setText("");
}
}
});
try {
File f = new File("D:/Users/DAVID Family/Desktop/Employees.txt");
Scanner sc = new Scanner(f);
List<Employee> people = new ArrayList<Employee>();
while (sc.hasNextLine()) {
//...
Employee p = new Employee(Id, name, rate);
if (x == Id) {
people.add(p);
}
}
//...
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Won't work, because by the time your code reaches if (x == Id) { x will still be -1, as the program won't have been able to respond to any key events...
You may, also, want to take a look at How to Use Text Fields and How to Write an Action Listeners

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

How to properly load a JFrame from a file?

I'm making this grade keeping program for my computer science class and the one thing I haven't gotten to work is saving/loading sessions. As I have it set up now it automatically saves when you exit and loads when you start if there is a file to load. However, I feel I'm loading or saving it incorrectly; there's one main JFrame that holds all the data, and that's the one object that is saved. When it's loaded, well, it'd be easier to show you.
If it looks like this when I close it::
Then it'll look like this when I start it up again:
Also, the "Enter Student" button, as well as the ActionListener on the JTextField used for input, cease to work when the program loads the JFrame. The program is split into 3 class files:
Gradebook:
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
public class GradeBook implements java.io.Serializable {
private static JFrame frame;
public static void main(String[] args) throws Exception{
try{
FileInputStream fis = new FileInputStream("t.tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
frame = (JFrame) ois.readObject();
ois.close();
} catch(Throwable t) {
frame = new JFrame("Course Grades");
}
frame.addWindowListener(new closing());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new CourseGrade());
frame.pack();
frame.setVisible(true);
}
closing:
private static class closing extends WindowAdapter {
public void windowClosing(WindowEvent e) {
try {
FileOutputStream fos = new FileOutputStream("t.tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(frame);
oos.close();
} catch(Throwable t){System.out.println(t.getMessage());}
}
}
}
CourseGrade:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.FlowLayout;
import java.util.Random;
import javax.swing.table.*;
import java.io.*;
public class CourseGrade extends JPanel implements java.io.Serializable {
private JLabel entername;
private JTextField in;
private JTextArea list;
private JScrollPane scroll;
private String[] students = new String[1000];
private JButton enter;
private JButton[] studentbuttons = new JButton[1000];
private JButton[] delete=new JButton[1000];
private int numstudents;
private JFrame[] studentframes=new JFrame[1000];
private static JTable[] tables=new JTable[1000];
private static DefaultTableModel[] model=new DefaultTableModel[1000];
private static int[] numass=new int[1000];
public CourseGrade() {
String[][] data = {{"", "", "", ""}};
String[] headers = {"Assignment", "Date Assigned", "Score", "Percentage"};
for(int i=0; i<tables.length; i++){
model[i] = new DefaultTableModel(data, headers);
tables[i] = new JTable(model[i]){
public boolean isCellEditable(int rowIndex, int colIndex) {
return false;
}
};
}
numstudents=0;
in=new JTextField(13);
in.addActionListener(new enterListener());
list=new JTextArea();
scroll=new JScrollPane(list);
list.setEditable(false);
entername=new JLabel("Enter a student's name");
enter=new JButton("Enter Student");
enter.addActionListener(new enterListener());
setPreferredSize(new Dimension(260, 300));
setBackground(Color.green);
add(entername);
add(in);
add(enter);
add(scroll);
scroll.setPreferredSize(new Dimension(240, 200));
}
private class enterListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
String x=in.getText();
String y="";
String z="";
in.setText("");
int a=numstudents+1;
if(x.length()>0) x=a+". " + x + "\n";
students[numstudents] = x;
if(x.length()>0)numstudents++;
for(int i=0; i<numstudents; i++){
x=students[i];
if(x.length()>13)x=x.substring(0,11)+"...\n";
y+=x;
}
studentbuttons[numstudents]=new JButton("Edit");
studentbuttons[numstudents].addActionListener(new grades());
delete[numstudents]=new JButton("Delete");
delete[numstudents].addActionListener(new del());
list.setText(y);
list.add(studentbuttons[numstudents]);
studentbuttons[numstudents].setBounds(100,(numstudents-1)*16,55,15);
list.add(delete[numstudents]);
delete[numstudents].setBounds(160,(numstudents-1)*16,70,15);
}
}
private class grades implements ActionListener {
public void actionPerformed(ActionEvent event) {
Object obj = event.getSource();
if(obj instanceof JButton){
JButton clicked = (JButton)obj;
int x=clicked.getY()/16;
String y=students[x];
for(int i=0; i<y.length(); i++){
String q=y.substring(i,i+1);
if(q.equals(" ")) {
y=y.substring(i+1);
i=y.length()+1;
}
}
studentframes[x]=new JFrame(y+"'s Grades");
studentframes[x].setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
try{studentframes[x].getContentPane().add(new GradePage(x, tables[x], numass[x]));}
catch(Exception e){}
studentframes[x].pack();
studentframes[x].setVisible(true);
}
}
}
private class del implements ActionListener {
public void actionPerformed(ActionEvent event) {
Object obj = event.getSource();
if(obj instanceof JButton){
JButton clicked = (JButton)obj;
int x=clicked.getY()/16;
String y="", z="";
studentbuttons[numstudents].setVisible(false);
delete[numstudents].setVisible(false);
numstudents--;
int q=3;
int w=0;
for(int i=x; i<=numstudents; i++){
if(i<10)q=1;
else if(i<100) q=2;
tables[i]=tables[i+1];
numass[i]=numass[i+1];
model[i]=model[i+1];
w=i+1;
try{if(!students[i+1].equals(null)){students[i]=w+students[i+1].substring(q);} else{students[i]=null;}}catch(Throwable t){}
}
for(int i=0; i<numstudents; i++){
y=students[i];
if(y.length()>13)y=y.substring(0,11)+"...\n";
z+=y;
}
list.setText(z);
}
}
}
public static void setTable(int numtable, JTable table){
tables[numtable]=table;
}
public static void newRow(int numtable){
model[numtable].addRow(new Object[]{"", "", "", ""});
}
public static void setNumEntries(int numtable, int num){
numass[numtable]=num;
}
}
The third class shouldn't have anything to do with this so I wont post it for now.
I realize the code is probably poorly written but I'm only in my second year of High School computer science and we haven't actually covered any of this. This program wasn't even supposed to be a GUI, and this is the first time I've even heard of Input or Output streams so I really don't know anything about them. I realize now that having the classes implement java.io.Serializable was probably unnecessary but when I was trying to research this I came across someone taking about how some objects can't be saved because they don't naturally implement it. So sorry if it's some stupid mistake, and thanks for your time.
You can store the data in a notepad file like this
try
{
FileWriter file = new FileWriter( "insert file name here" );
BufferedWriter buffer = new BufferedWriter( file ) ;
buffer.write( "insert file content here" ) ;
buffer.newLine();
buffer.close();
}
catch ( IOException e )
{
//Insert error message here
}
And then read it like this
try
{
FileReader file = new FileReader( "insert file name here" ) ;
BufferedReader buffer = new BufferedReader( file );
String line = "" ;
while( ( line = buffer.readLine() ) != null )
{
System.out.println( line ) ;
}
buffer.close() ;
}
catch( IOException e )
{
//Insert error message here
}
Hope that helps
i dont recomend that you save JFrame object. here is a better solution you can save the students name and there grades on a text file and each time your program loads it will load the information from the text file.
Hint : you can use Input & Output streams dirctly but it's maybe a little bit sonfusing so go and read about these two classes :
Scanner (and how to use it to read from file)
PrintWriter (and how to use it to write to file)
P.S.: i could'v given you the code but it is much better learning experience to suffer a little bit to find information, because while you are trying to figure it out you will learn a lot of other things.
The frame is not an integral part of your application's state, it's just a way of displaying the important information (names, grades, etc). If you want to save your session, save the information the is currently on the screen and then re-create the JFrame with the deserialized information. An ObjectOutputStream is a reasonable way of writing things to disk, and and ObjectInputStream is good for reading the data back in. The documentation contains good examples. Also, your classes would need to implement Serializable.

Java cant write in a .txt

hello i desperately need your help,well i have a jframe with a jcombobox and 3 textfields i want anything i write in the textfields and the choice i make in the combobox to be written in a .txt i tried so many things but nothing , the file is being created as Orders.txt but remains blank :S this is my code i appreciate any help Thanks :)
public class addSalesMan extends JFrame {
private JComboBox namesJComboBox;
private JTextField text1;//gia to poso
private JTextField text2;//thn perigrafh
private JTextField text3;//kai to numero ths paragelias kai ola auta tha egrafontai sto Orders.txt
private JButton okJbutton;
private String names[] = {"Basilis Komnhnos", "Iwanna Papadhmhtriou"};
public String amount,name,description,number;
public addSalesMan() {
super("Προσθήκη παραγγελιών");
setLayout(new FlowLayout());//dialegoume to flowlayout
// TextFieldHandler handler = new TextFieldHandler(); writer.write(string);
//ftiaxonoume to combobox gia tn epilogi tou onomatos
namesJComboBox = new JComboBox(names);//orizmos JCOMBO BOX
namesJComboBox.setMaximumRowCount(2);//na emfanizei 2 grammes
add(namesJComboBox);
namesJComboBox.addItemListener(new ItemListener() {
//xeirozome to simvan edw dhladh tn kataxwrisei ston fakelo
public void itemStateChanged(ItemEvent event) {
//prosdiorizoyme an eina epilegmeno to plaisio elegxou
if (event.getStateChange() == ItemEvent.SELECTED) {
name = (names[namesJComboBox.getSelectedIndex()]);
// writer.newLine();
setVisible(true);
}
}
}); //telos touComboBOx
//dimioutgw pediou keimenou me 10 sthles gia thn kathe epilogh kai veveonomaste oti tha mporoume na ta epe3ergasoume kanontas ta editable
text1 = new JTextField("Amount",10);
add(text1);
text2 = new JTextField("Description",10);
add(text2);
text3 = new JTextField("Order Number",10);
add(text3);
TextFieldHandler handler = new TextFieldHandler();
text1.addActionListener(handler);
text2.addActionListener(handler);
text3.addActionListener(handler);
//private eswterikh clash gia ton xeirismo twn events twn text
//button kataxwrisis
okJbutton=new JButton("Καταχώρηση");
add(okJbutton);
ButtonHandler bhandler=new ButtonHandler();
okJbutton.addActionListener(bhandler);
Order order=new Order(name,amount,description,number);
Order.addOrders(name,amount,description,number);
}
private class ButtonHandler implements ActionListener{
public void actionPerformed(ActionEvent bevent ){
JOptionPane.showMessageDialog(addSalesMan.this,String.format("Η Καταχωρηση ήταν επιτυχής",bevent.getActionCommand()));
}
}
private class TextFieldHandler implements ActionListener {
//epe3ergasia twn simvantwn me kathe enter t xrhsth
public void actionPerformed(ActionEvent evt) {
String amount,description,number;
amount=text1.getText();
description=text2.getText();
number=text3.getText();
text1.selectAll();
text2.selectAll();
text3.selectAll();
}
if(evt.getSource()==text1 && evt.getSource()==text2 && evt.getSource()==text3){
JOptionPane.showMessageDialog(addSalesMan.this,String.format("Η Καταχωρηση ήταν επιτυχής",evt.getActionCommand()));
}
}
//actionperformed telos
//ean o xrhsths patisei enter sthn kathe epilogh antistixi kataxwrisi sto
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new addSalesMan().setVisible(true);
}
});
}
}
The writers are in another class. Here is the relevant code:
public static void addOrders(String name,String amount,String description,String o_number){
FileOutputStream fout;
try {
FileWriter fstream = new FileWriter("Orders.txt");
if(name!=null){
BufferedWriter out = new BufferedWriter(fstream);
out.write(name);
out.write(amount);
out.write(description);
out.write(o_number);
out.write("\t\n");
out.close();
}
} catch (IOException e) {
System.err.println ("Unable to write to file");
System.exit(-1);
}
}
It looks like the main problem is that you are calling Order.addOrders() in your constructor. Instead, you should call it when a user chooses to save it's selection. I assume you would like this to happen when the user presses the button. So the code should be added in the button's ActionListener.
What you might need to try is flushing and closing the writer when a user closes your frame.
Add the following to the constructor of your frame:
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
writer.flush();
writer.close();
}
});
The above code will flush and close the writer when a user closes the frame.
Your code is unclear, so I'm not sure where the writer variable is declared, I'm just assuming it is a class level variable.
Also, you need to open your file in 'append' mode if you want to add lines to the file instead of overwriting it every time. This can be achieved through the following:
new FileWriter(yourFilePath, true); // set append to true

Mysterious one time Casting Exception

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();
}
}

Categories