Reputation: 43
I have some problems with the following classes: My problem is that the JPanel doesn't get renderd on the JFrame.
Here's the source code:
MainFrame.class
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
JPanel panel;
public MainFrame() {
setTitle("TestFrame");
setLayout(null);
setSize(800, 450);
setLocation(400, 225);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new TestPanel();
getContentPane().add(panel);
panel.setLocation(0, 0);
panel.setSize(64, 64);
panel.setVisible(true);
setLocationRelativeTo(null);
setVisible(true);
}
public void start() {
while(true) {
panel.repaint();
try {
Thread.sleep(20);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MainFrame frame = new MainFrame();
frame.start();
System.exit(-1);
}
}
TestPanel.class
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class TestPanel extends JPanel {
@Override
public void paintComponents(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawString("Test", 0, 0);
}
}
Why does it not work properly?
Fixed. All due to bad code quality.
Upvotes: 1
Views: 81
Reputation: 22474
You've overridden the paintComponents
method instead of paintComponent
(without "s").
Your infinite loop while(true)
is blocking the EDT thread which will freeze the GUI. You need to run that on a new thread or a better solution will be to use a javax.swing.Timer
to refresh the panel.
Also, as @CoderinoJavarino has mentioned, you need to set the y
coordinate in the drawString(....)
call to a bigger value.
As it is mentioned in the documentation:
The baseline of the leftmost character is at position (x, y)
You can do something like this to make sure the text isn't drawn offscreen:
g.drawString("Test", 0, g.getFontMetrics().getHeight());
Upvotes: 2
Reputation: 2881
You don't see your string, because your y
parameter is too small - it defines where the bottom of the string is, and since the lowest point of string is at very top you can't see it.
package test;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
public class TestPanel extends JPanel{
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.blue);
g.drawString("Hello", 0, 10);
}
public static void main (String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPanel());
frame.setSize(100, 100);
frame.setVisible(true);
}
}
Also, I really don't like your start
method, even though you are not using it yet. What you probably want to do, is let the panel implement ActionListener, and somewhere in your initialization code create a timer - Timer t = new Timer (delay, this); t.setRepeats(true); t.start();
. This will create a new thread that will be calling actionPerformed
method every delay
milliseconds.
package test;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TestPanel extends JPanel implements ActionListener{
private int red = 0;
private Timer t;
TestPanel() {
t = new Timer(20, this);
t.setRepeats(true);
t.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color (red, 0, 0));
g.drawString("Hello", 0, 10);
}
public static void main (String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPanel());
frame.setSize(100, 100);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
red = (red + 2) % 255;
repaint();
}
}
Upvotes: 2