Append Textarea result from another class - java

I have two classes class Game and class wampusGUI. In wampusGUI class I have one textarea named displayTextArea under the method textarea1().
I am trying to append result to textarea from Game class. but when I am trying to access from that class . the function running fine and also the result is coming in that class (I just tested by simply System.out.print() method), but it is not appending to textarea. Here is my code.
// Code of wampusGUI class
public class wampusGUI extends javax.swing.JFrame {
/**
* Creates new form wampusGUI
*/
public wampusGUI() {
initComponents();
}
public void textArea1(String text) {
System.out.print(text);
displayTextArea.append(text); // this is not appending to textarea.
}
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new wampusGUI().setVisible(true);
Game g = new Game();
g.testing();
}
});
}
//Here is the code of Game class
private wampusGUI gui;
public void testing () {
String welCome=welcome();
gui= new wampusGUI();
gui.textArea1(welCome);
}

Make this Changes in your code
In Your First Class wampusGUI
public class wampusGUI extends javax.swing.JFrame {
/**
* Creates new form wampusGUI
*/
public wampusGUI() {
initComponents();
}
public void textArea1(String text) {
System.out.print(text);
displayTextArea.append(text); // this is not appending to textarea.
}
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
wampusGUI w=new wampusGUI();
w.setVisible(true);
Game g = new Game(w);
g.testing();
}
});
}
And for Second class Game
private wampusGUI gui;
//Add Contructor with Parameter
public Game(wampusGUI w){
//put this line of code at the end
gui=w;
}
public void testing () {
String welCome=welcome();
gui.textArea1(welCome);
}
this will work...

To append the text in TextArea
String str = textarea.getText();
str+="appending text";
textarea.setText(str);
It may help you.

You are creating one instance of wampusGUI inside run() of invokeLater, and one instance of wampusGUI inside testing() method.
What you are actually doing is appending the text to an textarea you can't see (probably) because you have the other one instance of wampusGUI set visible.

Related

Editing JLabel from JTextField in another class

I've looked around but nothing seems to help me out. Basically I'm writing a multithreaded chat program with a gui. The user inputs his name in a textfield in a Login class and hits the login button which directs him to a ClientGUI class. In the client GUI class theres a JLabel at the top that says
"Welcome to the ChatSystem (Username)"
. So what the user input in the textfield in the login class should appear in the JLabel after "Welcome to the ChatSystem" but I can't figure out why it doesn't work. Here's my code:
Login Class:
loginB = new JButton("Login");
main.add(loginB);
loginB.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
ClientGUI clientgui = new ClientGUI();
clientgui.setVisible(true);
}
}
ClientGUI class:
public ClientGUI(){
Login login = new Login();
String username = login.usernameTF.getText();
welcome = new JLabel("Welcome to ChatSystem "+username, SwingConstants.CENTER);
}
I understand that username should really by a JLabel and not a String but I have tried many ways to do this and I can't seem to get my head around this.
That is not going to work like that because
login.usernameTF.getText(); is actually a new created object in the ClientGUI constructor...
what I would suggest to do is to overload the constructor and to pass the name as parameter...
Example:
loginB.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
ClientGUI clientgui = new ClientGUI(getTheNameAndpassItHere);
clientgui.setVisible(true);
}
}
and then ClientGUI class:
public ClientGUI(String username){
//Login login = new Login();
// String username = login.usernameTF.getText();
welcome = new JLabel("Welcome to ChatSystem "+username, SwingConstants.CENTER);
}
Basically, you should use a Observer Pattern, which allows ClientGUI to generate events to interested parties when something changes.
This decouples your code and prevents the ClientGUI from doing things it shouldn't (like removing the label or it's parent component for example)
You could use some of the inbuilt listeners if they meet your needs, but for something like this, I'd prefer to use my own
public class LoginEvent extends EventObject {
private Throwable cause;
private String userName;
public LoginEvent(Object source) {
super(source);
}
public Throwable getCause() {
return cause;
}
public String getUserName() {
return userName;
}
}
public interface LoginListener extends EventListener {
public void loginFailed(LoginEvent evt);
public void loginSuccessful(LoginEvent evt);
}
Then you could add an instance of the listener to the ClientGUI...
loginB.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ClientGUI clientgui = new ClientGUI(getTheNameAndpassItHere);
clientgui.addLoginListener(new LoginListener() {
#Override
public void loginFailed(LoginEvent evt) {
Throwable cause = evt.getCause();
// Show error message
}
#Override
public void loginSuccessful(LoginEvent evt) {
String name = evt.getUserName();
// Update UI
}
});
clientgui.setVisible(true);
}
}
or something simular
the swings component are by default private you need to make them public by just little steps
1.go to the properties of the component and then to the code tab
2.you will find variable modifier as private make them public and as well as static if you want.
you will now be able to use the components with the same code

access object method from another class

I'm new to Java and oriented-object and I'm trying to create a chat program. Here's what I'm trying to do:
Somewhere in my Main.java
Window window = new Window;
Somewhere in my Window.java
History history = new History()
Somewhere in my History.java:
public History()
{
super(new GridBagLayout());
historyArea = new JTextArea(15, 40);
historyArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(historyArea);
/* some other code... */
}
public void actionPerformed(ActionEvent event)
{
String text = entryArea.getText();
historyArea.append(text + newline);
entryArea.selectAll();
historyArea.setCaretPosition(historyArea.getDocument().getLength());
}
public JTextArea getHistoryArea()
{
return historyArea;
}
public void addToHistoryArea(String pStringToAdd)
{
historyArea.append(pStringToAdd + newline);
historyArea.setCaretPosition(historyArea.getDocument().getLength());
}
Now that I'm in Server.java, I want to use the method addToHistoryArea. How can I do that without making my historyArea static? Because if I understand well how static works, I couldn't have different historyArea even if I create a new History...
Thanks for your help and tell me if I got it all wrong!
In your Server constructor, send the instance of your History object (e.g new Server (history), and then you can invoke, history.addToHistoryArea, other option would be have a setter method which sets an instance of history to an instance variable, and then just call the addToHistoryArea method
public class Server{
private History history;
public Server(History history){
this.history = history;
}
public void someMethod(){
this.history.addToHistoryArea();
}
}
Another way
public class Server{
private History history;
public void setHistory(History history){
this.history = history;
}
public void someMethod(){
this.history.addToHistoryArea();
}
}
In someplace in Server you can have History
public class Server{
private History history;
public void setHistory(History history){
this.history= history;
}
public void someMethod(){
history.addToHistoryArea();
}
}
Or if you don't want to have an instance in Server
public void someMethod(History history){
history.addToHistoryArea();
}
Or if you want to be more decoupled you can take approach with the observer pattern or perhaps a mediator if they are colleagues.
You may want to create a History object in the Server class and then call the addToHistoryArea() method on that history instance.
public class Server{
private History history;
public void setHistory(History history){
this.history = history;
}
public void methodCall(){
history.addToHistoryArea();
}
}

Continuously check the time?

So I'm making a little sample application that displays train times.
Right now the JTable in which the trains are displayed isn't dynamic.
What I'd like, is for the time to be checked every 30 secs or minute and the table would eliminate a train that "should have arrived".
I'm stuck however at the constantly checking time part. I've created a TimeChecker class to run in the background but it's not much use as when I put a infinite loop or thread into my JPanel class, the user interface doesn't show.
Here's my TimeChecker:
package controller;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class TimeChecker extends Thread {
private String timeStamp;
public String getTimeStamp() {
return timeStamp;
}
public void run() {
while(true) {
try {
Thread.sleep(2000);
String dateStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss").format(
Calendar.getInstance().getTime());
timeStamp = dateStamp.substring(9,13);
System.out.println(timeStamp);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
and here's my Panel class:
package view;
import java.awt.GridLayout;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import controller.*;
public class Panel extends JPanel {
/* JPanel containing the JTabbedPane stuff */
JTabbedPane jtp = new JTabbedPane();
TimeChecker tc = new TimeChecker();
public Panel() {
super(new GridLayout(1,0));
Table t = new Table("Haymarket");
jtp.add(t);
jtp.setTitleAt(0, "Haymarket");
add(jtp);
tc.setDaemon(true);
tc.start();
}
public void addTrain(String d, String c, String dep, String a) {
/*
* Receives 4 parameters to control
* the new entry required for a train
*/
Table t = (Table) jtp.getComponentAt(jtp.getSelectedIndex());
t.addTrain(d,c,dep,a);
}
public void addStation(String s) {
/*
* Adds a station, after prompting the
* user for a station name
*/
jtp.add(new Table(s));
jtp.setTitleAt(jtp.getTabCount()-1, s);
jtp.setSelectedIndex(jtp.getTabCount()-1);
}
public void addStation(Table t) {
jtp.add(t);
jtp.setTitleAt(jtp.getTabCount()-1,t.getStation());
}
public void removeAllStations() {
jtp.removeAll();
}
public void removeStation() {
/*
* Removes currently selected station
*/
jtp.remove(jtp.getSelectedIndex());
}
public void removeTrain() {
/*
* WIP: Removes a train
*/
Table t = (Table) jtp.getComponentAt(jtp.getSelectedIndex());
t.removeTrain();
}
}
Sounds like you want a javax.swing.Timer to fire every 30 seconds.
Alternatively, use a timer in a background thread (e.g. via a ScheduledExecutorService) - then fetch the information and only get the UI involved when you actually need to update the UI.
You've created a thread from the UI, which means that the thread will run with the same priority as the UI. You should not do that, but use SwingUtilities instead.

Cannot get variable from Child back to Parent in JAVA (Options Window)

STARTED - 3:00PM
UPDATE 1 - 5:36PM
Apply Button in the Option() class:
private void cmdApplyActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
hud.setTime(btnTxtTime);
hud.setTemp(btnTxtTemp);
hud.setSurface(btnTxtSurface);
hud.setWeather(btnTxtWeather);
hud.setRadiation(btnTxtRadiation);
dispose();
}
This is a section of the Option() Class.
public class Options extends javax.swing.JFrame {
public String btnTxtTime;
public String btnTxtTemp;
public String btnTxtSurface;
public String btnTxtWeather;
public String btnTxtRadiation;
public static boolean ApplyClicked;
/**
* Creates new form Profile
*/
private HUD hud;
public Options(HUD hud) {
initComponents();
this.hud = hud;
}
This is a method in Option() class:
public String getTime() {
if ("Day".equals(grpTimeOfDay.getSelection())) {
btnTxtTime = "Day";
return this.btnTxtTime;
}
if ("Night".equals(grpTimeOfDay.getSelection())) {
btnTxtTime = "Night";
return this.btnTxtTime;
}
return null;
}
This is how Options() is openned from within HUD():
private void cmdOptionsActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
Options o = new Options(hud);
this.getLocation(p);
o.setLocation((int) p.getX() + 100, (int) p.getY() + 100);
o.setVisible(true);
}
This is the start of my HUD() Class:
public abstract class HUD extends javax.swing.JFrame implements Runnable {
private Options o;
private HUD hud;
public HUD(Options o) {
initComponents();
this.o = o;
and this is the method from HUD() which gets the value of the JButtons from Options():
public void setTime(String strTime) {
strTime = o.getTime();
txtTime.setText(strTime);
}
However whenever I click Apply, the options set in Options() are not then set in the TextFields that display them in HUD() like they should be :/
It's difficult to navigate through your very lengthy code sample, however take a look at your cmdApplyActionPerformed() method. You are creating a new HUD() and setting values in it... and then doing absolutely nothing with it.
If you are trying to use the "Apply" button to modify an existing HUD object, your class needs to have a reference to it somewhere. If the HUD is the parent class which creates the Options, try having the Options store a reference to the parent in its constructor. Then, when you perform changes like this in the Options, you can perform them on the parent rather than on a new variable which has no effect.
private HUD parent;
/**
* Creates new form Profile
*/
public Options(HUD parent) {
initComponents();
this.parent = parent;
}
Then, in your event handler, you can have ...
parent.setTime(btnTxtTime);
parent.setTemp(btnTxtTemp);
parent.setSurface(btnTxtSurface);
parent.setWeather(btnTxtWeather);
parent.setRadiation(btnTxtRadiation);
dispose();
From what I understand, HUD is your 'main window' and the users gets to this option frame from that window.
But when you apply, you're setting the properties on a new HUD, not the one you had before.
To fix this, you need a handle to your main window in your config window, so that you can set the properties on it.
in your hud:
ConfigFrame config = new ConfigFrame();
config.setHUD(this);
config.setVisible(true);
In your config
private HUD hud;
public void setHUD(HUD hud){
this.hud = hud;
}
then just leave out the HUD hud = new hud();

Overriding constructors in Java

For school I need to learn Java and since I'm used to C++ (like Cocoa/Objective-C) based languages, I get really frustrated on Java.
I've made a super-class (that can also be used as a base-class):
public class CellView {
public CellViewHelper helper; // CellViewHelper is just an example
public CellView() {
this.helper = new CellViewHelper();
this.helper.someVariable = <anything>;
System.out.println("CellView_constructor");
}
public void draw() {
System.out.println("CellView_draw");
}
public void needsRedraw() {
this.draw();
}
}
public class ImageCellView extends CellView {
public Image someImage;
public ImageCellView() {
super();
this.someImage = new Image();
System.out.println("ImageCellView_constructor");
}
public void setSomeParam() {
this.needsRedraw(); // cannot be replaced by this.draw(); since it's some more complicated.
}
#Override public void draw() {
super.draw();
System.out.println("ImageCellView_draw");
}
}
Now, when I call it like this:
ImageCellView imageCellView = new ImageCellView();
imageCellView.setSomeParam();
I get this:
CellView_constructor
ImageCellView_constructor
CellView_draw
However, I want it to be:
CellView_constructor
ImageCellView_constructor
CellView_draw
ImageCellView_draw
How can I do this?
Thanks in advance,
Tim
EDIT:
I also implemented this method to CellView:
public void needsRedraw() {
this.draw();
}
And this to ImageCellView:
public void setSomeParam() {
this.needsRedraw(); // cannot be replaced by this.draw(); since it's some more complicated.
}
And I've been calling this:
ImageCellView imageCellView = new ImageCellView();
imageCellView.setSomeParam();
Does this causes the problem (when I call a function from the super it calls to the super only)? How can I solve this... (without having to redefine/override the needsRedraw()-method in every subclass?)
You should get proper output.
I tried you example just commented unrelated things:
import java.awt.Image;
public class CellView {
//public CellViewHelper helper; // CellViewHelper is just an example
public CellView() {
//this.helper = new CellViewHelper();
//this.helper.someVariable = <anything>;
System.out.println("CellView_constructor");
}
public void draw() {
System.out.println("CellView_draw");
}
public static void main(String[] args) {
ImageCellView imageCellView = new ImageCellView();
imageCellView.draw();
}
}
class ImageCellView extends CellView {
public Image someImage;
public ImageCellView() {
super();
//this.someImage = new Image();
System.out.println("ImageCellView_constructor");
}
#Override public void draw() {
super.draw();
System.out.println("ImageCellView_draw");
}
}
and I get following output:
CellView_constructor
ImageCellView_constructor
CellView_draw
ImageCellView_draw
This is exactly what you want, and this is what your code print's.
The short answer is "you can't."
Objects are constructed from the bottom up, calling base class initializers before subclass initializers and base class consrtuctors before subclass constructors.
EDIT:
The code you have looks good, based on your edit. I would go through the mundane tasks like ensuring that you have compiled your code after you've added you System.out.println calls to your subclass

Categories

Resources