Reputation: 7
Im trying to use what I have learned the last six months of java programming to recreate the classic pong game. But drawing lines isn't one of the things, even if it seems basic.
public static void main(String[] args) {
Pong p = new Pong();
p.setVisible(true);
}
/**
* The Constructor
*/
public Pong() {
makeFrame();
draw(getGraphics());
}
/**
* Making the frame for the game
*/
public void makeFrame() {
// Frame stuff goes here
}
/**
* Drawing the in-games lines
*/
public void draw(Graphics g) {
super.paint(g);
g.setColor(Color.white);
g.drawLine(400, 0, 400, 550);
}
I can't seem to get the line to draw itself. Any idea on what I'm doing wrong? I want the line in the middle of my screen.
EDIT: Would like to thanks the guys who answered the question. Many kudos to you guys! I really appreciate the answers and the provided links! :)
Upvotes: 0
Views: 930
Reputation: 347204
In Swing, you are not responsible for painting, that job falls to the RepaintManager
. It decides what and when to paint based on a number of factors.
The recommended mechanism for performing custom painting is to crate a custom class, extending from something like JPanel
and override it's paintComponent
method. If you would like to update the component, you can request that the component be repainted by calling it's repaint
method.
Make no mistake, this is a request only.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class QuickPaint {
public static void main(String[] args) {
new QuickPaint();
}
public QuickPaint() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new PaintPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PaintPane extends JPanel {
private int paints = 0;
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
paints++;
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.drawLine(width / 2, 0, width / 2, height);
g.drawLine(0, height / 2, width, height / 2);
g.drawLine(0, 0, width, height);
g.drawLine(0, height, width, 0);
String text = "Repainted " + paints + " times";
FontMetrics fm = g.getFontMetrics();
int x = (width - fm.stringWidth(text)) / 2;
int y = ((height - fm.getHeight()) / 2) + fm.getAscent();
g.drawString(text, x, y);
}
}
}
Take a close look at Performing Custom Painting and Painting in AWT and Swing for more details...
Upvotes: 1
Reputation: 17945
In Java Swing, you do not call "draw" by yourself - instead, you create a JFrame (or another top-level container, such as JApplet) and overwrite its "paint" method -- or the paint method of components that are contained, directly or indirectly, in your root elements.
Your getGraphics() will not return an actual graphics context (those are only created for root swing components, or when building bitmap buffers for off-screen painting). So nothing will be displayed. Have a look at the official painting tutorial.
The recommended approach (and the one used in the above tutorial) is to perform custom painting by overriding the paintComponent() method of a JPanel contained within your component hierarchy.
Upvotes: 2