GUI from separate thread - java

Trying to create two independent forma that could run code in separate threads. Code below creates two forms , but if I press button on one of them I can't do the same with another. It simply not executes code. How to make two simple forms that could run non blocking each other?
public class MnemonicEx1 extends JFrame
{
public JeasiHandler jh = null;
private Log log = Log.getLog();
public MnemonicEx1()
{
initUI();
}
private void initUI()
{
JButton btnAuth = new JButton("1");
btnAuth.addActionListener(new ActionListener()
{
// #Override
public void actionPerformed(ActionEvent e)
{
System.out.println("starting");
for (int i = 0; i < 1000; i++)
{
try
{
Thread.sleep(100);
System.out.println(Integer.toString(i));
} catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
System.out.println("finishing");
}
});
btnAuth.setMnemonic(KeyEvent.VK_B);
//createLayout(btnAuth);
createLayout(btnAuth);
setTitle("****");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void createLayout(JComponent authButn)
{
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
int i = 0;
gl.setHorizontalGroup(
gl.createSequentialGroup()
.addComponent(authButn)
);
gl.setVerticalGroup(gl.createParallelGroup()
.addComponent(authButn)
);
pack();
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
});
EventQueue.invokeLater(new Runnable()
{
public void run()
{
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
});
}
}
UPD
Changed main() by creating separate threads , but got the same result
public static void main(String[] args)
{
new Thread (new Runnable()
{
public void run()
{
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
}).start();
new Thread(new Runnable()
{
public void run()
{
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
}).start();
}

#Nadir is more or less right.
You are launching both windows in the same thread represented by EventQueue.
I think swing programmers prefer to use SwingUtilities for opening new frame applications but you can achieve your goal changing your method actionPerformed
// #Override
public void actionPerformed(ActionEvent e) {
new Thread() {
#Override
public void run() {
System.out.println("starting");
for (int i = 0; i < 1000; i++)
{
try
{
Thread.sleep(100);
System.out.println(Integer.toString(i));
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("finishing");
}
}.start();
That way you'll have two different threads. In your original version you only had one thread.
UPDATED: Change also your main method
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
});
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
MnemonicEx1 ex = new MnemonicEx1();
ex.setVisible(true);
}
});
}

Related

Display multiple JFrame in a loop by click the button

I want to display several JFrame with the delay of several seconds in a loop by clicking on a button. Frames come but they are quite white, have the title but they don't have body (Buttons are not visible). Without loop hence once calling a JFrame, No problem. What should I do?
Do you have another idea?
Main class:
public class Game3 {
game3.NewJFrame2 start_frame = new game3.NewJFrame2();
public Game3() throws InterruptedException {
this.start_frame.setSize(500,500);
start_frame.setVisible(true);
final JButton enter = new JButton("Enter");
enter.setBounds(10,10,50,50);
start_frame.add(enter);
enter.setVisible(true);
enter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
start_frame.dispose();
try {
new Play();
} catch (InterruptedException ex) {
Logger.getLogger(Game3.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public static void main(String[] args) throws InterruptedException {
new Game3();
}
}
and Play class:
public class Play {
game3.NewJFrame2 start_frame1 = new game3.NewJFrame2();
public Play() throws InterruptedException {
this.select_rnd_word();
}
public static void select_rnd_word() throws InterruptedException {
for (int i = 0; i < 5; i++) {
game3.NewJFrame2 frame = new game3.NewJFrame2();
frame.setSize(200, 200);
JButton b = new JButton("A");
b.setBounds(0, 0, 30, 30);
frame.add(b);
b.setVisible(true);
frame.setVisible(true);
Thread.sleep(2000);
frame.dispose();
}
}
}
Follow code has this problem too:
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 3; i++) {
new Game3();
}
}
One idea is moving 'new Play() ' to out of ActionListener.
enter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
start_frame.dispose();
}
});
Thread.sleep(10000);
start_frame.dispose();
new Play();
By making a new thread, this problem is solved.
enter.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
start_frame.dispose();
new Thread() {
#Override
public void run() {
try {
new Play();
} catch (InterruptedException ex) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
}
}
}.start();
}
});
for more information: Event Dispatch Thread

How to start and stop a threads in netbeans from a jButton click

I write Java desktop app to fetch and post some data from my online rails backend app. The App have to call a get request every 5 second to update the relay state(example Arduino). here is my code:
public class GUI extends javax.swing.JFrame {
private Serial serial = null;
private Service service = null;
private volatile boolean connected = false;
private Thread updateThread;
public GUI() {
initComponents();
init_serial();
service = new Service();
updateThread = new Thread() {
public void run() {
while (connected) {
updateJob();
}
}
};
updateThread.start();
}
private void init_serial() {
serial = new Serial();
serial.searchForPorts();
serial.connect();
serial.initIOStream();
serial.initListener();
}
private void updateJob() {
ActionListener actListner = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
updateState();
}
};
Timer timer = new Timer(5000, actListner);
timer.start();
}
private void updateState() {
String portState = service.get_port_state();
serial.write(portState);
System.out.println(portState);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
connected = true;
logger.setText(null);
logger.setText("connected");
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
logger.setText(null);
logger.setText("disconnected");
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
}
});
}
}
but it didn't work as expected, my question is how can i fix my code and how to put the thread correctly?
You can use a Thread object in class's member and you can start and stop in button click action events. Here is the sample to start/stop thread.
public class GUI extends javax.swing.JFrame {
Thread updateThread = null;
public GUI() {
JButton btnStart = new JButton("Start");
JButton btnStop = new JButton("Stop");
JPanel jPanel = new JPanel();
jPanel.setBounds(0, 0, 100, 200);
jPanel.add(btnStart);
jPanel.add(btnStop);
add(jPanel);
btnStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
updateThread = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
System.out.println("Work updated");
try {
Thread.sleep(1000);//Time to wait for next routine
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
updateThread.start();
}
});
btnStop.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
updateThread.stop();
}
});
setVisible(true);
setBounds(0, 0, 100, 200);
}
public static void main(String[] args) {
new GUI();
}
}
You can possibly use thread.join();

Multi-Threading in J2ME and LWUIT

I want to make dialog box to be shown while I load some data from the web service
I'm using the LWUIT,
The following is the code
public class LoaderAnimation extends Container implements Runnable {
private Thread t;
private boolean running = false;
public LoaderAnimation() {
}
public void start() {
running = true;
t = new Thread(this);
t.start();
}
public void run() {
while (running) {
// do something
t.sleep(150);
}
}
public void stop() {
running = false;
}
}
what happens now that it runs but the code of calling the web service has stop working
that is the calling of it
public static void showLoaderScreen ()
{
dialog = new Dialog();
dialog.setLayout(new BorderLayout());
canvas = new LoaderAnimation();
dialog.addComponent(BorderLayout.CENTER , canvas);
canvas.start();
dialog.show();
}
public static void dismissLoaderScreen ()
{
canvas.stop();
dialog.dispose();
}
try this piece of code.
private void startLoader() {
Dialog d = new Dialog();
d.getStyle().setBgColor(0xffffff);
d.getStyle().setBgTransparency(255);
d.show(100, 250, 90, 150, true, false);
d.setAutoDispose(true);
try {
Thread.sleep(30);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
d.dispose();
new Timer().schedule(new TimerTask() {
public void run() {
new Loader().start();
}
}, 30);
}
Loader class we can write parsing stuff or web service handling etc.
class Loader extends Thread
{ public void run() {
try {
ServiceTypesScreen st = new ServiceTypesScreen();
st.init();
} catch (Exception e) {
e.printStackTrace();
}
}
}

JLabel paints dots

import java.awt.Graphics;
import javax.swing.*;
public class Demo
{
JFrame jf;
JLabel[] labels;
JPanel panel;
public Demo()
{
jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
labels = new JLabel[10];
Box vbox = Box.createVerticalBox();
for (int i = 0; i < 10; i++)
{
labels[i] = new JLabel();
vbox.add(labels[i]);
}
panel = new JPanel();
panel.add(vbox);
jf.add(panel);
jf.setSize(300, 250);
jf.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new DemoRunnable());
}
public void updateState()
{
for (JLabel l : labels)
{
if (Math.random() > 0.5)
l.setText("777777777777777777777777777777777777");
else
l.setText("10000000000000000000000000000000000000");
}
}
}
class DemoRunnable implements Runnable
{
Demo demo;
DemoRunnable()
{
this.demo = new Demo();
}
#Override
public void run()
{
Thread t = new Thread(new Runnable()
{
#Override
public void run()
{
while (true)
{
try
{
Thread.sleep(0);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
demo.updateState();
}
}
});
t.start();
}
}
I see such effect when this program is perfomed. Is it possible to eliminate it(zeroes must be instead dots)?
Instead of setSize() use pack() to take advantage of the component's carefully calculated preferred size. You'll also need to initialize your label:
labels[i] = new JLabel("10000000000000000000000000000000000000");
Also consider javax.swing.Timer instead of a separate thread.
Addendum: Conveniently, each Swing Timer shares a common background thread, and the actionPerformed() is called on the event dispatch thread. An alternative is SwingWorker, illustrated here.
my code in answer is example only,
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.*;
public class Demo {
private JFrame jf;
private JLabel[] labels;
private JPanel panel;
public Demo() {
labels = new JLabel[10];
Box vbox = Box.createVerticalBox();
for (int i = 0; i < 10; i++) {
labels[i] = new JLabel();
labels[i].setText("10000000000000000000000000000000000000");
vbox.add(labels[i]);
}
panel = new JPanel();
panel.setLayout(new GridLayout());
panel.add(vbox);
jf = new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(panel);
jf.pack();
jf.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new DemoRunnable());
}
public void updateState() {
for (final JLabel l : labels) {
if (Math.random() > 0.5) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
l.setText("777777777777777777777777777777777777");
}
});
} else {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
l.setText("10000000000000000000000000000000000000");
}
});
}
}
}
}
class DemoRunnable implements Runnable {
private Demo demo;
DemoRunnable() {
this.demo = new Demo();
}
#Override
public void run() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
demo.updateState();
}
}
});
t.start();
}
}

Load function in a thread

How can i use the callme(input); to get launched with a new thread?
/* We send username and password for register and load a heavy load */
public class button3 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String input = output.getText();
if (input.length()<=0)
{
JOptionPane.showMessageDialog(null, "Empty....");
} else {
callme(input);
}
}
}
public static String callme() { //heavy loads... starts, which freezed the button
return "Did you called me?";
}
Try 1: but getting failed (output1 does not get the returned text results):
/* We send username and password for register and nat mapping */
public class button3 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String input = output.getText();
if (input.length()<=0)
{
JOptionPane.showMessageDialog(null, "Empty....");
} else {
new Thread(new Runnable() {
public void run() {
try {
output1.setText( callme(output.getText()) );
} catch(Exception t) {
}
}
}).start();
}
}
}
Try 2: Also tried this, did not returns output1 = callme();
new Thread(new Runnable() {
public void run() {
final String result = callme(output.getText());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
output1.setText( result );
} catch(Exception t) {
}
}
});
}
}).start();
new Thread(new Runnable() {
public void run() {
try {
callme(input);
} catch(Exception t) {
// appropriate error reporting here
}
}
}).start();
Note that input must be declared as final.
Also, consider using invokeLater(Runnable) from Swing Utilities
Try this:
public class button3 implements ActionListener {
public void actionPerformed(ActionEvent e) {
final String input = output.getText();
if ( input.length() <= 0 ) {
JOptionPane.showMessageDialog(null, "Empty....");
}
else {
Thread t = new Thread(new Runnable() {
public void run() {
callme(input);
}
});
t.start();
}
}
public static String callme(String input) {}
}
If you modify swing controls inside your method you should use
new Thread(new Runnable() {
#Override
public void run() {
final String result = callme(input);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
output1.setText( result );
} catch(Exception t) {
}
}
});
}
}).start();
If you need the return value, you should really be using a Callable with an ExecutorService which will give you back a Future that you can use the retrieve the value later on.
See:
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

Categories