Why is Java Graphics not painting? - java

I'm a bit new to programming right now and am trying to make Pong in java. However I'm not able to make any graphics show up.
Main Class
public class Pong1 {
public static Frame frame = new Frame();
public static Panel panel = new Panel();
public static void main(String[] args) {
initUI();
}
public static void initUI(){
frame.setLayout(new BorderLayout());
frame.add(BorderLayout.CENTER, panel);
frame.pack();
frame.setVisible(true);
}
public static int getPanelWidth(){
return panel.getWidth();
}
public static int getPanelHeight(){
return panel.getHeight();
}
}
JFrame Class
package pong1;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Frame extends JFrame{
Frame(){
setTitle("Pong");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(true);
setMinimumSize(new Dimension(800,500));
setLocationRelativeTo(null);
}
}
In this final class is the JPanel class where I override and call paintComponent. However, nothing shows up.
public class Panel extends JPanel{
Panel(){
setPreferredSize(new Dimension(800,500));
setMinimumSize(new Dimension(800,500));
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.blue);
g2.fillOval(100,100,100,100);
}
I've looked at dozens of other posts and I've tried many different things, and yet nothing shows up. Does anyone know what is going on?

I run you posted code and it seemed to work just fine, however, the reliance on static is very worrying and is likely to lead into some very interesting problems, best to avoid it.
Also, you should ensure that your UI is created within the context of the Event Dispatching Thread to reduce possible thread violation issues which could cause more problems.
Finally, you don't really need to extend JFrame, you're not really adding any value to the class and you could use a factory or builder pattern to achieve the same thing with less complexity
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Pong1 {
public static void main(String[] args) {
new Pong1();
}
public Pong1() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Panel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Panel extends JPanel {
public Panel() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 500);
}
#Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("...");
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.blue);
g2.fillOval(100, 100, 100, 100);
}
}
}
Oh, and you really should avoid using setPreferred/Minimum/MaximumSize, see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for more discussions on the subject

Related

rendering an Image to a JPanel

I am currently trying to render an Image to a JPanel. Here is my Code:
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class ScreenSaver extends JPanel {
private static final long serialVersionUID = 001;
public static void main(String[] args) {
new ScreenSaver();
}
public ScreenSaver() {
new Window(1600, 900, "ScreenSaver", this);
}
public Image ball;
public void initCode() {
try {
File pathToBall = new File("ball.png");
ball = ImageIO.read(pathToBall);
} catch (IOException ex) {
ex.printStackTrace();
}
renderImage()
}
public void renderImage(Graphics g) {
g.drawImage(ball, 0, 0, 100, 100, null);
}
}
The "initCode()" method gets called after the JFrame has loaded. My problem now is that I want to call the "renderImage()" method. In the parameters I have to put "Graphics g" to use the "g.drawImage" function. Sadly I now dont know what to put in the brackets when I want to call "renderImage()". Can someone help?
The painting of pictures and graphic elements works a little differently than in your question.
Here is a working example:
import java.awt.*;
import java.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
public class PaintExample extends JFrame{
private BufferedImage ball;
public static void main(String[] args) {
new PaintExample();
}
public PaintExample(){
initCode();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(1600, 900));
setMinimumSize(new Dimension(800, 600));
add(new JPanel(){
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(ball, 0, 0, 100, 100, this);
}
});
pack();
setLocationRelativeTo(null);
setTitle("Paint Example");
setVisible(true);
}
public void initCode() {
try {
File pathToBall = new File("ball.png");
ball = ImageIO.read(pathToBall);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
I hope this solves your problem.
Swing is event driven, this means that you never directly call painting methods.
Basics for a custom painting component:
extends JComponent
override paintComponent(Graphics g), this is the point where you can put your rendering code
override getPreferredSize(), so that the layout managers can do their duty, a suitable value is your image size
In addition I don't understand this line:
new Window(1600, 900, "ScreenSaver", this);

Java swing: i called once drawString and it printed my string multiple times

I'm new in java swing programming. What i'm trying to do is paint a string to a specific location in a JPanel. The JPanel is very large and so i add it to a JScrollpane, but when i draw the string it is printed not just in the specified location but also in others.
The first image represents the bottom of the panel where i decided to draw the string and this is correct. But if you observe whole the panel you can find the string too in others locations (see second image).
Can someone tell me why this happen? How can i prevent it?
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
class Example extends JFrame
{
private MyPanel gg=new MyPanel();
Example(){
add(new JScrollPane(gg));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(MAXIMIZED_BOTH);
}
public static void main(String argv[]){
EventQueue.invokeLater(new Runnable() {
public void run() {
Example test=new Example();
test.setVisible(true);
}
});
return;
}
}
class MyPanel extends JPanel
{
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d=(Graphics2D)g;
g2d.drawString("HI I LOVE ELON MUSK", 90, 300035);
return;
}
public Dimension getPreferredSize() {
return new Dimension(500, 300060);
}
}
Your code ran fine on my Windows 10 system. I have a Java 13 JDK that I compile at Java 8.
I made a few changes to your main class. Maybe these changes stabilized the display. Run my code on your system and see.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class LongJPanelExample {
public LongJPanelExample() {
JFrame frame = new JFrame("Long JPanel Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel gg = new MyPanel();
frame.add(new JScrollPane(gg));
frame.pack();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
public static void main(String argv[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new LongJPanelExample();
}
});
}
}
class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawString("HI I LOVE ELON MUSK", 90, 300035);
return;
}
public Dimension getPreferredSize() {
return new Dimension(500, 300060);
}
}

Java Code Painting in JPanel

I just started learning Java and am now recently learning new things outside of the console. I copied a code from The Professor's board but i can't seem to get it to work. It is suppose to draw circles and rectangles for now but i just get a blank window when i try to paint. I think i may have missed a line of code or something. I am using Eclipse on Mac.
I understand there may be many ways to do this but i want to kind of keep the code exactly how he has it for now in addition with whatever fixes you think will make it work. Thanks alot.
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class Bunny {
public static void main(String [] args)
{
MyFrame f = new MyFrame();
f.setSize(500,400);
f.setVisible(true);
f.setLocation(50,100);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class MyFrame extends JFrame
{
public MyFrame()
{
}
}
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class MyPanel extends JPanel
{
public void paintComponent(Graphics g)
{Graphics2D g2 = (Graphics2D) g;
Ellipse2D.Double Circle = new Ellipse2D.Double(100,50,75,75);
g2.setColor(Color.RED);
g2.fill(Circle);
Rectangle box = new Rectangle(200,100,150,150);
g2.setColor(Color.RED);
g2.fill(box);
Color myColor = new Color(255,0,0);
}
}
I'd like to, very much, tell your professor that they need to go back to school and learn how to use Swing properly
You should start by taking a look at Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
Ellipse2D.Double Circle = new Ellipse2D.Double(100, 50, 75, 75);
g2.setColor(Color.RED);
g2.fill(Circle);
Rectangle box = new Rectangle(200, 100, 150, 150);
g2.setColor(Color.RED);
g2.fill(box);
g2.dispose();
}
}
}
Code Review...
public class Bunny {
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.setSize(500, 400);
f.setVisible(true);
f.setLocation(50, 100);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Bad: Interacting with UI from outside the context of the Event Dispatching Thread. See Initial Threads for details
public class MyFrame extends JFrame {
public MyFrame() {
}
}
Bad: Extending from a top level container is (like JFrame) is generally discourage, you're not adding any new features to the class and this is one of the areas where most problems occur. You might like to do some research into "composition over inheritance".
You also not actually adding anything to the frame, so it will appear blank.
public class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Ellipse2D.Double Circle = new Ellipse2D.Double(100, 50, 75, 75);
g2.setColor(Color.RED);
g2.fill(Circle);
Rectangle box = new Rectangle(200, 100, 150, 150);
g2.setColor(Color.RED);
g2.fill(box);
Color myColor = new Color(255, 0, 0);
}
}
Bad: paintComponent should never be public, there is no reason ever that any other class should be calling this method. Not calling super.paintComponent will cause no end of graphic glitches and issues, you should always call super.paintComponent first. The only times you wouldn't is when you know what you're doing and you have an extremely good reason not to...which is like <1% of the time.

I'm trying to draw a filled rectangle over an imageIcon using the coordinates of the image and the rectangle appears off

Eventually after I work out this small detail it will receive a building and room number to outline said building and room number so it is easy to locate but I can't get the rectangle to draw even close to acurately over a single room.
package programSTLApp;
/*
Program to request the classroom no. in STLCC and Display the location of
that classroom.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class STLApp extends JFrame
{
private JLabel imageLabel;
private JButton button;
private JPanel imagePanel;
private JPanel buttonPanel;
public STLApp()
{
super("My STLCC Class Locator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
buildImagePanel();
buildButtonPanel();
add(imagePanel, BorderLayout.CENTER);
add(buttonPanel,BorderLayout.SOUTH);
pack();
setVisible(true);
}
private void buildImagePanel()
{
imagePanel = new JPanel();
imageLabel = new JLabel("Click the button to see the drawing indicating "
+ "the location of your class");
imagePanel.add(imageLabel);
}
private void buildButtonPanel()
{
buttonPanel = new JPanel();
button = new JButton("Get Image");
button.addActionListener(new ButtonListener());
buttonPanel.add(button);
}
private class ButtonListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
ImageIcon SiteLayoutFV = new ImageIcon("D:\\B120.jpg");
imageLabel.setIcon(SiteLayoutFV);
imageLabel.setText(null);
pack();
}
}
public void paint(Graphics g)
{
super.paint(g);
g.setColor(Color.RED);
g.fillRect(55,740,164,815);
}
public static void main(String[] args)
{
new STLApp();
}
}
As has already being pointed out, top level containers ain't a studiable class for performing custom painting, there is just to much going with these containers to make it easy to paint to.
Instead, create yourself a custom component, extending from something like JPanel, and override it's paintComponent method.
Once you have the floor pane rendered, you can render you custom elements over the top of it.
How you store this information is up to you, but basically, you need some kind of mapping that would allow you to take the floor/room and get the Shape that should be rendered.
Because the floor map might float (it may not always be rendered at 0x0 for example), you need to be able to translate the coordinates so that the Shape will always match.
Take a look at...
Performing Custom Painting
2D Graphics
For more details
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FloorPlan {
public static void main(String[] args) {
new FloorPlan();
}
public FloorPlan() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage floorPlan;
private Rectangle myOffice = new Rectangle(150, 50, 32, 27);
public TestPane() {
try {
floorPlan = ImageIO.read(new File("floorPlan.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return floorPlan == null ? new Dimension(200, 200) : new Dimension(floorPlan.getWidth(), floorPlan.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (floorPlan != null) {
int x = (getWidth() - floorPlan.getWidth()) / 2;
int y = (getHeight() - floorPlan.getHeight()) / 2;
g2d.drawImage(floorPlan, x, y, this);
g2d.setColor(Color.RED);
g2d.translate(x, y);
g2d.draw(myOffice);
}
g2d.dispose();
}
}
}

Not showing graphics in JPanel which is added to another JPanel

When adding a JPanel that has graphics to a JFrame, it's working fine. But when I try to add a JPanel in which I have added another JPanel with graphics, its not showing in the JFrame. Please see code below
package sample;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame{
public static void main(String[] args) {
new Main();
}
public Main(){
setTitle("Sample");
setVisible(true);
setSize(500,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(new SamplePanel2());
}
}
class SamplePanel2 extends JPanel{
public SamplePanel2(){
add(new JButton("Hi"));
add(new SamplePanel());
}
}
class SamplePanel extends JPanel {
public SamplePanel(){
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("HHHHHHHHHHHH", 100, 100);
}
}
Please do watch the constructor of the Main Class, make this your habbit to follow the sequence as shown in this example. First add components to the JFrame then only make calls like pack(), setSize() or setVisible(...), not before that.
Always make it your habbit, that whenever you override paintcomponent() method, override getPreferredSize() method as well.
And always put calls like pack()/setVisible(...) inside the EDT - Event Dispatch Thread. Please read Concurrency in Swing, for more detail on the topic.
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame{
public static void main(String[] args) {
new Main();
}
public Main(){
setTitle("Sample");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setContentPane(new SamplePanel2());
pack();
setVisible(true);
}
}
class SamplePanel2 extends JPanel{
public SamplePanel2(){
add(new JButton("Hi"));
add(new SamplePanel());
}
}
class SamplePanel extends JPanel {
public SamplePanel(){
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(300, 300));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("HHHHHHHHHHHH", 100, 100);
}
}

Categories

Resources