Why doesnt my rectangle draw to the JFrame? - java

I'm trying to draw a rectangle in a window. The window is appearing, but not the rectangle, what am I doing wrong? Can someone just give me a simple explanation, thanks
import java.awt.Graphics;
import javax.swing.JFrame;
public class Moving{
public static void main (String[]args) {
Main();
drawShape(null);
}
public static void Main () {
JFrame frame= new JFrame () ;
frame.setVisible(true);
frame.setSize(400, 400);
}
public static void drawShape(Graphics g) {
g.drawRect(0, 0, 100, 100);
}
}

First off, there isn't much point to having 2 main methods, so it would be best to combine them. Second, you need a Graphics object in order to draw and you're passing null. What do you think will happen with (null graphic).draw()? You need to pass the graphic your frame is using.
public static void main (String[]args) {
JFrame frame= new JFrame ();
frame.setSize(400, 400);
Graphics g = frame.getGraphics();
drawShape(g);
frame.setVisible(true);
}

Related

paint() in java with no display

import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
class game extends JFrame {
public game(){ //this is constructor
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(500,500);
frame.setTitle("Hello world");
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Line2D line = new Line2D.Double(60,90,150,100);
g2.draw(line);
}
public static void main(String args[]) {
game l = new game();
}
}
The above code is compiling in java but on running the code it only displays the frame and its title, but does not include any of the lines being drawn using the Graphics2D and Line2D, what is the mistake that is being made??? The frame being displayed does not show any content, why is that???
First, you are creating and displaying a JFrame which is not an instance of game, so there is no chance that it paints what you have in the paint method of game .
You usually don't want to create a subclass of JFrame for custom painting anyway, just create a subclass of JPanel, and set it as the content pane of the frame.
Also don't override paint, but paintComponent, which is the method responsible for painting the current component.
You should also call the parent method of paintComponent, to make sure that all the usual cleaning takes place correctly.
Also by convention, class names should start with an upper case letter.
One last thing, make the frame visible only once you have added all your components, or you may encounter visual glitches some day.
Putting it all together :
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
class Game extends JPanel {
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
Line2D line = new Line2D.Double(60, 90, 150, 100);
g2.draw(line);
}
public static void main(final String args[]) {
Game l = new Game();
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setTitle("Hello world");
frame.setContentPane(l);
frame.setVisible(true);
}
}
In your constructor call method of JFrame class using this keyword because you extends JFrame class in your class.
public game(){ //this is constructor
/*JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(500,500);
frame.setTitle("Hello world");*/
this.setVisible(true);
this.setSize(500,500);
this.setTitle("Hello world");
}
This solve your problem.
you dont need to create instance of JFrame class ,
modified you constructor as shown below
public game(){ //this is constructor
setVisible(true);
setSize(500,500);
setTitle("Hello world");
}

drawString not drawing text on window

I'm trying to make a test window with some text on it, when I run my code, it doesn't draw the string. I specified the color for it. Can anybody help me with this?
import javax.swing.*;
import java.awt.*;
class Main
{
public static void main(String[] args) {
DrawFrame f = new DrawFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
class DrawFrame extends JFrame
{
public DrawFrame(){
setTitle("For Aylin");
setSize(1280,720);
DrawPanel panel = new DrawPanel();
Container cp = getContentPane();
cp.add(panel);
}
}
class DrawPanel extends JPanel
{
public void paintComponents(Graphics g)
{
super.paintComponents(g);
g.setColor(Color.darkGray);
g.drawString("Hi", 100, 10);
}
}
You should override the JPanel's paintComponent method not its paintComponents method as they are for two very different purposes. The first paints the component itself (what you want) while the second gets the child components held by this parent to paint themselves.
Also remember to change the super call so that it matches, and to use the #Override annotation above the method.

Making an image show up in Java

I've been struggling to get an image to show up for some time now. Ive read a few different things, and all of them seem to have different ways of showing images. Can someone tell me what I'm doing wrong? I'm trying to make a program that uses 2 classes to make a picture show up in a frame. I guess what I don't understand still is what a Graphics object is, what a Graphics2D object is and how its different, and what method from what class do I call in order to make an image show up. Here is my code:
public class Smiley {
private BufferedImage smileyFace;
private Graphics2D renderWindow;
private Dimension smileyPosition;
private File smileyFile;
public Smiley() {
try{
smileyFile = new File("C:\\Users\\MyName\\Desktop\\smiley.png");
smileyFace = ImageIO.read(smileyFile);
}
catch (Exception e){
System.out.println("There was an error finding or reading the file \" smiley.png.\"");
}
MainScreen.graphicPane.drawImage(smileyFace,50,50, null);
}
and the second class:
public class MainScreen extends JFrame{
public static MainScreen ms;
public static Graphics2D graphicPane;
public static void main (String[] args){
MainScreen ms = new MainScreen();
Smiley newSmiley = new Smiley();
}
public MainScreen(){
super("Main Screen Window");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
this.setSize(500,800);
this.getContentPane().setBackground(Color.black);
graphicPane = (Graphics2D) this.getContentPane().getGraphics();
}
}
the program compiles with no errors and nothing is reported back to me about not finding the file.
Your going to need some sore of paint method. For that you will require a Component to paint on. You need to learn a GUI framework, like Swing. There are clear compoents you can paint on like a JPanel. With that panel you need to override its paintComponent method.
The Graphcics object is what the component uses to actually paint the graphic onto the component.
The Graphics2D object just extends the capabilities of the Graphics object.
You should take a look at the Swing tuorial and the **Graphics toturial
To get your program running though you would do something like this
public class DrawPanel extends JPanel {
BufferedImage smileyFace;
public DrawPanel() {
try{
smileyFile = new File("C:\\Users\\MyName\\Desktop\\smiley.png");
smileyFace = ImageIO.read(smileyFile);
}
catch (Exception e){
System.out.println("There was an error finding or reading the file \" smiley.png.\"");
}
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(smileyFace,50,50, this);
}
#Override
public Dimension getPreferredSize(){
return new Dimension(500, 500);
}
}
Then you can instantiate that panel in another class, adding it to a JFrame to run it
public class Main {
public static void main(String[] args) {
SwingUtiliites.invokeLater(new Runnable(){
public void run() {
JFrame frame = new JFrame();
frame.add(new DrawPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
You are calling this in your constructor for your Smiley class.
MainScreen.graphicPane.drawImage(smileyFace,50,50, null);
If you are going to paint the image yourself you need to override paintComponent() in a component that gets added to your main screen.
Or just add the image to a JLabel that you added to the main screen.
You draw image in wrong way.
For using drawImage() you need to use that in paintComponent() method of JComponent(for example JPanel), examine next code:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.beans.Transient;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JFrame {
public Example() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Smiley());
frame.pack();
frame.setVisible(true);
}
public static void main(String args[]) {
new Example();
}
class Smiley extends JPanel{
private BufferedImage smileyFace;
Smiley(){
try {
File smileyFile = new File("C:\\Users\\MyName\\Desktop\\smiley.png");
smileyFace = ImageIO.read(smileyFile);
} catch (Exception e) {
System.out
.println("There was an error finding or reading the file \" smiley.png.\"");
}
}
#Override
#Transient
public Dimension getPreferredSize() {
return new Dimension(smileyFace.getWidth(),smileyFace.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(smileyFace, 0,0, this);
}
}
}
or you can add your image to JLabel and that do all for you, change Smile class like next:
class Smiley extends JPanel{
Smiley(){
ImageIcon icon = new ImageIcon("C:\\Users\\MyName\\Desktop\\smiley.png");
JLabel l = new JLabel(icon);
add(l);
}
}
ALso read more about customPaintings.

Drawing Canvas on JFrame

I'm trying to draw simple shapes with Canvas, in this class I've set the painting
public class Game extends Canvas{
//FIELDS
public int WIDTH = 1024;
public int HEIGHT = WIDTH / 16 * 9;
//METHODS
public void start(){
Dimension size = new Dimension (WIDTH, HEIGHT);
setPreferredSize(size);
paint(null);
}
public void paint(Graphics g){
g.setColor(Color.GREEN);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
g.fillOval(100, 100, 30, 30);
}
}
And in this the Window
public class MainW {
public static void main(String[] args) {
Game ga = new Game();
JFrame frame = new JFrame ();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add(ga);
frame.setVisible(true);
ga.start();
}
}
It works, but the JFrame is not adapting to the Canvas. I have to manually resize the window to see the objects. How can I pack it so that JFrame automatically encompasses the Canvas?
EDIT:
That's really weird. While frame.pack() is indeed essential, it's not enough.
What I did was change the start method and turn it into a constructor, like that:
public class Game extends Canvas{
//FIELDS
public int WIDTH = 1024;
public int HEIGHT = WIDTH / 16 * 9;
//METHODS
public void Game(){
Dimension size = new Dimension (WIDTH, HEIGHT);
setPreferredSize(size);
}
then, from the other class, Eclipse complained about calling the constructor directly(E.G. ga.Game), so I followed it's tip and changed to:
public static void main(String[] args) {
Game ga = new Game();
JFrame frame = new JFrame ();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add(ga);
frame.setVisible(true);
ga.getName();
}
This way I achieve what I have in mind but I really don't know why I can't call the constructor.
I don't know what it is you're trying to do, but you should NEVER be calling paint and especially not pass it null.
Start by taking a look at Performing Custom Painting and Painting in AWT and Swing for details about how painting works.
In order to get the window to size to you component, you need to provide it some important information.
While Window#pack is the method you are looking for, it will not help you unless you provide appropriate sizing hints.
In this case, you need to override the getPreferredSize method of you component and provide an appropriate size value. Window#pack will use this value to determine what size it needs to be in order to accommodate it.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestPaint {
public static void main(String[] args) {
new TestPaint();
}
public TestPaint() {
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 {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
g.fillOval(100, 100, 30, 30);
}
}
}
The paint chain is very important and you should avoid breaking it at all coasts. Make sure you always call super.paintXxx or be prepared for some serious weirdness
Also may want to have a read of Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
Use java.awt.Window.pack (JFrame indirectly extends Window):
Causes this Window to be sized to fit the preferred size and layouts of its subcomponents.
// ...
frame.add(ga);
frame.pack();
frame.setVisible(true);
// ...
After painting on canvas try repaint the JFrame
public static void main(String[] args) {
Game ga = new Game();
JFrame frame = new JFrame ();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add(ga);
frame.setVisible(true);
ga.start();
//repaint here
frame.repaint();
}
Also note that:
frame.pack for fixing the size issue.
frame.revalidate sometimes help when adding or removing components in runtime.

repaint() in Java [duplicate]

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Java GUI repaint() problem?
I write a Java code, but I have a trouble with GUI problem. When I add a component into JFrame object, then I call repaint() method in order to update the GUI but it doesn't work. But when I minimize or resize this frame, the GUI is updated.
Here is my code:
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(460, 500);
frame.setTitle("Circles generator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
String input = JOptionPane.showInputDialog("Enter n:");
int n = Integer.parseInt(input);
CircleComponent component = new CircleComponent(n);
frame.add(component);
component.repaint();
}
If you added JComponent to already visible Container, then you have call
frame.getContentPane().validate();
frame.getContentPane().repaint();
for example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(460, 500);
frame.setTitle("Circles generator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setVisible(true);
}
});
String input = JOptionPane.showInputDialog("Enter n:");
CustomComponents0 component = new CustomComponents0();
frame.add(component);
frame.getContentPane().validate();
frame.getContentPane().repaint();
}
static class CustomComponents0 extends JLabel {
private static final long serialVersionUID = 1L;
#Override
public Dimension getMinimumSize() {
return new Dimension(200, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
#Override
public void paintComponent(Graphics g) {
int margin = 10;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
}
}
}
Simply write :
frame.validate();
frame.repaint();
That will do .
Regards
You're doing things in the wrong order.
You need to first add all JComponents to the JFrame, and only then call pack() and then setVisible(true) on the JFrame
If you later added JComponents that could change the GUI's size you will need to call pack() again, and then repaint() on the JFrame after doing so.
You may need to call frame.repaint() as well to force the frame to actually redraw itself. I've had issues before where I tried to repaint a component and it wasn't updating what was displayed until the parent's repaint() method was called.

Categories