Accessing data from another class which reads values - java

Ok, so here is a problem: I have main class which generates a window and two buttons:
...
public MainWindow()
{
...
b_read.addActionListener(new ReadStudents());
b_open_all.addActionListener(new OpenStudents());
...
In ReadStudents.java class I load data from a file with JFileChooser and print it on the screen. Sample of code thats load file:
#Override
public void actionPerformed(ActionEvent e) {
...
JFileChooser fc = new JFileChooser(".");
...
int rez = fc.showOpenDialog(fc);
if (rez == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile();
...
So now in my ReadStudents.java class variable "file" has my loaded information.
How do i pass this variable with containing information in it to a class that prints Students on the screen (second button OpenStudents.java) ?
Edit:1) I can not initialize an object of ReadStudents.java in OpenStudents.java class because in the new object variable "file" will be empty. Something is loaded to a "file" only when a button b_read is pressed.

One option would be to implement the action listener on your MainWindow class and the call a method in the ReadStudents/OpenStudents that return the list of files.
For example:
/**
* Main window class.
*/
public static void main(String args[]) {
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new BorderLayout());
mainFrame.setSize(100, 100);
final StudentReader student = new StudentReader();
JButton button = new JButton("Click Me");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Make the call here. Take note!
// Look at the return type!
List<String> strings = student.fileNames();
for (String s : strings) {
System.out.println(s);
}
}
});
mainFrame.add(button);
mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
}
public class StudentReader {
public List<String> fileNames() {
// Do your magic here :)
// Open a dialog. Get the files.
// Return it as a list
return Arrays.asList(new String[]{"Filename"});
}
}
I Hope this helps!

Related

Change value of public variable in Java, used by multiple frames

I have two frames in NetBeans 9.0 as frame1.java, frame2.javaand the main class as main.java.
If I declare a public variable in frame1.java as
public String stringName;
and a function fn() which gives the value of stringName in frame1as say "abcd".
When I write this in frame2,
frame1 fm = new frame1();
String str = frame1.stringName;
System.out.print(str);
I get the output as null. But what I require is "abcd".
What am I doing wrong, and what should it be?
Thanks for help!
Edit:
I have linked frame1 and frame2 such that the GUI from frame1 leads to frame2, and so does the value.
Edit 2
The process goes like this:
GUI of frame1 is visible >> based on user's input, function fn() stores the value, say "abcd" in stringName >> a button click in frame1 leads to frame2>> variable str gets the value from stringName >> System.out.print(str) outputs the value as null .
CODE
frame1:
public class frame1 extends javax.swing.JFrame {
public String stringName;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){
stringName = jTextField1.getText(); // gets a not null value
}
}}
frame2:
public class frame2 extends javax.swing.JFrame {
frame1 fm = new frame1();
String str = frame1.stringName;
System.out.print(str); //outputs a null value
}
The point ist that you are crating a new Instance (frame1, fm) in your class frame2. So the value from the string in this new Instance is null. You need a reference to your old Instance which you maybe have initialised in your main method?
Something like that:
String str = myOldInstance.stringName;
But you should create getter an setter and make your var private.
But to help you exactly we need more Code.
in this case the best is Listener pattern.
Create interface of listener, which will inform about change text. In class - target of this information - create instance of this listener and return that. In class - source of information - set listener and put on field.
When you want inform of change text, you fire method of listener, and on seconde frame will execute implementation of method.
Below example - I fire on button click.
Any way, field should be private, and add getter and setter. Public fields are bad.
Main class
public class App {
public static void main(String[] args) {
Frame1 f1=new Frame1();
Frame2 f2=new Frame2();
TextListener textListener = f2.getListener();
f1.setListener(textListener);
}
}
Listener
public interface TextListener {
public void onTextPropagate(String text);
}
Frame classes
public class Frame1 extends JFrame{
private TextListener listener;
JButton button;
public Frame1() {
super("Frame1");
setBounds(200, 200, 400, 600);
button=new JButton("Action");
button.setBounds(100, 200, 200, 100);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(listener!=null) {
String text = UUID.randomUUID().toString();
System.out.println("On Frame1:\t"+text);
listener.onTextPropagate(text);
}
}
});
this.add(button);
setVisible(true);
}
public void setListener(TextListener listener) {
this.listener=listener;
}
}
public class Frame2 extends JFrame{
public Frame2() {
super("Frame2");
setBounds(100, 100, 200, 400);
setVisible(true);
}
public TextListener getListener() {
return new TextListener() {
#Override
public void onTextPropagate(String text) {
reactOnChangeText(text);
}
};
}
private void reactOnChangeText(String text) {
System.out.println("On Frame2:\t"+text);
}
}

Assigning values to JButtons from object arrayList

I'm working on an EPOS system, and as part of the program, I am generating a GridLayout of all items that are stored in an ArrayList. Within the items ArrayList, all the objects are stored with their necessary member variables, such as name, barcode and price. I have currently made it so that the grid is populated, however the buttons are action-less, and I am quite unsure how to handle the data from the classes, is there perhaps some way to assign the values of the current item object that is being iterated over onto the button being made? As each button is made by my code, and is not "hand made". The relevant code is as below:
public class gridCreator extends JFrame {
ObjectCreator obj = new ObjectCreator();
GridLayout itemGrid = new GridLayout();
JFrame frame = new JFrame("pls work");
static gridCreator instance;
public static void main(String[] args) throws FileNotFoundException {
instance = new gridCreator();
instance.createGrids();
instance.createAndShowGUI();
}
public void createGrids() throws FileNotFoundException{
obj.loadItems();
itemGrid.setColumns(20);
itemGrid.setRows(4);
for (ObjectCreator.Item item : obj.items){
addComponentsToPane(item);
}
}
private void addComponentsToPane(ObjectCreator.Item item) {
JButton button = new JButton(item.getName());
frame.add(button);
}
As a side note, the ObjectCreator class is where the objects themselves are made.
You can make the class implement ActionListener, and assign all the buttons that actionListener:
public class gridCreator extends JFrame implements ActionListener{
ObjectCreator obj = new ObjectCreator();
GridLayout itemGrid = new GridLayout();
JFrame frame = new JFrame("pls work");
static gridCreator instance;
public static void main(String[] args) throws FileNotFoundException {
instance = new gridCreator();
instance.createGrids();
instance.createAndShowGUI();
}
public void createGrids() throws FileNotFoundException{
obj.loadItems();
itemGrid.setColumns(20);
itemGrid.setRows(4);
for (ObjectCreator.Item item : obj.items){
addComponentsToPane(item);
}
}
private void addComponentsToPane(ObjectCreator.Item item) {
JButton button = new JButton(item.getName());
frame.add(button);
}
#Override
public void actionPerformed(ActionEvent e) {
//do actions here
}
Then, in the action listener of the JFrame, you can make a case specific action.

Why is my output null every time?

Hello I have a class that opens a JFrame and takes in a text. But when I try getting the text it says its null.
Everytime I click the button I want the System.out to print the text I entered in the textArea.
This is my first class :
public class FileReader {
FileBrowser x = new FileBrowser();
private String filePath = x.filePath;
public String getFilePath(){
return this.filePath;
}
public static void main(String[] args) {
FileReader x = new FileReader();
if(x.getFilePath() == null){
System.out.println("String is null.");
}
else
{
System.out.println(x.getFilePath());
}
}
}
This is a JFrame that takes in the input and stores it in a static String.
/*
* This class is used to read the location
* of the file that the user.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.event.*;
import javax.swing.*;
public class FileBrowser extends JFrame{
private JTextArea textArea;
private JButton button;
public static String filePath;
public FileBrowser(){
super("Enter file path to add");
setLayout(new BorderLayout());
this.textArea = new JTextArea();
this.button = new JButton("Add file");
add(this.textArea, BorderLayout.CENTER);
add(this.button, BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 100);
setVisible(true);
this.button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
filePath = new String(textArea.getText());
System.exit(0);
}
});
}
}
But everytime I run these programs I get
String is null.
You are mistaken by the way how JFrames work. A JFrame does not stall the execution of the code until it is closed. So, basically, your code creates a JFrame and then grabs the filePath variable in that object, before the user could have possibly specified a file.
So, to solve this, move the code that outputs the filepath to stdout to the ActionListener you have. Get rid of the System.exit() call, and use dispose() instead.
Update: You should have this code for the ActionListener:
this.button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
filePath = new String(textArea.getText());
if(filePath == null){
System.out.println("String is null.");
}
else
{
System.out.println(filePath);
}
dispose();
}
});
And as main method:
public static void main(String[] args)
{
FileBrowser x = new FileBrowser();
}
Your main does not wait until the user has specified a text in the textArea. You could prevent this behaviour by looping until the text in the textArea is set or you could place the logic of the main function into the ActionListener to handle the event.
Following the second way the main function only creates a new FileBrowser object.

Cannot set variable by listener

I'm beginning with GUI and listeners. I want to choose and set file from pc into the "File zvolenysubor" in class Hlavna by another class implementing ActionListener.
I can choose file in the listener's actionPerformed method and set it into "File subor" but I fail in saving it into the "File zvolenysubor" in my main (and all of my ideas how to do it failed too).
What should I change/add there please?
Here are my classes:
public class Hlavna {
public static void main(String[] args) {
File zvolenysubor = null;
JFrame frame = new JFrame("ABCDE");
JButton vybersuboru = new JButton("vyber");
vybersuboru.setBounds(220, 15, 200, 20);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640, 480);
frame.add(vybersuboru);
frame.setLayout(null);
VyberListener list1 = new VyberListener(zvolenysubor);
vybersuboru.addActionListener(list1);
vybersuboru.setText("vyber subor");
}
}
public class VyberListener implements ActionListener {
private File subor;
public VyberListener(File subor){
this.subor = subor;
}
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
System.out.println("lol");
FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Images", "jpg", "gif");
chooser.setFileFilter(filter);
chooser.showOpenDialog(null);
subor = chooser.getSelectedFile();
System.out.println(subor.getAbsolutePath());
}
}
Not really sure what you're asking here. Java passes method arguments by value as opposed to reference, so the File parameter you're supplying to the constructor of VyberListener is only updated in the VyberListener class by the actionPerformed method, not the reference in your main method. What is it you're trying to accomplish here?
If you're trying to update "File zvolenysubor" in your main method, it may be worthwhile making your "File subor" in your VyberListener class public, so that it can be accessed by the main method.
Update
To minimise the amount of chatter in the comments below, I'll try and summarise. Although Java supports pass by reference, it's actually only passing pointers by reference. Thus in your example, you pass a null object reference (subor) to your ActionListener, which is then overwritten in the actionPerformed method:
subor = chooser.getSelectedFile();
Thus your File variable "zvolenysubor" is never updated. In order to update fields in your Hlavna class, I recommend using the following "Container" pattern:
public class Hlavna {
public static void main(String[] args) {
// New "FileReference" container instance
FileReference zvolenysubor = new FileReference();
JFrame frame = new JFrame("ABCDE");
JButton vybersuboru = new JButton("vyber");
vybersuboru.setBounds(220, 15, 200, 20);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640, 480);
frame.add(vybersuboru);
frame.setLayout(null);
VyberListener list1 = new VyberListener(zvolenysubor);
vybersuboru.addActionListener(list1);
// Retrieves the updated File instance
File updatedFile = zvolenysubor.getFile();
}
}
public class VyberListener implements ActionListener {
private FileReference subor;
public VyberListener(FileReference subor){
this.subor = subor;
}
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Images", "jpg", "gif");
chooser.setFileFilter(filter);
chooser.showOpenDialog(null);
subor.setFile(chooser.getSelectedFile());
}
}
// FileReference container class allows the file reference to be updated by the ActionListener
// without re-initialising the object reference
public class FileReference {
private File _file;
public void setFile(File file) {
_file = file;
}
public File getFile() {
return _file;
}
}

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

Categories