Repaint not validating? - java

Hello everyone I am quite new to applets in java and was wondering why my oval was not moving up the screen when I press the up key. I said repaint in the paint method and nothing is happening
Any Ideas? (Please don't be rude I am new to applets so...)
package mypackage;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.applet.*;
public class gameapplet extends Applet {
int charecterx = 500;
int charectery = 250;
public void init(){
addKeyListener(new AL());
setSize(1000,1000);
setBackground(Color.RED);
}
public void paint(Graphics g){
//Paint Method
g.setColor(Color.BLACK);
g.fillOval(charecterx,charectery,100,100);
repaint();
}
public class AL extends KeyAdapter
{
public void keyPressed (KeyEvent e)
{
int keyCode = e.getKeyCode();
//If Statements To see if user is moving
if(keyCode == e.VK_UP)
{
if(charecterx <= 0)
{
charecterx = 0;
}
else
{
charecterx--;
}
}
}
public void keyRealesed(KeyEvent e){
}
}
}

You're main problem comes down to two main issues...
1- You are using a KeyListener
KeyListeners are notorious for being problematic in that they only respond to keystrokes when the component they are registered to are focusable AND have focus.
2- You never call repaint from within the keyPressed method to request that the applet be repainted.
You should avoid Applet as it is woefully out of date and generally not used by many people anymore. Instead use JApplet, in fact, I would recommend avoiding applets altogether until you understand the API better
Don't call setSize on an applet, the size of applet is defined by the html tag it is created from.
Don't call repaint or anything that might call repaint from within any paint method
Don't override paint, it's too easy to break the paint chain (which you have) and for top level containers like Applet, isn't double buffered. In fact AWT generally isn't double buffered, which will cause flickering when the component is repainted. Instead, you should use something like a JPanel and override it's paintComponent method
Don't use KeyListener, it has too many issues with focus. Instead, make use of the Key Bindings API which provides you with more control and a much more reusable API
Take a look at:
Creating a GUI With JFC/Swing
Performing Custom Painting
Painting in AWT and Swing
For more details

It depends on the version of your jdk.
In jdk1.6 I would use this
invalidate();
validate();
repaint();
In jdk 1.7 I would use
revalidate();
repaint();

Related

How to get the Java Output screen?

I am trying to display images on the screen using Graphics but the screen doesn't load
The output screen appears but only show The black screen and not the images
The code gets compiled properly so why am i not getting the output
package game;
import java.awt.*;
import javax.swing.JFrame;
public class Screen {
private GraphicsDevice vc;
public Screen(){
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
vc=env.getDefaultScreenDevice();
}
public void setFullScreen(DisplayMode dm, JFrame window){
window.setUndecorated(true);
window.setResizable(false);
vc.setFullScreenWindow(window);
if(dm !=null && vc.isDisplayChangeSupported()){
try{
vc.setDisplayMode(dm);
}catch(Exception ex){}
}
}
public Window getFullSCreenWindow(){
return vc.getFullScreenWindow();
}
public void resotreScreen(){
Window w= vc.getFullScreenWindow();
if(w!=null){
w.dispose();
}
vc.setFullScreenWindow(null );
}
}
package game;
import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
class Images extends JFrame{
public static void main(String[] args){
DisplayMode dm = new DisplayMode(800,600,16,DisplayMode.REFRESH_RATE_UNKNOWN);
Images i = new Images();
i.run(dm);
}
private Screen s;
private Image bg;
private Image pic;
private boolean loaded;
public void run(DisplayMode dm){
setBackground(Color.BLUE);
setForeground(Color.WHITE);
setFont(new Font("Arial",Font.PLAIN,24));
loaded =false;
s = new Screen();
try{
s.setFullScreen(dm, this);
loadpics();
try{
Thread.sleep(10000);
}catch(Exception ex){}
}finally{
s.resotreScreen();
}
}
public void loadpics(){
bg = new ImageIcon("C:\\Users\\Dhruv\\Downloads\\Ronaldo.jpg").getImage();
pic =new ImageIcon("C:\\Users\\Dhruv\\Downloads\\Messi.jpg").getImage();
loaded= true;
repaint();
}
public void paint(Graphics g){
if(g instanceof Graphics2D){
Graphics2D g2 =(Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
if(loaded){
g.drawImage(bg,0,0,null);
g.drawImage(pic,170,180,null);
}
}
}
Let's start with background information...
A JFrame is a container for a JRootPane, which contains the contentPane, JMenuBar and JGlassPane
When you override paint of top level container like JFrame, you are only painting the bottom most component, the JRootPane and it's contents are then painted over the top, making it kind of pointless.
See How to Use Root Panes for more details
Painting is also a complex operation, failing to call super.paint will cause no end of issues, make sure you always call the super paint method before painting unless you really understand how it works and are prepared to do it's job manually.
In Swing you are instead encouraged to extend from a JComponent based class (JPanel been the preferred) and override its paintComponent method and perform your custom paint there
This component can either be added to the window or set as the contentPane or added to some other container depending on your needs.
See Painting in AWT and Swing and Performing Custom Painting for more details.
ImageIcon uses background thread to load it's images, so even though it returns, the image might not be realised (or fully loaded). When you use g.drawImage(bg,0,0,null);, passing null as the ImageObserver, it prevents the container from knowing when the image changes and allowing it to automatically repaint itself.
What's cool is, all Component based classes implement ImageObserver, so pretty much anything which can paint can act as an ImageObserver.
Convention would encourage to pass this as the ImageObserver.
Generally, a better solution is to use ImageIO, which when it loads images, won't return until the image is fully realised.
Have a look at Reading/Loading an Image for more details.
Thread.sleep(10000); is a dangerous thing to use in Swing. It has the potential to stop the UI from been updated or respond to other input and events, making your program appear as if it's hung, because it has. But in your case, it means you're violating the single thread rules of Swing.
Swing is a single threaded environment, you should never perform any action which might block the Event Dispatching Thread and you should never update the UI from outside the context of the EDT.
There are solutions available to help you, Swing Timer for generating periodical events which are dispatched within the EDT and SwingWorker for performing long running operations which have support for updating the UI.
See The Event Dispatch Thread for more details.
My recommendation is to not worry about the full screen support, focus on getting the images painting using a normal window and the add the full screen support. This allows you to solve problems within an isolated set of functionality, making it much easier to solve.

how to call a graphical method in actionperformed?

I am kinda new to java and would like to invoke a graphical method in ActionEvent, for instance let's say I would like a square to be drawn when button b is pressed? Will appreciate any help thanks:
package Mst;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Cours2_2 extends Applet implements ActionListener {
Button a,b,c;
public void init(){
setBackground(Color.pink);
a= new Button("KIRMIZI");
a.addActionListener(this);
add(a);
b= new Button("BEYAZ");
b.addActionListener(this);
add(b);
c= new Button("SARI");
c.addActionListener(this);
add(c);
}
public void paint(Graphics g){
g.drawString("s", 5, 5);
}
public void actionPerformed(ActionEvent e){
String s= e.getActionCommand();
if(s.equals("KIRMIZI")){
setBackground(Color.red);
}
if(s.equals("BEYAZ")){
setBackground(Color.white);
}
if(s.equals("SARI")){
setBackground(Color.yellow);
}
drawStrings(t);
}
public void drawStrings(Graphics t) {
t.setColor(Color.yellow);
t.fillRect(0, 0, 75 ,75);
}
}
I would like to know if I should create this square which I want drawn when a button is pressed as a method or a function. Thanks
Avoid Applet, if you "really" have to, use JApplet instead. Having said that, you should start with JPanel and override it's paintComponent method instead (and make sure you call super.paintComponent before doing any custom painting. Take a look at Painting in AWT and Swing and Performing Custom Painting for more details.
Generally speaking, painting in AWT/Swing is passive, that is, when the system "decides" something needs to be updated, it will then be painted. This means that you (generally) have little control over when something will be painted. You make suggestions, but it's update to the system to decide what and when something is painted.
You paint methods should paint the current state of the component. This means that you will need to provide some information and logic that the paint methods can use to make decisions about what to paint. For example, you could have a flag, which is changed by the ActionListener, which calls repaint on your component and when the component is painted, you would test the state of this flag and make decisions on what should be done (like drawing a square for example).
A more complicated approach might use a List and take advantage of the Shape API, adding or removing shapes to the List which the paint method would then be able to iterate over and paint
Have a look at Collections Trail and
2D Graphics for more details

Japplet shapes does not shown in Applet

Im working with eclipse.
My Code:
import javax.swing.JApplet;
import java.awt.*;
public class Einstein extends JApplet
{
public void pain(Graphics page)
{
page.drawRect(60,60,40,40); // Square
page.drawString("Out of clutter, find simplicity. " , 110, 70);
}
}
The rectangle and text does not shown in the applet.
what could be the problem?
public void pain(Graphics page) - interesting choice of naming...
I believe the method you're looking for is paint
#Override
public void paint(Graphics g) {
super.paint(g);
//...
}
Make sure you call super.paint before performing any custom painting, otherwise you could end up with a bunch of nasty paint artefacts.
Having said that. Consider using a custom component, extending from JPanel for example, and override it's paintComponent method instead, then add this component to your applet.
You gain the benefit of the double buffering support of Swing for free and the freedom to move you component to another container, like a JFrame or other container for example, making it far more re-usable

why components redrawn when i override with empty paintComponent(g) method?

As i understand (and i am java noob), when i resize a window or change its content paintComponent() method should be called automatically. It redraws everything, so when i override it with an empty method, nothing should be redrawn...but it is. Why? Probably i am missing something. What exactly is redrawn by paintComponent(), everything? Or some backgrounds or smth?
import java.awt.*;
import javax.swing.*;
public class TextFrame extends JFrame {
public TextFrame(String text, String fontName) {
super("Show Font");
setSize(725, 150);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TextFramePanel sf = new TextFramePanel(text, fontName);
JButton ok = new JButton("i hate disappearing");
sf.add(ok);
add(sf);
setVisible(true);
}
public static void main(String[] arguments) {
if (arguments.length < 1) {
System.out.println("Usage: java TextFrame message font");
System.exit(-1);
}
TextFrame frame = new TextFrame(arguments[0], arguments[1]);
}
}
class TextFramePanel extends JPanel {
String text;
String fontName;
public TextFramePanel(String text, String fontName) {
super();
this.text = text;
this.fontName = fontName;
}
public void paintComponent(Graphics comp) {
//super.paintComponent(comp);
/*Graphics2D comp2D = (Graphics2D)comp;
comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Font font = new Font(fontName, Font.BOLD, 18);
FontMetrics metrics = getFontMetrics(font);
comp2D.setFont(font);
int x = (getSize().width - metrics.stringWidth(text)) / 2;
int y = getSize().height / 2;
comp2D.drawString(text, x, y);
System.out.println("vlad");*/
}
}
I suggest you read up on the official docs for Custom Painting: http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html, more importantly under the Section A Closer Look at the Paint Mechanism.
Here's the part that's directly related to your question:
[...] the paintComponent method is where all of your painting code should be placed. It is true that this method will be invoked when it is time to paint, but painting actually begins higher up the class heirarchy, with the paint method (defined by java.awt.Component.) This method will be executed by the painting subsystem whenever you component needs to be rendered. Its signature is:
public void paint(Graphics g)
[...] The API does nothing to prevent your code from overriding paintBorder
and paintChildren, but generally speaking, there is no reason for you
to do so. For all practical purposes paintComponent will be the only
method that you will ever need to override.
So, when you're declaring:
public void paintComponent(Graphics comp) {}
you're not actually doing nothing. That's because the painting, as stated from the docs, does not begin with paintComponent(), but rather with paint(), which is called much earlier.
Now, if you declare it like this:
public void paint(Graphics g){}
then nothing will be redrawn after resizing and etc, no matter what code you have in your paintComponent(), because the beginning of the paint hierarchy has just been defined as an empty routine.
"...so when i override it with an empty method, nothing should be redrawn...but it is. Why?"
So it looks like you're running this program from the command line. If you are running the program, and it's still painting the stuff inside the paintComponent method (even after you commented out its content), most likely you ran the program with compiling again. So the program is still running from the same .class file.
When I run the program as is, I see nothing but a button, no painted words.
C:\stack>java TextFrame Hello World
" What exactly is redrawn by paintComponent(), everything? Or some backgrounds or smth?"
paintComponent just paint the component itself, which is just the JPanel in your case. It doesn't paint any other components added to it. That painting is delegated by its paintComponent method. Every JComponent has its own paintComponent method. So if you're wondering why the button still appears, it's because the call to paintComponent in the JPanel only affects the JPanel, not other child components add to it.

Launching another Applet from another Applet

I have made a Loader Applet which greets the user and when user clicks the button displayed on that Applet it then launches the main applet and the Loader Applet is destroyed.
But on clicking Another applet is not launched !
Loader Applet:
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
public class Loader extends JApplet implements ActionListener{
Display secondApplet;
Button button;
#Override
public void init() {
setSize(800,600);
}
#Override
public void start() {
setLayout(new FlowLayout());
button = new Button ("Click me !!");
add(button);
button.addActionListener(this);
}
#Override
public void paint(Graphics g) {
}
#Override
public void actionPerformed(ActionEvent e) {
secondApplet = (Display)getAppletContext().getApplet("Display");
if (secondApplet != null) {
secondApplet.init();
secondApplet.start();
}
else {
System.out.println("Not Running\n");
}
}
}
Display Applet:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JApplet;
public class Display extends JApplet {
#Override
public void init() {
setSize(600,400);
}
#Override
public void paint(Graphics g) {
g.fillRect(0, 0, this.getWidth(), this.getHeight());
}
}
How can I create an instance of the other Applet and destroy the current Applet !!
Since an Applet/JApple is a java.awt.Panel itself, then you can embed one into the other, for your specific case you can embed Display into Loader using a Panel in Loader to reload Display as you need.
Something like this:
Panel container = new Panel();
container.setLayout(new GridLayout(1,0));
container.add(secondApplet); //Display Applet
add(container):
secondApplet.init();
secondApplet.start();
button.setVisible(false);
There are so many things wrong with the applets it is hard to know where to begin. But let us concentrate 1st on a more sensible strategy to cause the change beteween one view and another.
Instead of having two applets, have two panels that are swapped in a CardLayout
Instead of having both applets in one page, call getAppletContext().showDocument(secondAppletURL);. Presumably secondAppletURL is different to the URL of the page that hosts the first applet.
OK - the problems with the first applet:
Don't try to set the size of an applet. It is set by the HTML.
All the methods calls in the start() method should be moved to the init() method, since the start() method might be called repeatedly. Then there is no reason to override start() at all.
Don't mix Swing (e.g. JApplet) & AWT (e.g. Button) components without good cause. In this case, use JButton instead of Button.
As a stylistic point, it is typically better to create an anonymous inner ActionListener than implement it on the parent class.
Overriding paint() with an empty implementation is not a good idea. The original paint() draws the applet and components, so now it would do nothing.
The methods in the actionPerformed() are equally nonsensical. An applet does not get included into the AppletContext until after init() & start() have been called, which would mean that calling those methods explicitly causes them to be invoked a second time. While the start() method is meant to be called multiple times, the init() method should only be called once.
2nd Applet.
Ditto point 1. re the 1st applet.
The overridden paint() method ..would paint the BG color (or the FG color - not sure) but nothing else. Again, don't override it.
Try this method to load another applet. See if it works.
Class applet2 = Class.forName("Applet2");
Applet appletToLoad = (Applet)applet2.newInstance();
appletToLoad.setStub(this);
setLayout(new GridLayout(1,0));
add(appletToLoad);
appletToLoad.init();
appletToLoad.start();

Categories

Resources