Launch 3 threads and print them all inside a JTextArea

Can't figured it out :Sinstead of using the console , i want to do the same but in a JTextArea

import java.awt.BorderLayout;

import java.awt.Container;

import javax.swing.JFrame;

import javax.swing.JTextArea;

publicclass ThreadTArea{

publicstaticvoid main(String[] args){

Interface inter =new Interface();

inter.execute();

PrintChar2 letra_a =new PrintChar2('a', 100, inter);

PrintChar2 letra_b =new PrintChar2('b', 100, inter);

PrintNum2 numero =new PrintNum2(100, inter);

letra_a.start();

numero.start();

letra_b.start();

}

}

class PrintChar2extends Thread{

privatechar letra;

privateint times;

Interface inter;

public PrintChar2(char letra,int times, Interface inter){

this.letra = letra;

this.times = times;

inter =new Interface();

}

publicvoid run(){

for(int i = 1; i <= times; i++){

// Print into the TextArea

try{

Thread.sleep(1000);

}catch(InterruptedException e){ e.printStackTrace();}

}

}

}

class PrintNum2extends Thread{

privateint times;

Interface inter;

public PrintNum2(int times, Interface inter){

this.times = times;

inter =new Interface();

}

publicvoid run(){

for(int i = 1; i <= times; i++){

try{

Thread.sleep(1000);

}catch(InterruptedException e){ e.printStackTrace();}

}

}

}

class Interface{

public Interface(){

Container c = frame.getContentPane();

c.setLayout(new BorderLayout());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

c.add(area, BorderLayout.CENTER);

}

private JFrame frame =new JFrame("Result");

private JTextArea area =new JTextArea();

publicvoid printThreads(....){

//Maybe this is not necessary

}

publicvoid execut(){

frame.pack();

frame.setLocation(300,300);

frame.setVisible(true);

}

}

Thanks

[4966 byte] By [Java__Estudantea] at [2007-11-26 15:23:53]
# 1
Swing isn't thread safe, you need to update the contents of the text area on the event thread.
macrules2a at 2007-7-8 21:39:14 > top of Java-index,Desktop,Core GUI APIs...
# 2

Hm

1. don't extend Thread, implement Runnable

2. 'Interface' is possibly the worst name for a class I can think of

3. Swing has a single event thread (which is not the main thread and certainly not any other thread you choose to start) and you need to access Swing objects on that thread only - see http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

4. your threads aren't doing anything useful, are we supposed to guess what you want to happen?

Still, at least you're not extending JFrame so have a biscuit.

itchyscratchya at 2007-7-8 21:39:14 > top of Java-index,Desktop,Core GUI APIs...
# 3

Ok, I'm feeling generous, or insane... But if you take a look at the code below, you should be able to easily finish your own homework.

I would strongly suggest you check up everything that you don't understand using google, or the link that itchy provided.

package jdc;

import java.awt.BorderLayout;

import java.awt.Container;

import java.awt.Dimension;

import javax.swing.JFrame;

import javax.swing.JTextArea;

import javax.swing.SwingUtilities;

public class TestMutlitpleThreads {

private final JFrame frame = new JFrame("Result");

private final JTextArea textArea = new JTextArea();

public static void main(String[] args) {

TestMutlitpleThreads test = new TestMutlitpleThreads();

StringAppender appender1 = new StringAppender("a", 10, test);

StringAppender appender2 = new StringAppender("b", 10, test);

Thread t1 = new Thread(appender1, "Thread 1");

t1.start();

Thread t2 = new Thread(appender2, "Thread 2");

t2.start();

}

public TestMutlitpleThreads() {

this.textArea.setLineWrap(true);

this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.frame.setLocation(300, 300);

this.frame.setSize(new Dimension(100, 100));

this.frame.setVisible(true);

Container c = this.frame.getContentPane();

c.setLayout(new BorderLayout());

c.add(textArea, BorderLayout.CENTER);

}

public void appendString(final String toAppend) {

SwingUtilities.invokeLater(new Runnable() {

@SuppressWarnings("synthetic-access")

public void run() {

TestMutlitpleThreads.this.textArea.append(toAppend);

}

});

}

}

final class StringAppender implements Runnable {

private TestMutlitpleThreads test;

private int repeatCount;

private String toAppend;

public StringAppender(String str, int numberOfTimesToRepeat, TestMutlitpleThreads test) {

if (str == null || str.trim().length() == 0) {

throw new IllegalArgumentException("You must specify a String to display");

}

this.toAppend = str;

this.repeatCount= numberOfTimesToRepeat;

this.test = test;

}

public void run() {

for (int i = 0; i < this.repeatCount; ++i) {

try {

this.test.appendString(toAppend);

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

Hmmm, you may need the synchronised keyword on the appendString method. I'll leave that to someone with a better understanding to help out.

macrules2a at 2007-7-8 21:39:14 > top of Java-index,Desktop,Core GUI APIs...
# 4

solved.

I did it only with three classes...(Interface class as the main class)

here is the final code, thanks everyone

Why to complicate something that can be easy :) , that's my problem, i think to much when the answer is rigtht there lol

import java.awt.BorderLayout;

import java.awt.Container;

import javax.swing.JFrame;

import javax.swing.JTextArea;

public class ThreadTArea {

public static void main(String[] args) {

JFrame frame = new JFrame("Result");

JTextArea area = new JTextArea();

Container c = frame.getContentPane();

c.setLayout(new BorderLayout());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

c.add(area, BorderLayout.CENTER);

PrintChar2 letra_a = new PrintChar2('a', 100, area);

PrintChar2 letra_b = new PrintChar2('b', 100, area);

PrintNum2 numero = new PrintNum2(100, area);

frame.setLocation(300,300);

frame.setSize(300,450);

frame.setVisible(true);

letra_a.start();

numero.start();

letra_b.start();

}

}

class PrintChar2 extends Thread{

private char letra;

private int times;

JTextArea area;

public PrintChar2(char letra, int times, JTextArea area) {

this.letra = letra;

this.times = times;

this.area = area;

}

public void run(){

for(int i = 1; i <= times; i++){

area.append(Character.toString(letra)); // Print into the TextArea

area.setLineWrap(true);

try{

Thread.sleep(100);

}catch(InterruptedException e){ e.printStackTrace();}

}

}

}

class PrintNum2 extends Thread{

private int times;

JTextArea area;

public PrintNum2(int times, JTextArea area) {

this.times = times;

this.area = area;

}

public void run() {

for(int i = 1; i <= times; i++){

area.append(" "+Integer.toString(i));

area.setLineWrap(true);

try{

Thread.sleep(50);

}catch(InterruptedException e){ e.printStackTrace();}

}

}

}

Message was edited by:

Java__Estudante

Java__Estudantea at 2007-7-8 21:39:14 > top of Java-index,Desktop,Core GUI APIs...
# 5

You ignored itchy and scratchy

You ignored me.

Let's try it one more time.

Swing is NOT thread safe, you cannot update a swing component on a random thread that you created. If you scroll back up, you will see that I gave you the code to use, free of charge, at no cost to you other than to actually read it.

Don't bother coming back to us asking why your multi-threaded application is hanging.

It is bad practice to extend Thread, you should implement the runnable interface instead. I would also suggest that you use named threads, it will make your debugging much simpler (what am I thinking, you won't bother debugging, you will just dump your code here, and ask for it to be fixed).

macrules2a at 2007-7-8 21:39:14 > top of Java-index,Desktop,Core GUI APIs...