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
Related
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
So I have this code:
public class myPanel extends JPanel implements ActionListener{
int x = 0;
JButton myButton = new JButton("Click me");
public myPanel(){
super().setLayout(null);
myButton.setBounds(50,50,50,50);
super().add(myButton);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(x==1)
g.drawString("hi",10,10);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==myButton){
x=1;
//Do something here
}
}
}
How do I call paintComponent again? Say when I press the button, it calls paintComponent again and draw the string, "Hi", after checking if the integer,x, is equal to one? Thank you in advance!!! Still very new to Java here, so can you guys explain this like you will to a 10 year old?
Call repaint(), it will paint it again.
You would call repaint() after any change in state that should change the GUI's view. For instance, if the button changes a variable, and if this should be reflected in a change in the view, call repaint() in the button's ActionListener. If a mouse drag changes the view of an ImageIcon sprite, then you would call repaint in the MouseMotionListener's mouseDragged method. If a Swing Timer drives an animation, then you would call repaint() from within the Swing Timer's ActionListener.
One thing you never want to do is to call repaint() from within a paint(Graphics g) or paintComponent(Graphics g) method as this will lead to looping that is completely out of your control.
On a side note, in general you will want to avoid using null layouts and setBounds as this makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain.
I am making a game in which I move a square with my mouse, but when I move my mouse the old squares do not delete, which results in a trail of squares. I would like it to only have the one square which is following my mouse. This is currently my code. I have read to use paintcomponents but I am not sure how to use it since I am still a beginner.
This is in my "GamePanel" Class
public void mouseMoved(MouseEvent m) {
Graphics g= this.getGraphics();
h.changeX(m.getX());
h.changeY(m.getY());
h.drawHero(g);
}
This is in my "Hero" Class
public void drawHero(Graphics g){
g.drawImage(heroPic,stX,stY,null); //heroPic is a picture I imported
Don't use the this.getGraphics(). That is something you will definitely not want to to do, since it produces artifacts (as you mentioned).
It would be better to store the mouse position as a variable, then handle all the rendering when the paintComponent(Graphics) method has been called. Be sure to also call super.paintComponent(Graphics) to get rid of artifacts.
Generally, you should only handle graphics inside the paintComponent(Graphics) method and in any methods that are called only from the paintComponent(Graphics) method.
Here is a question which touches on why you should avoid Component#getGraphics(): Drawing an object using getGraphics() without extending JFrame
Here is another question I answered revolving around rendering with graphics: Java JFrame draw
Use a seperate class that extends JPanel :
class DrawPane extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(heroPic, x, y, this);
}
}
Then create a variable that will hold this class object :
DrawPane dp = new DrawPane();
after that set the variable to the contence pane. :
JFrame.setContencePane(dp);
Now to repaint this do :
dp.repaint();
Do not worry about the 'Graphics g' you wont have to input anything.
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();
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.