Reputation: 471
When I run my code, I expect to see a JPanel
in my JFrame
, but nothing shows up. I had a button in the frame, and it shows up. But the JPanel
doesn't show up, I even colored it in red.
Here is the code for my JPanel
:
import java.awt.*;
import javax.swing.JPanel;
public class graphic extends JPanel {
private static final long serialVersionUID = -3458717449092499931L;
public Game game;
public graphic(Game game){
this.game = game;
this.setPreferredSize(new Dimension(400,400));
this.setBackground(Color.RED);
}
public void paintComponent(Graphics g){
for (Line l:game.mirrors){
g.setColor(Color.BLACK);
g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
}
}
}
And my JFrame code:
import java.awt.Container;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.*;
public class Viewer implements ActionListener {
public JFrame frame;
public JButton drawShoot;
public boolean draw;
public Game game;
public graphic graphic;
public TimerTask timert;
public Timer timer;
public Viewer(){
draw = true;
game = new Game();
}
public static void main(String args[]){
Viewer v = new Viewer();
v.setup();
}
public void setup(){
frame = new JFrame("Laser Stimulator");
drawShoot = new JButton("Edit Mode");
graphic = new graphic(game);
graphic.repaint();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(300, 300, 600, 600);
Container contentPane = frame.getContentPane();
SpringLayout layout = new SpringLayout();
contentPane.setLayout(layout);
drawShoot.addActionListener(this);
timert = new TimerTask() {
@Override
public void run() {
}
};
timer =new Timer();
timer.scheduleAtFixedRate(timert, 0, 1000/30);
contentPane.add(graphic);
layout.putConstraint(SpringLayout.NORTH, graphic, 0, SpringLayout.NORTH, contentPane);
layout.putConstraint(SpringLayout.WEST, graphic, 0, SpringLayout.WEST, contentPane);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==drawShoot){
draw = !draw;
drawShoot.setText((draw)?"Edit Mode":"Shoot Mode");
}
}
}
Upvotes: 3
Views: 2552
Reputation: 36423
@MadProgrammer has already answered this question (+1 to him). In most overriden methods there are calls to their super do not forget to honor this or else these small hiccups begin to surface.
On another note:
Dont call setBounds(..)
on JFrame
( i cannot see why you need it) rather call JFrame#pack()
before setting the JFrame
visible.
No need to do frame.getContentPane()
as of Java 6. Simply use:
frame.add()
or frame.setLayout(..)
.
As a conveniance
add
and its variants,remove
andsetLayout
have been overridden to forward to the contentPane as necessary.
You also have this:
graphic = new graphic(game);
graphic.repaint();
I cannnot see why the call to repaint()
will be necessary repaint()
will be called the first time the component is visible
Rather override getPreferredSize
of JPanel
than calling setPreferredSize()
Do not implement an ActionListener
in a class unless it will be accessed via other classes. Rather use an anonymous Listener
like so:
refresh.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == drawShoot) {
draw = !draw;
drawShoot.setText((draw) ? "Edit Mode" : "Shoot Mode");
}
}
});
Upvotes: 4
Reputation: 347334
So the basic problem is you failed to honor the paint chain. You must call super.paintXxx
when ever you override on the paint methods...
This method must call super.paintComponent(g)
, because it's responsible for clearing the background ;)
public void paintComponent(Graphics g) {
for (Line l : game.mirrors) {
g.setColor(Color.BLACK);
g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
}
}
public class QuickTestPaintPane {
public static void main(String[] args) {
new QuickTestPaintPane();
}
public QuickTestPaintPane() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
Viewer v = new Viewer();
v.setup();
}
});
}
public class Viewer implements ActionListener {
public JFrame frame;
public JButton drawShoot;
public boolean draw;
// public Game game;
public graphic graphic;
public TimerTask timert;
public Timer timer;
public Viewer() {
draw = true;
// game = new Game();
}
public void setup() {
frame = new JFrame("Laser Stimulator");
drawShoot = new JButton("Edit Mode");
graphic = new graphic();
// graphic.repaint();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(300, 300, 600, 600);
// Container contentPane = frame.getContentPane();
SpringLayout layout = new SpringLayout();
frame.setLayout(layout);
drawShoot.addActionListener(this);
timert = new TimerTask() {
@Override
public void run() {
}
};
timer = new Timer();
timer.scheduleAtFixedRate(timert, 0, 1000 / 30);
frame.add(graphic);
layout.putConstraint(SpringLayout.NORTH, graphic, 0, SpringLayout.NORTH, frame.getContentPane());
layout.putConstraint(SpringLayout.WEST, graphic, 0, SpringLayout.WEST, frame.getContentPane());
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == drawShoot) {
draw = !draw;
drawShoot.setText((draw) ? "Edit Mode" : "Shoot Mode");
}
}
}
public class graphic extends JPanel {
private static final long serialVersionUID = -3458717449092499931L;
// public Game game;
// public graphic(Game game) {
public graphic() {
// this.game = game;
this.setPreferredSize(new Dimension(400, 400));
this.setBackground(Color.RED);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.drawLine(0, 0, getWidth(), getHeight());
// for (Line l : game.mirrors) {
// g.setColor(Color.BLACK);
// g.drawLine(l.start.x, l.start.y, l.end.x, l.end.y);
// }
}
}
}
Upvotes: 5