MultiThreading with instance variable java - java

I have a class like,
Class A extends B {
String test = "";
String first = "";
public void testMethod() {
new Thread() {
public void run() {
testThreadMethod();
}
}.start();
}
public void testThreadMethod() {
System.out.println(first + " " + test);
}
}
The above class compiles fine. But in run time, the error is thrown in system.out.println() saying "invalid thread access".
Is there any wrong in the code. Accessing instance variables in multithread not allowed? Is there any way to access the instance variable inside the thread?
Thanks in advance.
EDITED NEW: To Reproduce the problem
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
public class SWTView extends ViewPart{
public static Display display;
public static Shell shell;
static Text sampleText;
static String testField1 = "";
static String firstField2 = "";
public static void main(String[] args) {
display = new Display();
shell = new Shell(display);
// Create a new Gridlayout with 2 columns
// where the 2 column do not have the
// same size
GridLayout layout = new GridLayout(2, false);
// set the layout of the shell
shell.setLayout(layout);
// Create a label and a button
sampleText = new Text(shell, SWT.NONE);
Label label = new Label(shell, SWT.NONE);
label.setText("A label");
Button button = new Button(shell, SWT.PUSH);
button.setText("Press Me");
// Create a new label that will spam two columns
label = new Label(shell, SWT.BORDER);
label.setText("This is a label");
// Create new layout data
GridData data = new GridData(GridData.FILL,
GridData.BEGINNING, true, false, 2, 1);
label.setLayoutData(data);
// Create a new label which is used as a separator
label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
// Create new layout data
data = new GridData(GridData.FILL, GridData.BEGINNING, true,
false, 2, 1);
data.horizontalSpan=2;
label.setLayoutData(data);
// Create a right aligned button
Button b = new Button(shell, SWT.PUSH);
b.setText("New Button");
b.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
new Thread() {
public void run() {
printInstanceVariables();
}
}.start();
//showProgressBar() ---> // This is been implemented in another file which will shoe progress bar
}
});
data = new GridData(GridData.END, GridData.BEGINNING, false,
false, 2, 1);
b.setLayoutData(data);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public static void printInstanceVariables() {
System.out.println("Text entered is :: " +sampleText.getText());
System.out.println("test Field 1 is :: " + testField1);
System.out.println("first Field 2 is :: " + firstField2);
}
#Override
public void createPartControl(Composite arg0) {
// TODO Auto-generated method stub
}
#Override
public void setFocus() {
shell.setFocus();
}
}
The above code will throw invalid thread acesses ecpection # printInstanceVariables() first system.out.println()
Answer: Got it.. It is because of accessing the component Text inside the thread in printInstanceVariables(). When i pass this component as paramter, everything works fine. Thanks for all you answers.

This program compiles and executes as expected (it prints a space and a new line). Your problem is somewhere else:
public class Test {
public static void main(String[] args) throws Exception {
A a = new A();
a.testMethod();
}
static class A {
String test = "";
String first = "";
public void testMethod() {
new Thread() {
public void run() {
testThreadMethod();
}
}.start();
}
public void testThreadMethod() {
System.out.println(first + " " + test);
}
}
}

I tried your code without extending class B and its working fine. What does your class B contain? Is there really any need to extend class B?

anonymous inner class is only allowed access FINAL member variable.
this is JVM specification.
i doubt why there is no warning when your code be compiled.
in fact i could get nothing out put when run these code. is there something wrong?
i rewrite the codes, test it and find
it can't access a member variable when the thread in anonymous inner class.
please see the output from eclipse.

Related

refresh gui in swt button listener

I have following class.
Why the btnDecorate is allways enabled? I wanted to disable the button when the loop is under processing.
Why text.redraw() works only in the end of loop? I wanted to see the box sequently on every character.
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class SampleRefreshStyledText {
public static void main(String[] args) {
final Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout(SWT.VERTICAL));
final Button btnDecorate = new Button(shell, SWT.NONE);
btnDecorate.setText("Decorate");
final StyledText text = new StyledText(shell, SWT.NONE);
text.setText("ABCDEFGHIJKLMNOPRQ\n1234567890");
btnDecorate.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent event) {
btnDecorate.setEnabled(false);
for (int i = 0; i < text.getText().length(); i++) {
StyleRange styleRange = new StyleRange();
styleRange.start = i;
styleRange.length = 1;
styleRange.borderColor = display.getSystemColor(SWT.COLOR_RED);
styleRange.borderStyle = SWT.BORDER_SOLID;
styleRange.background = display.getSystemColor(SWT.COLOR_GRAY);
text.setStyleRange(null);
text.setStyleRange(styleRange);
text.redraw();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
btnDecorate.setEnabled(true);
}
#Override
public void widgetDefaultSelected(SelectionEvent arg0) {}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
You can't write loops like this with SWT.
All UI operations occur on the single UI thread. Calling Thread.sleep puts the UI thread to sleep and nothing at all will happen.
The redraw call only requests that the text is redrawn, it will not actually happen until the next time the display.readAndDispatch() is run, so doing this repeatedly in a loop doesn't work.
What you have to do is run the first step of your loop once. You must then arrange to run the next step 500ms later without blocking the thread. You can do this using the Display.timerExec method to request that code is run at a later time:
display.timerExec(500, runnable);
where runnable is a class implementing Runnable that does the next step. At the end of this code you call timerExec again until you have worked your way through all the steps.

Opening one shell each time

In my project i have a shell, in the shell there are 3 buttons, i want that a click on each button will open a shell ,but i want that if a shell is already open due to a click on a button then that shell will be closed and a new shell will be opened.
(I dont want 2 shell from clicking buttons to be open at the same time)
But i have no idea how to do this.
In this class the opening of the shells should be.
public class ClickLabel implements MouseListener
{
Shell shell;
int p;
public ClickLabel(int p)
{
shell = new Shell();
this.p = p;
}
#Override
public void mouseDoubleClick(MouseEvent e) {}
#Override
public void mouseDown(MouseEvent e) {}
#Override
public void mouseUp(MouseEvent e) {
shell.open();
}
}
Can anyone help me?
Here is simple example with buttons and one active Shell, examine that:
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Example{
public static void main(String[] args) {
new Example();
}
private Shell openedShell;
public Example() {
final Display display = new Display ();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
SelectionAdapter adapter = new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
if(openedShell != null){
openedShell.dispose();
}
openedShell = new Shell(display);
openedShell.setSize(200,200);
openedShell.setText(((Button)e.getSource()).getText());
openedShell.open();
}
};
for(int i =1;i<4;i++){
Button b = new Button(shell, SWT.PUSH);
b.setText("shell "+i);
b.addSelectionListener(adapter);
b.pack();
}
shell.pack();
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}

Can't print to JTextArea from another class

I am attempting to print to my JTextArea from another class. I have the class ActivityLogger call method Alert inside of my main class Risk_Mgnt_Manager which is where the JTextArea is located. I am able to pass the string into this method and print to counsel but it won't append or setText to the JTextArea. What am I missing?
My goal is to have different classes send messages to the class ActivityLogger which in turn sends it to the JTextArea.
Any examples are appreciated and Thank you in advance.
Main class
package risk_mgnt_manager;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
public class Risk_Mgnt_Manager extends JFrame{
boolean begin = false;
String message = null;
JTextArea text = new JTextArea();
JButton Start = new JButton("Start");//exit program button
JButton End = new JButton("End");//Ok button executes message creation
JButton Exit = new JButton("Exit Program");
public void Alert(String a){
System.out.println(a); // This is printing correctly
text.append(a + "\n"); // why won't this display the string?
}
public Risk_Mgnt_Manager(){
text.setEditable(false);
text.setWrapStyleWord(true);
text.setLineWrap(true);
JScrollPane scroll = new JScrollPane(text);
setLayout(new GridLayout(2, 3, 5, 5)); //LayoutManager Setup
JPanel myPanel = new JPanel(new GridLayout(3,0));
//JPanel myPanel2 = new JPanel(new GridLayout(1, 1));
//JPanel myPanel3 = new JPanel(new GridLayout(1, 1));
JPanel myPanel4 = new JPanel(new GridLayout(1, 1));
myPanel.add(new JLabel("Start Automated Processes: "));
myPanel.add(Start);
myPanel.add(new JLabel("End Automated Processes: "));
myPanel.add(End);
myPanel.add(new JLabel(" "));
myPanel.add(Exit);
myPanel4.add(text);
Start.addActionListener(new startActions());//Listener for button 1
End.addActionListener(new stopActions());//Listener for button 2
Exit.addActionListener(new Quit());//Listener for button 2
add(myPanel);
//add(myPanel2);
//add(myPanel3);
add(myPanel4);
}
public void StartAutomation(boolean start) throws SAXException, ParserConfigurationException, IOException, SQLException{
//calls test class
Test t = new Test();
t.mainTest(begin);
//ignore these classes
// Step one import settlement data from FIX 1 settlement tables
ImportSettles tbl = new ImportSettles();
//tbl.DataTransfer(begin);
// Step two import Real-Time price data from t_span_price on FIX 1
ImportSpanPrice tbl2 = new ImportSpanPrice();
//tbl2.DataTransfer1(begin);
// Step three import from xml file
ImportTradeData tbl3 = new ImportTradeData();
//tbl3.parseXML(begin);
// Step four not used as of 11/26/2013
ImportFirmRpt tbl4 = new ImportFirmRpt();
// Step five import poew.csv file
ImportPOEW tbl5 = new ImportPOEW();
//tbl5.csvImportPOEW(begin);
// Step six import paycollect.csv file
ImportPaycollect tbl6 = new ImportPaycollect();
//tbl6.csvImportPaycollect(begin);
// Step seven import data from RISK 1
ImportSecDeposit tbl7 = new ImportSecDeposit();
//tbl7.DataTransfer2(begin);
// Step 8 import FCM financial info, WinJammer not used as of 11/26/2013
ImportFCM tbl8 = new ImportFCM();
// Step nine import CGM_post.csv file
ImportCGMPost tbl9 = new ImportCGMPost();
//tbl9.csvImportCGMPost(begin);
// Step ten import RM_Intraday_paycollect.csv
ImportIntraday tbl10 = new ImportIntraday();
//tbl10.csvImportIntra(begin);
}
private static void ProjectFrame(){
Risk_Mgnt_Manager projectFrame = new Risk_Mgnt_Manager();
projectFrame.setSize(500, 300); //JFrame size set
projectFrame.setLocationRelativeTo(null); //JFrame centered to center of screen
projectFrame.setTitle("Automation Control"); //JFrame Title
projectFrame.setVisible(true);//JFrame is visible upon start of program
projectFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
ProjectFrame();
}
static class Quit implements ActionListener {
public void actionPerformed (ActionEvent e) {
//Once Exit JButton is pressed the program exits
System.exit(0);
}
}
public class startActions implements ActionListener {
public void actionPerformed (ActionEvent e) {
//Once Exit JButton is pressed the program exits
begin = true;
try {
StartAutomation(begin);
} catch (SAXException ex) {
Logger.getLogger(Risk_Mgnt_Manager.class.getName()).log(Level.SEVERE, null, ex);
} catch (ParserConfigurationException ex) {
Logger.getLogger(Risk_Mgnt_Manager.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Risk_Mgnt_Manager.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Risk_Mgnt_Manager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class stopActions implements ActionListener {
public void actionPerformed (ActionEvent e) {
//Once Exit JButton is pressed the program exits
begin = false;
try {
StartAutomation(begin);
} catch (SAXException ex) {
Logger.getLogger(Risk_Mgnt_Manager.class.getName()).log(Level.SEVERE, null, ex);
} catch (ParserConfigurationException ex) {
Logger.getLogger(Risk_Mgnt_Manager.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Risk_Mgnt_Manager.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Risk_Mgnt_Manager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Test class
package risk_mgnt_manager;
import java.util.Date;
/**
*
* #author bgilbert
*/
public class Test {
public void mainTest(boolean a){
ActivityLogger act = new ActivityLogger();
act.logger("Testing message reporting " + new Date(), 1, true);
}
}
ActivityLogger class
package risk_mgnt_manager;
/**
*
* #author MLaMeyer
*/
public class ActivityLogger{
private String message;
// this will perform different purposes once I can print to JTextArea
public void logger(String log, int type, boolean execution){
if (execution == true) {
message = log;
}
if (execution == false) {
message = log;
}
print();
}
// calls method Alert in main class and passes the string correctly
public void print(){
Risk_Mgnt_Manager m = new Risk_Mgnt_Manager();
m.Alert(message);
}
}
Your program prints out to the other class, just not in the object displayed:
public void print(){
Risk_Mgnt_Manager m = new Risk_Mgnt_Manager();
m.Alert(message);
}
When you create a new Risk_Mgnt_Manager, you do just that, create a new completely unique Risk_Mgnt_Manager object, one that is not displayed. Printing to it will have no effect on the displayed one.
A the solution is to pass in a reference to your logger class to the actual displayed Risk_Mgnt_Manager object.
public class ActivityLogger{
private String message;
private Risk_Mgnt_Manager m; // ***** added
public ActivityLogger(Risk_Mgnt_Manager m) {
this.m = m; // ****** added
}
// this will perform different purposes once I can print to JTextArea
public void logger(String log, int type, boolean execution){
if (execution == true) {
message = log;
}
if (execution == false) {
message = log;
}
print();
}
// calls method Alert in main class and passes the string correctly
public void print(){
// Risk_Mgnt_Manager m = new Risk_Mgnt_Manager();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
m.Alert(message);
}
});
}
}
Whatever you do, don't attempt to solve this my making anything static as that road will lead to misery.
You need to update the UI in separate Thread, I mean UI related operations should run on the Event dispatch thread. Add constructor in your ActivityLogger class like Hovercraft's solution then try,
SwingUtilities.invokeLater(new Runnable() {
public void run() {
text.append(a+"\n");
}
});
First of all make the frame visible in your constructor.
public Risk_Mgnt_Manager(){
setVisible(true);
}
Then as per solution by Hovercraft pass by reference.

Show Page loading no browser until page is fully loaded

I want to hide the content of html page until its fully loaded. The idea is I want to get the content of html page do some processing and set the content back again. For doing so I am able to retrieve the text and do some processing on it. But the problem is , till the time processing is not complete, I want to hide the original html page and instead wanna show some dummy page.
I want to hover a shell on browser window and remove it when the loading is complete. I tried to hide the browser widget but that is not working as per the expectations.
Here is the snippet for the same.
package browserapp;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.extended.LocationEvent;
import org.eclipse.swt.browser.extended.LocationListener;
import org.eclipse.swt.browser.extended.ProgressEvent;
import org.eclipse.swt.browser.extended.ProgressListener;
import org.eclipse.swt.browser.extended.Browser;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class MyBrowser_1 {
/**
* Runs the application
*/
Display display = new Display();
protected boolean done;
public void run() {
final Shell shell = new Shell(display);
shell.setText("Simple Browser");
createContents(shell);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
/**
* Creates the main window's contents
*
* #param shell the main window
*/
private void createContents(final Shell shell) {
shell.setLayout(new FormLayout());
// Create the composite to hold the buttons and text field
Composite controls = new Composite(shell, SWT.NONE);
FormData data = new FormData();
data.top = new FormAttachment(0, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
controls.setLayoutData(data);
// Create the web browser
final Browser browser = new Browser(shell, SWT.NONE);
browser.addLocationListener(new LocationListener() {
#Override
public void changing(LocationEvent event) {
// TODO Auto-generated method stub
//browser.setVisible(false);
Image image = new Image(display,
"C:\\Documents and Settings\\My
Documents\\Pictures\\loadingAnimation.gif");
///shell.setBackgroundImage(image);
}
#Override
public void changed(LocationEvent event) {
// TODO Auto-generated method stub
}
});
browser.addProgressListener(new ProgressListener()
{
public void completed(ProgressEvent event)
{
}
public void changed(ProgressEvent event)
{
int progressWorked=0;
if (event.total == 0)
return;
done = (event.current == event.total);
int percentProgress = event.current * 100 / event.total;
System.out.println("Loading...");
if (done)
{
progressWorked = 0;
System.out.println("Loading completed...");
//browser.setVisible(true);
//maskPage(browser, maskedMap);
} else if (progressWorked == 0)
{
progressWorked = percentProgress;
} else
{
progressWorked = event.current;
}
}
});
data = new FormData();
data.top = new FormAttachment(controls);
data.bottom = new FormAttachment(100, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
browser.setLayoutData(data);
// Create the controls and wire them to the browser
controls.setLayout(new GridLayout(7, false));
// Create the back button
Button button = new Button(controls, SWT.PUSH);
button.setText("Back");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.back();
}
});
// Create the forward button
button = new Button(controls, SWT.PUSH);
button.setText("Forward");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.forward();
}
});
// Create the refresh button
button = new Button(controls, SWT.PUSH);
button.setText("Refresh");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.refresh();
}
});
// Create the stop button
button = new Button(controls, SWT.PUSH);
button.setText("Stop");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.stop();
}
});
// Create the address entry field and set focus to it
final Text url = new Text(controls, SWT.BORDER);
url.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
url.setText("https://netbanking.hdfcbank.com/netbanking/");
url.setFocus();
// Create the go button
button = new Button(controls, SWT.PUSH);
button.setText("Go");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.setUrl(url.getText());
}
});
GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, true, false);
Label status = new Label(controls, SWT.BORDER);
status.setLayoutData(gridData2);
// Allow users to hit enter to go to the typed URL
shell.setDefaultButton(button);
}
/**
* The application entry point
*
* #param args the command line arguments
*/
public static void main(String[] args) {
MyBrowser_1 browser=new MyBrowser_1();
browser.run();
}
}

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

Categories