I don't want to get called events during the render or update step, but before them. I also don't want to only redraw when an event has occurred, but as soon as possible, so I need a loop in my program.
poll events - call functions to associated listeners
update - may be merged with draw
draw
How can I accomplish this?
I don't really understand your problem, but if you want to draw continuously, then you should make a main loop. This thing cannot be made with swing components, but only if you design an event or use a predefined event. In that event, redraw the whole canvas, using validate() when you add a new component and repaint() or paint() when you just want to update the image.
If you don't want to render continuously then just render when "something" happens, such as when an event triggers.
Related
I am making something that resembles a subtitle player that will go over a video.
I would like to make the background transparent so that the box that the text is in will not interfere with the movie/TV show playing behind it. I have tried 2 ways to do this and each way results in the same problem. The text does not disappear when the next sentence appears. If the background is a color (Eg: Color.red), then this works fine. After a certain time, I call text.setText("next sentence"), but this does not work with a transparent background. The relevant code is as follows. text is a JTextField
I should mention the video is not in this program. This program is ONLY subtitles.
First way:
text.setBackground(new Color(0,0,0,0));
Second way: (using a transparent image)
Graphics c = myPicture.getGraphics();
text.paintAll(c);
I update the text like this.
Thread.sleep(Graphix.subtitles.get(counter).getStart());
text.setText(Graphix.subtitles.get(counter).getText());
This also makes it overlap.
text.setForeground(Color.blue);
text.setBackground(new Color(0,0,0,0));
text.setOpaque(false);
The relevant code from Main is as follows.
final JFrame JFwindow = new JFrame("Subtitles");
JFwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JFwindow.getContentPane().add(new Subtitles());
JFwindow.setSize(1300, 150);
JFwindow.setUndecorated(true);
JFwindow.setBackground(new Color(0,0,0,0f));
JFwindow.pack();
JFwindow.setVisible(true);
Transparency is achieved by calling JPanel#setOpaque and passing it false.
You should NEVER be calling getGraphics. getGraphics and return null and is, at best, only as snap shot. Once the RepaintManager starts a new paint cycle, the results of painting to it will be overridden.
Using a tarnsparent color will only confuse the RepaintManager as it won't know that it needs to paint under the component
Sleeping within the Event Dispatching Thread (EDT) will stop Swing from performing any updates (as well as process any events). Instead I'd recommend using a javax.swing.Timer. See Concurrency in Swing for more details.
If you're using the VLC bindings, then it can't be achieved
Don't forget to make all the parent containers that the sub titles are contained in transparent as well
The list of SWT constants in the SWT API supplies two very similar event types (for use with various event listeners):
Show
Paint
What's the difference? Wouldn't all 'Show' events require a 'Paint' event and all 'Paint' events require a 'Show' event?
According to this page:
Show:
The widget is becoming visible
Paint:
A control was asked to draw
So the main difference is the following:
SWT.Show is dispatched once the Widget becomes visible. SWT.Paint is called whenever the Widget changes state, i.e. when it has to be redrawn. For example when it is resized or the content changes.
To answer your last question. Every Show event is coupled with a Paint, but not every Paint is coupled with a Show.
To see how it works just attach two Listeners to a Shell that just print out "Show" or "Paint" and see when they are fired.
How to use paint() such that when repaint() is called the previously drawn object should not get deleted when drawing the new object. That is the drawing area must get UPDATED only and not REDRAWN.
In my code when one of many button is clicked, some aplhabet get displayed. I want to have functionality such that when other buttons are clicked the previously drawn alhabets must be present.Take is as if a string of alphabets getting created as the buttons are clicked.
Im using Java Swing for coding.
Some piece of my code:
if(source == btnAlpha[i] )
bollyDraw.repaint(); //bollydraw is an object of a JPanel extended class having implemented the paintComponent(Graphics g) method
In the paint() method:
if (word[i] == key) {
g.drawChars(word, i, 1, x, y);
}
In a project I worked on I used a List to store the objects that were to be drawn as a member of a class. Then as the user interacted with my UI I added/removed items from this list. The JPanel that rendered the items painted the items that were in this list. It's helps separate the UI logic from the paint logic as you can determine what goes into the paint list when an event is fired rather than in the paint method ( which should be as clean as possible ). However this will force you to repaint everything on every paint call.
In conjunction with this Kim's RepaintManager is a great way to limit what gets repainted. It is region based so there is some complexity in determining what region of the screen has changed. If you have the time it is better to use something like this otherwise it could be difficult to add this functionality down the road.
Your app must be prepared to re-paint anything it has painted. From your description, I'm afraid that means you have to keep track of everything you've painted.
The Swing behavior is partially dictated by the underlying window manager and graphical system, which at any time may chose to paint over an area where your application is present. You can override update() to control repaints initiated by your own app, and might be able to improve performance by implementing your own RepaintManager.
This tutorial explains Swing painting in more detail: http://java.sun.com/products/jfc/tsc/articles/painting/
Custom Painting Approaches shows a couple of ways to do this depending on your exact requirement.
I've customized a JPanel that displays a large, complicated diagram. Depending on the size of the data, it can take a few minutes to render in paintComponent(). I'm looking for a strategy to:
draw the component without tying up the event dispatch thread.
draw something in the JPanel to let the user know the image is being rendered.
periodically update another container's label to show the progress
I've researched this a bit, and I'm wondering if the right strategy is to use a SwingWorker to create a background thread and draw to a BufferedImage. Timers would handle the status updates. Class member variables would hold the status.
Am I on the right track?
You need to look into using a SwingWorker. You should do the rendering of the diagram in a separate thread. The SwingWorker will help accomplish that.
To get started with multi-threading in concurrency, sun has a great tutorial that should prove very helpful.
Use background image which is updated by special working thread. Then in JPanel's paintComponent() method just paint this image. The strategy is called double-buffering. You have background and foreground image. If separate thread finish the painting of data then set this image as foreground and foreground load as background. Invalidate JPanel and continue painting on back image if necessary.
I have a little java applet where I create 2 threads, one thread repaints and the other moves an image from a point to where the user clicks. The problem is that when I call the move function it loops until the image is where the user clicks but it wont repaint until I break out of the loop even though the thread doing the moving and the thread doing the painting are separate.
shortened version of key points:
my program is an applet using the paint() method
I have 2 threads one moves an image and the other paints that image
when I am moving the image it is in a while loop
the painting thread is still calling repaint() but that is as far as the call goes, it never repaints
thank you for your time.
It might be useful to read an introduction of the painting system of the AWT framework of Java. Take a look for example at th one from Sun: http://java.sun.com/products/jfc/tsc/articles/painting/index.html
In your case you don't need 2 threads. The thread in charge of repainting your applet is created by AWT. It is called the event dispatching thread or EDT. So you just need to change the position of your image and on each change call the repaint method on your applet.