I am unable to understand why the println() statement inside paint() is executing twice.This is the code-
import java.awt.*;
import java.applet.*;
public class FirstApplet extends Applet
{
public void init()
{
System.out.println(getBackground());
}
public void paint(Graphics g)
{
setBackground(Color.CYAN);
setForeground(Color.RED);
g.drawString("This is my first Applet",250,250);
System.out.println(getBackground());
}
}
OUTPUT:
java.awt.Color[r=255,g=255,b=255]
java.awt.Color[r=0,g=255,b=255]
java.awt.Color[r=0,g=255,b=255]
Can somebody please explain me why the println() inside paint() is executing twice?
public void paint(Graphics g)
{
setBackground(Color.CYAN); // will trigger repaint()!
setForeground(Color.RED); // will trigger repaint()!
g.drawString("This is my first Applet",250,250);
System.out.println(getBackground());
}
The paint(Graphics) method is called whenever the toolkit feels it is necessary to do so. There are many things that will cause a repaint() (which in turn, leads to a call to paint(Graphics)). Some of them are:
A window moves in front of, or is removed from in front of, the app.
The size of the app. changes.
The background or foreground color changes or a component state changes.
A menu opens or closes.
...
Obviously, a paint does not happen only the times the programmer wants (or expects) it to. If that 'paint whenever needed' is a problem for the app., it is the apps. problem to sort, not the toolkits.
Queries for you:
Why code an applet? If it is due to the teacher specifying it, please refer them to Why CS teachers should stop teaching Java applets.
Why use AWT? See this answer for many good reasons to abandon AWT using components in favor of Swing.
Related
I use NetBeans for Java programming, and whenever I try to make an Applet, it doesn't work. The code is completely correct and I did not make any mistakes on it. When I hit "Run" a message appears in the output box that says, "BUILD SUCCESSFUL (total time: 0 seconds)" There are no error messages and no errors in the code, the Applet doesn't appear. The code is:
import java.applet.*;
import java.awt.*;
public class myProject extends Applet
{
public void init()
{
}
public void paint(Graphics g)
{
setSize(500,500);
}
public static void main(String[] args)
{
}
}
Get rid of the main method. If you're running the code as an applet, main will just confuse you and the IDE.
Make sure that you're telling NetBeans to run it as an applet, not as an application. Again, removing main should help you with this, since without main it can't run it as an app.
Consider not creating applets since they're considered somewhat dead technology.
Don't have setSize(...) within a paint method. Ever. GUI painting methods, such as paint(...) for AWT components and paintComponent(...) for Swing components derived from JComponent, should just do painting and nothing else.
Check out the Java Swing tutorials which can be found here: Swing Info
I've made a game in Java which works without any problem when I run it in Eclipse. Everything looks great and it is effectively done (at least until I come up with something else to do with it). So I've been trying to put it on my website, but whenever I run the game in browser I simply get a white screen, though checking the Java console shows no errors. I've managed to narrow the problem down to the painting of the screen. I have a timer which runs the game and makes stuff happen. At the end of it, it calls the repaint() method. In Eclipse, that works fine, but in the browser, nothing happens.
Here's the relevant code (All of which is inside the main class called FinalProject):
public class FinalProject extends JApplet implements ActionListener,
KeyListener, MouseListener, MouseMotionListener {
public void init(){
//...initialize program
System.out.println("game started");
}
/**
* A method called every so often by a timer to control the game world.
* Mainly calls other functions to control objects directly, but this
* is used as the only timer, which also calls repaint() at it's end.
*/
private void runGame(){
//...Run game and do important stuff
//This Draws The Screen
System.out.println("about to paint");
repaint();
}
public void paint(Graphics g){
System.out.println("painting");
//...paint screen
}
public void update(Graphics gr){
System.out.println("updating");
paint(gr);
}
}
runGame() is called by a timer. In Eclipse the output is:
game started
painting
painting
about to paint
painting
about to paint
painting
about to paint
painting
...
When doing this in a browser (Running offline directly on my machine. All browsers have the same problem as well), the console shows:
...(loading stuff)
game started
basic: Applet initialized
basic: Starting applet
basic: completed perf rollup
basic: Applet made visible
basic: Applet started
basic: Told clients applet is started
about to paint
about to paint
about to paint
...
I don't know what else to try at this point. Despite my efforts I still don't fully understand exactly what repaint() does, all I know is that it ultimately calls update() and paint(). Except that doesn't seem to be happening in the browser. I'm using Windows 7 64x with Java Version 7 Update 5. Thanks in advance for any help.
Turns out, the problem was in removing the menu bar. I had found some code a while ago which would remove the menu bar from the program and it worked without any problems. However it seems that it prevented it from repainting when placed in a browser. I have no idea why repainting broke because of removing the menu bar, but apparently it does.
The code I had used (in init()):
Frame[] frames = Frame.getFrames();
for (Frame frame : frames){
frame.setMenuBar(null);
frame.pack();
}
This code did remove the menu bar as desired, but also exploded the program whenever it was put online. Removing this fixed the issue. Fortunately, the menu bars don't show up online anyways, so you aren't losing much by removing this bit of code.
I'll start by saying that I'm a bit new to java, so if it's a stupid mistake, that's the reason.
I was messing with applets in java, and I've run into a problem when setting the size of the window, and using JOptionPane, whether it's just showing a message, or getting input through it, it displays three or more panes, rather than simply one. I'm on Ubuntu 12.04(x64), and here is my test code that still encounters the problem:
import javax.swing.JOptionPane;
import java.awt.Graphics;
import java.applet.Applet;
public class Main extends Applet{
public void paint(Graphics g)
{
//setup screen size
setSize((int)500,(int)500);
//print test message
JOptionPane.showMessageDialog(null, "There Should Be One Of Me!");
}
}
That's expected: there are as many option panes as number of calls to the paint method :-) the latter is not controllable by application code, neither in AWT nor in Swing.
As a general rule, never-ever change any component state in methods called during the paint cycle
remove setSize(.. and JOptionPane.sh... from public void paint(Graphics g)
for Applet I miss there method init()
(J)Applet tutorial shows a few examples
maybe better could be to use Swing JFrame instead of (J)Applet
I know this is sort of a vague question, but I will try to make it as clear as possible. When my Java app launches for the first time, it does some checking to see if files and directories exist and checks for an internet connection.
The app then allows the user to move on to the dashboard, which requires loading and adding many Swing components to the Background Panel. This takes time.
I was wondering how I could make it so that during the loading process at the start, the app loads all of the Swing components Images etc. so that they appear instantly when the user executes the command to do so.
I can load all of the components like this:
JButton = new JButton("blah");
but I'm not sure that's enough to make the components appear instantly, wouldn't adding several image filled Swing components at the same time still lag the UI thread, even if it was already "loaded" as seen above?
Thanks!
on the components use
setVisible(false)
for example
public class myParentPanel extends JPanel{
public myParentPanel{
//add all the child components
//Do what ever takes along time
setVisible(false); //this then makes in invisible but still
//allows all the set up code to run
}
public void showParent(){
setVisible(true);
invalidate();
}
}
and then create a method to make them visible when required. Hence all your setting in the constructors ca be called then when you call your method say:
drawWindow()
it then only has to call setVisible(true) and invalidate the screen to call their painting methods :).
An advancement on this would be to *run your setups i.e your checking and loading the panels methods on a separate threads*so you don't have to wait for a sequential loading. So on your loading you may to use an anonymous class
SwingUtilities.invokeLater(new Runnable(){ public void run(){
//do my display set up
}});
I'm creating an application in Swing using NetBeans. I would like to be able to manipulate some components during its startup (just once), after the window's made visible, for example update a progress bar. To this end, I have the app's main class, called MainWindow:
public class MainWindow extends JFrame
{
public MainWindow()
{
initComponents(); // NetBeans GUI builder-generated function for setting
// up the window components
}
public void Init()
{
loadLabel.setText("Loading....");
loadProgressBar.setValue(20);
doSomething();
loadProgressBar.setValue(40);
doSomething();
loadProgressBar.setValue(80);
doSomething();
loadProgressBar.setValue(100);
loadLabel.setVisible(false);
loadProgressBar.setVisible(false);
}
/* .... */
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
mainHandle = new MainWindow();
mainHandle.setVisible(true);
mainHandle.Init();
}
});
}
}
The problem is that the effect of the statements for updating the progress bar (or manipulating any other GUI component) within the Init() function can't be observed. If the Init() function is called from within main() as shown above, the window appears, but is empty, the Init() function executes and returns, only afterwards the window draws its contents but any changes made by Init() aren't visible because the window was empty and inactive the whole time. I also tried calling init from the windowOpened() AWT event, which executes after the window is fully drawn, but amazingly putting any statements for manipulating components there seems to have no effect, or rather they are put in a queue, and executed rapidly at some point in succession, so only the effect of the last one (hiding of the elements) can be observed. The only way I managed to get it working was to remove the whole invokeLater(new Runnable()...) mantra and put the new MainWindow(), setVisible(), Init() sequence directly in main(), which I guess is very ugly and breaks the concept of the gui running in a threaded manner. What is the right way to do this? Where do I put code to be executed first thing when the gui is ready to be manipulated, execute the statements once and return control to the main event loop?
I guess at the moment this is working in such a way, that while the Init() function is operating, any operations on the gui components are suspended (the drawing thread isn't separate and waits for Init() to finish before the manipulations are executed). Maybe I should make Init() a new thread... only how and what kind?
Thanks.
You could change the EventQueue.invokeLater() to invokeAndWait(), and move the call to init() out to a second EventQueue.invokeLater() call.
If (as looks to be the case) doSomething() takes a noticable amount of time, a better idea is to move the Init code into the body of a SwingWorker. This could be executed from the MainWindow() constructor or after the setVisible() call in main and is the idiomatic way to have a responsive GUI (in case the user gets bored waiting and wants to quit) and display some visible signs of progress.
See the process and publish methods for details on how to update the progress bar between doSomething() calls.
You may also want to look into ProgressMonitors for another alternative that would deal with the dialog box etc for you.
There are several things you can do:
For windows (such as JFrame or JDialog) you can attach WindowListener and do your manipulations in windowOpened method.
Override addNotify method and do your control manipulations there.
Attach HierarchyListener and do your manipulations whenever displayability of component changed.
Always make sure your do your component manipulations on EDT. Use SwingUtilities.invokeLater for simple UI updates or SwingWorker for long running tasks