I am writing a simple chat program that shows different dialogs in different tabs of a JTabbedPane. I used a JTextArea to display the dialog. I added a JTextArea to the tab like this:
JTextArea referenceToAppend = new JTextArea();
JTabbedPane.addTab(title,new JPanel(new JScrollBar(referenceToAppend)));
I put the reference referenceToAppend into a List, then when I need to append text I do
the following :
List.get(index).append(textForAppend);
The problem is: my application becomes unresponsive. How can I solve this problem? I looked up a lot of information on forums and of course, Oracle. I can't find what I need. Maybe I was inattentive or may be I am not understanding something simple. I will be very grateful if someone could give a simple example or link to another forum where they discuss this problem.
Take a look at SwingWorker. It allows you to perform operations in a background thread an report information to the Event Dispatch Thread. If you need to block on a socket read, you need to do that on a background thread to keep the UI responsive.
Related
Is there a possibility to prevent a JOptionPane dialog from blocking the interaction with the rest of the program, especially child JFrames? In my GUI, I launch a JFrame and want a message dialog to pop up after the child is closed to remind the user of something, but they launch parallel and the reminder blocks the child frame from being used.
Like here:
popupObjMan newPopup1 = new popupObjMan(gatewayAbstract, gatewayAbstractID);
JOptionPane.showInternalMessageDialog(this, "REMINDER: DO REFRESH");
I've tried to set the popup always on top, but this doesn't quite do the job.
I have no problem with them launching parallel (I'd even prefer it), but I could not work my head around it yet.
I just started Java programming ,so sorry in case that'd be something obvious.
A JOptionPane normally need to be modal. It shows something important and waits till the user answers with whatever option you give him (e.g. ok-button, yes/no-buttons, ...)
But there are several ways to reach your target.
(a)
Normally a JOptionPane creates a modal window.
You need a modeless window which does not block other windows.
https://docs.oracle.com/javase/tutorial/uiswing/misc/modality.html
(b)
You can start different threads to work for your different windows. They can have windows which are shown whenever the responsible thread commands them to. This is a bit difficult and can lead to memory-troubles.
(c)
You can write your own message-panels (e.g. notificaton) which are shown when and how long you like.
Bigger projects use different of these ways to achieve their goals.
A JOptionPane is a component, just like a JPanel. As a component it can be added to any other panel.
The JOptionPane API provides static methods to create a show the JOptionPane on a modal JDialog by default. You can't change this behaviour.
However, you can manually add the JOptionPane to a non-modal JDialog that you create. This is extra work as you now need to handle the closing of the dialog and processing the clicked button.
If you really want to do this then read the JOptionPane API. There is a section on Direct Use which demonstrates the basic code needed to add the JOptionPane to a JDialog.
I have a fairly simple Java Application I created with JFrames. There is more than one JFrame in my program. I have a menu launching at the beginning of the program. After going through the menu, I have the menu JFrame disposed.
The main JFrame has a menu button that should launch the exact same menu at a later time. However, when you launch the menu from inside of the ActionListener (when you press the menu button), the JFrame doesn't launch properly. None of the components show up and colors are off.
However, when the menu is launched from outside of the ActionListener, the JFrame shows up perfectly. I have tried multiple methods to fix this, but none of them have worked.
My full program code is available by clicking here.
The main class is "LetsMultiply5.java". This class also sets up the ActionListener.
The JFrame causing the problem is "MenuWindow.java".
"LetsMultiply5.java" calls the "Booter.java" class, which then calls the "MenuWindow.java".
"MainWindow.java" is the JFrame that has the "Menu" button.
For proof, "SpeedModer.java" calls the menu window after it has been disposed, and works.
================================EDIT================================
Also, I'd like to let you know that I realize my code is a little bit messy. I am not sure how else to write the code for this program.
I am forced to use Thread.sleep(x); because the Swing timers aren't what I am looking for. The Swing timers activate an ActionListener when the timer goes off. I need a system that will wait a second before continuing on with the code.
I realize that the while (repeater==0) loop with ActionListeners inside of it seems crazy, but that was the only way I could get it to work. If I put a single ActionListener and just had the while loop do no code inside of it, nothing happens when I press the button.
I would, as MadProgrammer mentioned:
Advice: Scrap your current approach and start again.
However, the way that I have my program currently coded is the only way that I know how to get what I need to do done. I read the tutorials, but still don't know how to improve the code in the way that you told me.
I thank everyone for trying to tell me to improve my bad "Java grammar", but as far as I am concerned, I am not going to continue this program for the next 20 years and make my millions off of it.
I have looked at the Swing timers before and I understand the whole new Timer(speed, this); concept, but I don't understand how this would make my code any better.
If anyone would like to show me how to fix my ActionListeners or Thread.sleep(x); lines, please tell me. Thank you.
You're blocking the Event Dispatching Thread with Thread.sleep(3000); - Don't do this, it will prevent the UI from been painted
See Concurrency in Swing for more details about the problem and How to use Swing Timers for a possible solution
You may also want to consider having a look at The Use of Multiple JFrames, Good/Bad Practice? and consider using CardLayout or JTabbedPane
If you need to block the user temporarily (to display a error message or gather important details), consider using a modal JDialog. See How to Make Dialogs for more details
I have a JFrame with three text fields, two combo boxes and two Jbuttons. The coding is written in Java. One button is to start the execution of the automation script and another button is to abort the execution.
But after clicking on Start Execution button, I am unable to click on the second button and unable to edit other fields like text fields, combo boxes in the JFrame also.
As this is my project related I cannot post my code here. I apologise for that. I hope you can understand the logic or concept behind my problem. I have done a lot of search in internet but still no progress.
Please help me with this. I am using action listener behind the two Jbuttons.
The Event Dispaching Thread (EDT) should only and only do graphic related work. Any other work should be done in another thread (see SwingWorker).
Every event generated by swing, will run in the EDT, this includes actionPerformed()
That is happen because of the code implement you in the first button is continuously running , use java thread to do that stuff in the first button code. then that will be works fine.
I am writing a socket programming. It has GUI for server and client. In the server GUI there is a textfield which shows the word requested by user.
But I am having problem in showing the word.
I have tried
txtWord.setText(sentword);
It is not showing the word in the textfield. But when I write this
txtWord.setText(sentword);
JOptionPane.showMessageDialog(null, "the requesed word is: "+sentword);
then it shows the word in textfield and also shows it in the messagebox.
I have tried repaint() but it dint work.
Please suggest me some solution as soon as possible
as #Binyamin Sharet correctly commented, you have a Concurrency in Swing issue.
your Swing GUI doesn't care about long and hard tasks you're running in the background
even JTextField#setText() is declared as thread safe, output from Socket (i.e.) by default never notified Event Dispatch Thread
correct way could be to use a SwingWorker that has been created specifically to run long and hard tasks background to the Swing GUI and output to the GUI on event thread or EDT
or even easier is to use a Runnable in a Thread but making sure that all output to the Swing GUI is queued on the Swing event thread by placing it in a Runnable and calling it with invokeLater()
A dirty hack is to wrap code lines like so:
txtWord.setText(sentword);
JOptionPane.showMessageDialog(null, "the requesed word is: "+sentword);
into invokeLater(), but in this case your GUI will be unresponsive to Mouse or Keyboard events until Socket (in your case) ended
txtWord.requestFocus();
textField does not show up until the window is over the textField and back or it gains focus, until Clicking on it. So... just request focus.
Also if check the text size if you had set while creation.Sometimes text not displayed if there is mismatch in size
eg: txtWord.setSize(200, 24);
In all my time so far working with Java and its Swing GUI framework, I've never quite figured out (or even attempted to try) how to make the interface animate components.
Say I wanted the screen to slide left into the next screen or have a JLabel "fly" to a new location. Perhaps you want a menu to smoothly open in an animated fashion. How does this work?
Do you have to use SwingWorker? Even if that's the case... how can you control the painting of components if the layout manager is already doing that?
Have a look at the book Filthy Rich Clients, you will find some really good answers there.
I think that there no reason for use SwingWorker, SwingWorker is designated for running long Backgroung Task(s) on output would be on Event dispatch Thread,
For animations in Swing is there javax.swing.Timer, examples here
Take a look at Trident library. You can use it to interpolate various properties in your class.