this is my code for updating jslider
try{
name=(String) jList1.getSelectedValue();
CanvasVideoSurface videoSurface = mediaPlayerFactory.newVideoSurface(canvas1);
mediaPlayer.setVideoSurface(videoSurface);
mediaPlayer.setAdjustVideo(true);
mediaPlayer.playMedia(name+".mp4");
mediaPlayer.setVolume(jSlider1.getMinimum());
mediaPlayer.parseMedia();
time = (int)(mediaPlayer.getMediaMeta().getLength()/1000);
jSlider2.setMaximum(time);
while(jSlider2.getValue()<jSlider2.getMaximum())
{
jSlider2.setValue((int) this.mediaPlayer.getTime()/1000);
}
}
catch(Exception e)
{
e.printStackTrace();
}
and for changed state of slider this is the code
private void jSlider2StateChanged(javax.swing.event.ChangeEvent evt)
{
mediaPlayer.setTime((long) this.jSlider2.getValue());
}
but it doesn't change position of nob,infact it keeps playing from start again anda again.i think reason is that setTime() function keeps updating to 0 before jslider can take new value.is there any solution??maybe using threads??
thanks!!
With this code:
while(jSlider2.getValue() < jSlider2.getMaximum())
{
jSlider2.setValue((int) this.mediaPlayer.getTime()/1000);
}
You're calling a long-running loop on the Swing Event Dispatch Thread or EDT, and this will freeze your GUI preventing all painting. Consider running your background process in a SwingWorker's doInBackground method and then updating the GUI via the SwingWorker's publish/process method pair. Also, if you're going to poll the media player, consider putting in a Thread.sleep(/* some number */) inside the polling loop since it doesn't make sense to poll almost continuously.
For more on this, please have a look at Concurrency in Swing.
Related
I have a JPanel with a start button when that button is pressed it calls through the mainFrame the start() function in the controller
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource().equals(start)) {
System.out.println("hi");
try {
f.c.start();
} catch (KludgeException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
the start() function calls the askQuesions() function which loops over questions creates a question panel for them and stores the answers.
public void start() throws KludgeException{
System.out.println("start");
askQuestions();
ConductInference();
}
public void askQuestions() throws KludgeException {
QuestionsPanel qp = new QuestionsPanel(main);
for(data.containers.Question q : kludge.getQuestions()){
qp.addQuestion(q.getQuestion(), q.getType());
main.setPanel(qp);
synchronized(this){
while(!next){
try {
wait();
kludge.setSystemValue(q.getValueName(), v);
//System.out.println("waitOver");
} catch (InterruptedException e) {}
}
}
next = false;
//System.out.println("next question");
}
System.out.println("questions over;");
}
this is a function in the mainFrame which is a JFrame it set the necessary panel.
public void setPanel(JPanel p){
main.getContentPane().removeAll();
main.getContentPane().add(p);
main.validate();
System.out.println("all removed, added and validated");
}
My problem is this... the program gets stuck on the startPanel when the stat button is pressed it freezes. If i skip the whole startPanel and tell it to go straight to the questions it works fine. but still i dont want it to go straight to the questions. For some reason it switches between the question panels fine but not between the startPanel and questionPanels..
You've got a concurrency issue and are calling long-running code on the Swing event thread, an issue that will prevent this thread from doing its important jobs such as painting the GUI and interacting with the user. The solution is to do the long-running code in a background thread such as provided by a SwingWorker. That and read up on Swing concurrency: Lesson: Concurrency in Swing
OK, I'm now sure that my original recommendation -- to use a background thread -- is wrong, that instead you've over-complicated your code with the while loop, the synchronized block and the wait. Yes these are blocking the event thread, and yes, this is hamstringing your application, making it freeze and become totally unresponsive, but the solution is not to use a background thread but instead you will want to get rid of the while (true) loop, the synchronized block and the wait() call and in their place use event listeners and call back methods. The exact wiring of this will depend on code that we're not yet privy to, but that is the solution to this problem. For instance, the question panel could notify a control class that a question has been answered, to change the state of the model so that it moves on to the next question. The model then changes, and this can notify the view that it must update itself and now display this next question.
Side notes:
you're better off using a CardLayout to swap views then to directly swap them. The tutorial can be found here: CardLayout tutorial.
And regarding: main.setPanel(qp);
You appear to be re-adding the QuestionPanel to the main within the for loop. If so, you only need to and only should add it once.
previous the same thread was running in java eclipse luna, but interruptions appeared I changed to Java EE IDE, the same thread which previous ran in luna now is not running in Java EE IDE, here it is
public void clockTime(){
Thread clock=new Thread(){
public void run(){
try {
for(;;){
Calendar cald=new GregorianCalendar();
day=cald.get(Calendar.DAY_OF_MONTH);
month=cald.get(Calendar.MONTH);
year=cald.get(Calendar.YEAR);
seconds=cald.get(Calendar.SECOND);
minutes=cald.get(Calendar.MINUTE);
hours=cald.get(Calendar.HOUR);
lblClock.setText("<html>"+hours+":"+minutes+":"+seconds+"<br>"+day+"/"+month+"/"+year+"</html>");
sleep(1000);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
clock.start();
}
please may any one help me??.
calling the method to constructor I have already done not seen here, but if I remove the thread the method is executed since it displays the time and date as required but not changing due to absence of loop and forever loop.
If this is a Swing application then:
Make sure that you start the application on the Swing event thread, by calling SwingUtilities.invokeLater(Runnable); where your GUI is started up in that Runnable
You're making a key Swing call off of the Swing event thread (EDT) in the code above, namely the lblClock.setText(...) call. This also should be called only on the Swing event thread, in the same way as point above.
Or you could use a SwingWorker and then make the setText call in the publish / process method pair.
Or (and this is what I would do), chuck all that code above and use a Swing Timer. It's much simpler, and you wouldn't have to worry about on/off Swing event since all calls would be on the event thread.
If you go the Swing Timer route, you'd construct pass in its constructor an int equal to the desired delay, here 1000 msecs. The Timer's ActionListener is called repeatedly, and in that you'd get your time values, and then use it to create a String that you pass to your JLabel.
For example, something roughly like:
int timerDelay = 1000;
Timer timer = new Timer(timerDelay, new ActionListener() {
public void actionPerformed(ActionEvent e) {
// calculations to get time Strings
String text = ..... // use calculations above
lblClock.setText(text);
}
});
timer.start();
Note that code has not been tested
I try to move a JLabel from Position A to Position B sequential in same X and Y Steps.. The Method works correctly, but doesnt't update my gui..
I Show you my code in the following:
When I don't call the .join() Method, the code works, but don't wait with execution on my another Thread... I need that this function don't call when it actually runs.. Can anybody help me?
Thread MoveThread = new Thread( new Runnable()
{
#Override
public void run()
{
for (int i = 0; i<Const.SteinVerschiebenSchritte; i++)
{
try
{
p_lblToMove.setLocation(p_lblToMove.getLocation().x + x_schritt, p_lblToMove.getLocation().y + y_schritt);
System.out.println("SetLoc");
Thread.sleep(10);
}
catch (InterruptedException ex)
{
StatusLog("InterruptedException");
}
}
System.out.println("invokeLater");
p_lblToMove.setLocation(p_lblToMove.getLocation().x + x_offset, p_lblToMove.getLocation().y + y_offset);
}
});
MoveThread.start();
try {
System.out.println("BeforeJoin");
MoveThread.join();
System.out.println("AfterJoin");
System.out.println("------------------");
} catch (InterruptedException ex) {
Logger.getLogger(Spielfeld.class.getName()).log(Level.SEVERE, null, ex);
}
Swing is a single thread environment, meaning that you should not performing any long running or blocking operations from within the context of the Event Dispatching Thread, equally, you Swing is also not thread safe, meaning that you should only update the UI from within the context of the Event Dispatching Thread.
See Concurrency in Swing for more details.
Depending on what you're trying to achieve you could use a SwingWorker, see Worker Threads and SwingWorker for more details, or a Swing Timer, see How to use Swing Timers for more details
Also remember, Swing relies on layout managers to do much of the core work when it comes to positioning and sizing components, you might find that you are fighting the layout mangers which could cause unexpected results
Of course, you could always have a look at The Universal Tween Engine and Sliding layout or Java: Moving jLabel twice using Timer
I have problem while working with JFrame, which get freezes while
running the code continuously. Below is my code:
On clicking on btnRun, I called the function MainLoop():
ActionListener btnRun_Click = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
MainLoop();
}
};
Implementation of MainLoop():
void MainLoop()
{
Hopper = new CHopper(this);
System.out.println(Hopper);
btnRun.setEnabled(false);
textBox1.setText("");
Hopper.getM_cmd().ComPort = helpers.Global.ComPort;
Hopper.getM_cmd().SSPAddress = helpers.Global.SSPAddress;
Hopper.getM_cmd().Timeout = 2000;
Hopper.getM_cmd().RetryLevel = 3;
System.out.println("In MainLoop: " + Hopper);
// First connect to the validator
if (ConnectToValidator(10, 3))
{
btnHalt.setEnabled(true);
Running = true;
textBox1.append("\r\nPoll Loop\r\n"
+ "*********************************\r\n");
}
// This loop won't run until the validator is connected
while (Running)
{
// poll the validator
if (!Hopper.DoPoll(textBox1))
{
// If the poll fails, try to reconnect
textBox1.append("Attempting to reconnect...\r\n");
if (!ConnectToValidator(10, 3))
{
// If it fails after 5 attempts, exit the loop
Running = false;
}
}
// tick the timer
// timer1.start();
// update form
UpdateUI();
// setup dynamic elements of win form once
if (!bFormSetup)
{
SetupFormLayout();
bFormSetup = true;
}
}
//close com port
Hopper.getM_eSSP().CloseComPort();
btnRun.setEnabled(true);
btnHalt.setEnabled(false);
}
In the MainLoop() function, the while loop is running continuesly until the Running is true problem is that if i want to stop that while loop i have to set Running to false which is done at another button btnHalt:
ActionListener btnHalt_Click = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textBox1.append("Poll loop stopped\r\n");
System.out.println("Hoper Stopped");
Running = false;
}
};
but btnHalt is not responding, whole frame is get freeze, also not
showing any log in the textarea.
Swing is a single thread framework. That is, there is a single thread responsible for dispatching all the events to all the components, including repaint requests.
Any action which stops/blocks this thread will cause your UI to "hang".
The first rule of Swing, NEVER run any blocking or time consuming tasks on the Event Dispatching Thread, instead, you should use a background thread.
This runs you smack into the second rule of Swing. Never create, modify or interact with any UI component outside of the EDT.
There are a number of ways you can fix this. You could use SwingUtilities.invokeLater or a SwingWorker.
SwingWorker is generally easier, as it provides a number of simple to use methods that automatically re-sync there calls to the EDT.
Take a read through Concurrency in Swing
Updated
Just so you understand ;)
Your MainLoop method should not be executed within the context of the EDT, this is very bad.
Also, you should not be interacting with any UI component from any thread other the then the EDT.
I currently have a JFrame where on it's content pane I draw images on from a game loop at 60 frames per second. This works fine, but at the right side, I now have more Swing elements on which I want to display some info on when selecting certain parts of the content pane. That part is a static GUI and does not make use of a game loop.
I'm updating it this way:
public class InfoPanel extends JPanel implements Runnable {
private String titelType = "type: ";
private String type;
private JLabel typeLabel;
private ImageIcon icon;
public void update() {
if (this.icon != null)
this.typeLabel.setIcon(this.icon);
if(this.type != null || this.type != "")
this.typeLabel.setText(this.titelType + this.type);
else
this.typeLabel.setText("");
}
public void run() {
try {
Thread.sleep(150);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.update();
}
(this method is only called when the player has actually moved, so it's just called once - not 60 times per second)
I noticed that, when calling this update()-method from the game loop, I get flickering effects. I assume this is because updating the UI takes some time, so I decided to put it in a new thread. This reduced the flickering, but didn't solve it.
Next, I decided to give the new thread low priority as the part of the screen which is redrawed 60 times a second is far more important. This reduced the flickering again, but it still happened. Then, I decided to use Thread.sleep(150); in the new thread before calling the update()-method, which solved the flickering effect on my system completely.
However, when running it on other systems, it still happens. Not as often as before (maybe one time per 20 seconds), but it's still pretty annoying. Apparantly, just updating the UI in another thread doesn't solve the problem.
Any ideas how to completely eleminate the flickering?
Call the update() in SwingUtilities.invokeAndWait() which stops the thread and updates UI in EDT.
Problem is that you are use Thread.sleep(int), that stop and freeze GUI during EventDispatchTread more in the Concurency in Swing, example demonstrating freeze GUI by using Thread.sleep(int), example for Runnable#Thread
If you want to delay whatever in Swing then the best way is implements javax.swing.Timer