So I am new in java graphics and I am creating a program that will show a rectangle. But when I run my program it only show like a small box and not the rectangle. I don't really know why it is happening.
Here is my code:
import javax.swing.*;
public class GraphicsEditor{
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
Rectangle rectangle = new Rectangle();
frame.setSize(1280, 720);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(panel);
panel.add(rectangle);
}
}
This is my rectangle class:
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Rectangle extends JPanel implements Shape {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.fillRect(0, 0, 200, 130);
}
}
This is my shape interface:
import java.awt.*;
public interface Shape {
void paintComponent(Graphics g);
}
Here, try this
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class GraphicsEditor {
public static void main(String[] args) {
JFrame frame = new JFrame();
Rectangle rectangle = new Rectangle();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(rectangle);
frame.pack();
// center frame on screen
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class Rectangle extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.fillRect(0, 0, 200, 130);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
}
A couple of things.
you don't need the interface.
unlike components, just painting a picture doesn't affect the layout manager, so the panel will be reduced to it's default size with out regard to any painting.
so you need to override getPreferredSize() in your JPanel.
As the comments said, you should set the preferred size of both your panel and rectangle to your desired size, and then pack the frame, like:
panel.setPreferredSize(new Dimension(500,500));
rectangle.setPreferredSize(new Dimension(500,500));
frame.pack();
Otherwise your LayoutManager (when not specified it defaults to FlowLayout) will handle your rectangle the way it wants. So another way would be learning about Layout Managers, and using your desired one.
As a side note, I would like to make some suggestions to your code. Remember, Swing is not thread safe, so place your code inside an invokeLater() call, such as:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
Rectangle rectangle = new Rectangle();
frame.setSize(1280, 720);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setPreferredSize(new Dimension(500,500));
rectangle.setPreferredSize(new Dimension(500,500));
frame.add(panel);
panel.add(rectangle);
frame.pack();
frame.setVisible(true);
}
});
Also, calling frame.setVisible(true) should be called after adding your components.
Related
I am new to java, I wanted to make a program that draws a box on screen, everything is correct except for the paintComponent(); which is not working
import java.awt.*;
import javax.swing.*;
import java.awt.Graphics2D.*;
public class Frame extends JPanel
{
#Override //this section creates the box
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawRect(150,150,20,20);
}
public static void createWindow() //this section creates the frame
{
JFrame frame = new JFrame("Simple GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //set closing bebavior
frame.setSize(400, 400); //set the size of jframe
frame.setLocationRelativeTo(null); //center the jframe
frame.setVisible(true); //show the frame
}
//main method
public static void main(String[] args)
{
createWindow();//launch your creaWindow method
paintComponent();
}
}
You have to review the basics of Java. Your mistake in this is that you have to create an object of this class Frame and add it to the JFrame which you have created. Below is the correct code #Hh000.
import java.awt.*;
import javax.swing.*;
import java.awt.Graphics2D.*;
public class Frame extends JPanel{
#Override //this section creates the box
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawRect(150,150,20,20);
}
//main method
public static void main(String[] args){
JFrame frame = new JFrame("Simple GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //set closing bebavior
Frame frameObject = new Frame(); //Making a class object
frame.add(frameObject); //Adding the object into the JFrame
frame.setSize(400, 400); //set the size of jframe
frame.setLocationRelativeTo(null); //center the jframe
frame.setVisible(true);
}
}
I'm building a PongClone but I encounter a bug. **I think the bug is cause by JPanel.
I tried the Image instead of BufferedImage.
I tried the drawImage outside the paintComponent method.
I create to another panel and then add that panel inside a mainpanel.
Menu Class
package me.pong;
import javax.swing.*;
public class TestMenu {
JFrame frame;
public void createFrame () {
TestMain main = new TestMain ();
frame = new JFrame("TEST");
frame.setSize (800, 450);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane ().add (main.panel);
frame.setVisible (true);
}
}
MainClass
package me.pong;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class TestMain extends JPanel {
JPanel panel = new JPanel ();
BufferedImage img;
Graphics g;
public static void main (String[] args) {
TestMain testMain = new TestMain ();
TestMenu menu = new TestMenu ();
menu.createFrame ();
testMain.drawGraphics ();
}
public void drawGraphics(){
panel.add (new TestMain ());
img = new BufferedImage(800, 450, BufferedImage.TYPE_INT_RGB);
g = img.createGraphics ();
g.drawString ("TEST STRING 2", 250,250);
}
#Override
protected void paintComponent (Graphics g) {
super.paintComponent (g);
g.clearRect (0,0,800,450);
g.drawImage (img, 0,0,null);
g.setColor (Color.white);
g.drawString ("TEST STRING", 500,250);
g.setColor (Color.black);
g.drawRect (150,100,10,70);
}
}
I expect the Image fill the component but actual output is little tiny box.
Just like that
EDIT: Delete the code and added MCVE/SSCCE Code(I didn't know that). Still same. If I add the image inside the frame it's works but other way doesn't. I know I'm missing something, but I don't know what that is.
**Yes. Problem caused by JPanel but I don't know how to fix it.
The extra panel declared within the custom painted class that is a panel was not only unnecessary, but the source of problems. See further comments in code.
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class TestMain extends JPanel {
JFrame frame;
// Not needed or useful!
//JPanel panel = new JPanel();
BufferedImage img;
Graphics g;
public static void main(String[] args) {
TestMain testMain = new TestMain();
testMain.createFrame();
testMain.drawGraphics();
}
public void createFrame() {
TestMain main = new TestMain();
frame = new JFrame("TEST");
frame.setSize(400, 250);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.getContentPane().add(main.panel);
frame.getContentPane().add(main);
frame.setVisible(true);
}
public void drawGraphics() {
//panel.add(new TestMain());
add(new TestMain());
img = new BufferedImage(800, 450, BufferedImage.TYPE_INT_RGB);
g = img.createGraphics();
g.drawString("TEST STRING 2", 250, 250);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, 800, 450);
// all JComponent instances are image observers
//g.drawImage(img, 0, 0, null);
g.drawImage(img, 0, 0, this);
g.setColor(Color.WHITE);
// NEW! Otherwise invisible
g.setColor(Color.RED);
g.drawString("TEST STRING", 200, 100);
g.setColor(Color.BLACK);
g.drawRect(150, 100, 10, 70);
}
}
As an aside:
That code still has problems, but I thought it best to stick closely to fixing only the immediate problem.
The easiest way to display a BufferedImage is to show it in a JLabel via an ImageIcon.
This what I am doing but is nothing is getting displayed on Jframe window. I have not extended class JFrame to do my, is it necessary to do so for displaying objects on window.
public class testGraphics {
static JFrame workingFrame = null;
public static void main(String args[])
{
JFrame workingManager = new JFrame("Hello");
workingManager.setSize(500, 500);
workingManager.setVisible(true);
Graphics g = workingManager.getGraphics();
JPanel jp = (JPanel) workingManager.getContentPane();
workingManager.paintComponents(g);
g.fillOval(0, 0, 30, 30);
g.drawOval(0, 50, 30, 30);
g.setColor(Color.CYAN);
}
}
Do not ever call getGraphics() or explicitly call paintXxx() to do custom painting. The correct way to do custom painting is to override the paintComponent method of the panel to paint on. The overriden method will be implicitly called for you. Then add that panel to the frame. Also you should override the getPreferredSize() of the panel, so it has a preferred size, so you can just pack the frame
class PaintPanel extends JPanel {
#Override
protected paintComponent(Grapchics g) {
super.paintComponent(g);
g.drawString(....);
}
#Override
public Dimension getPreferredSize() {'
return new Dimension(300, 300);
}
}
Then add it to the frame (or if you want to set it as the content pane of the frame, do that instead)
PaintPanel panel = new PaintPaint();
frame.add(panel);
...
frame.pack();
See more at Performing Custom Painting
I made several changes to your code to get it to work properly.
I changed your main method to call the SwingUtilities invokeLater method to make sure that the Swing components were defined and used on the Event Dispatch thread.
I created a drawing JPanel. I set the color first, then drew the ovals.
I added a JFrame default close operation. You must specify a default close operation, or else your Java application will continue running after you close the JFrame.
I moved the size to the drawing panel. The frame size will be calculated when you call the JFrame pack method.
And here's the modified code:
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestGraphics implements Runnable{
private JFrame workingManager;
private JPanel drawingPanel;
#Override
public void run() {
workingManager = new JFrame("Hello");
workingManager.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawingPanel = new DrawingPanel();
workingManager.add(drawingPanel, BorderLayout.CENTER);
workingManager.pack();
workingManager.setLocationByPlatform(true);
workingManager.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new TestGraphics());
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID =
-3701718376300985046L;
public DrawingPanel() {
this.setPreferredSize(new Dimension(500, 500));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.CYAN);
g.fillOval(0, 0, 30, 30);
g.drawOval(0, 50, 30, 30);
}
}
}
The setSize() and setVisible() must be at the bottom of the method:
JFrame workingManager = new JFrame("Hello");
Graphics g = workingManager.getGraphics();
JPanel jp = (JPanel) workingManager.getContentPane();
workingManager.paintComponents(g);
g.fillOval(0, 0, 30, 30);
g.drawOval(0, 50, 30, 30);
g.setColor(Color.CYAN);
workingManager.setSize(500, 500);
workingManager.setVisible(true);
My problem is I want to draw a huge Panel but its not possible to see this panel in a small size frame so i supposed to use ScrollPane and I used it..
But by scrolling clashes occurs so i cant see any panel there .i just want to fix it
Please anyone see my code and run it and help to solve the problem
import java.awt.*;
import javax.swing.*;
public class Swing{
JFrame frame;
Panel panel;
public static void main(String [] args){
Swing a = new Swing();
a.go();
}
public void go(){
frame = new JFrame();
panel = new Panel();
panel.setPreferredSize(new Dimension(5000, 5000));
JScrollPane scroll = new JScrollPane(panel);
frame.add(scroll);
frame.pack();
frame.setVisible(true);
}
class Panel extends JPanel{
public void paintComponent(Graphics g){
Graphics2D a = (Graphics2D)g;
a.setColor(Color.RED);
a.drawLine(50, 50, 5000, 5000);
}
}
}
Thanks in advance!
Always make sure to call super.paintComponent(g); to redraw the rest of the component. Otherwise these types of painting artifacts are seen.
import java.awt.*;
import javax.swing.*;
public class Swing{
JFrame frame;
Panel panel;
public static void main(String [] args){
Swing a = new Swing();
a.go();
}
public void go(){
frame = new JFrame();
panel = new Panel();
panel.setPreferredSize(new Dimension(5000, 5000));
JScrollPane scroll = new JScrollPane(panel);
frame.add(scroll);
frame.pack();
frame.setVisible(true);
}
class Panel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g); // VERY IMPORTANT!
Graphics2D a = (Graphics2D)g;
a.setColor(Color.RED);
a.drawLine(50, 50, 5000, 5000);
}
}
}
I'm almost done with my hangman java code. I want to add a picture in the background though.(nightsky.png) How do I do this in the paint graphics method? I created a imageicon in the beginning.
public HangmanRevised() {
setSize(600,400);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
ImageIcon background = new ImageIcon("nightsky.png");
Letter = new TextField();
JLabel label = new JLabel("pick a Letter");
button = new Button("Enter");
add(label);
add(button);
add(Letter);
button.addActionListener(this);
createGame();
}
public void paint(Graphics g) {
super.paint(g);
g.drawImage(background, 0, 156, Color.green, button);
}
If you are painting the image at its actual size, there is no need to do any custom painting.
As has already been suggested you just add the Icon to a JLabel and add the label to your frame (or panel). Then if you want the image to appear at a certion position within the label, then you simply add an EmptyBorder to the label.
By overriding a JPanel, you can redo paintComponent() to paint the image and the JPanel itself should have a paint function for its children (although I haven't tested this functionality).
http://www.java2s.com/Code/Java/Swing-JFC/Panelwithbackgroundimage.htm
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImageTest {
public static void main(String[] args) {
ImagePanel panel = new ImagePanel(new ImageIcon("images/background.png").getImage());
JFrame frame = new JFrame();
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
class ImagePanel extends JPanel {
private Image img;
public ImagePanel(String img) {
this(new ImageIcon(img).getImage());
}
public ImagePanel(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}
You need to put the background somewhere, i.e.:
//add the following in the HangmanRevised() constructor (?)
button.addActionListener(this);
//To add
ImagePanel panel = new ImagePanel(background.getImage());
JFrame frame = new JFrame();
frame.getContentPane().add(panel);
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
add(frame);
//end...
createGame();
You can also construct any image you like on-the-fly using 2D Graphics, as suggested in RotatableImage.