graphics drawxxx method does not work - java

I am new to graphics.
I got this code from open source.It should paint String "HEeelo" on jframe,but it does not.Can anyone explain why it is not working properly and the principle of paint method?Why should it edit JFrame as it is just method which is not even called from main?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import javax.swing.JFrame;
public class view extends JFrame{
public view(){
this.setSize(new Dimension(250, 250));
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g){
g.drawString("heello", 10, 10);
}
public static void main(String []args){
new view();
}
}

Get rid of that tutorial, that is not the way to do painting.
First the basic problems are that you should always invoke super.paint(...) when overriding a method. Secondly the text won't show because it is being painted under the title bar. You need to increase the y offset:
super.paint(g);
g.drawString("heello", 10, 40);
and the principle of paint method
Read the section from the Swing tutorial on Custom Painting for the proper way to do this. Basically you override the paintComponent() method of a JPanel and then add the panel to the frame. You should not do custom painting on a frame directly.

Related

How to draw shape inside of JPanel that is inside JFrame

I have issue with drawing shapes inside of JPanel that I already added using Netbeans GUI. Now, I have no idea where to add code for drawing a circle inside of that JPanel and how to insert and call it in the JPanel that is sitting empty now, waiting for this shape to be drawn. I already set up destination JPanel to be Flow layout.
Netbeans Designer created a big class in which I have entire frame with this JPanel, and I want to keep it inside of it as I can't really add it any other way because Designer doesn't let me change main initComponents method in which all components are sitting now. I have been reading tutorials and previous posts but noone really encountered this using Netbeans Designer.
SO can someone just help me with adding proper method in this frame class and how to call it from JPanel I want to draw in. JPanel is 50x50 pixels.
So as per #Abra, I changed some code:
so I made a new Circle Class, adjusted it a bit as I don't want to create a new frame but put this in JPanel.
public class Circle extends JPanel {
Color color;
public void circle(Color color) {
this.color = color;
setPreferredSize(new Dimension (30,30));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(0, 0, r, r);
g.setColor(color);
}
private void showGUI() {
JPanel panel = new JPanel();
panel.add(this, FlowLayout.CENTER);
panel.setVisible(true);
}
}
Then I opened JPanel in Designer, and added code to run it, in initComponents method like this:
circlePanel.setPreferredSize(new java.awt.Dimension(40, 40));
new Circle().showGUI();
PanelDS.add(circlePanel);
circlePanel is destination for this drawing and is inside PanelDS itself. It doesn't work this way tho, but Netbeans shows no errors in code. Additionally, how can I forward color to circle class.
In order to draw on a JPanel you need to override the paintComponent() method of JPanel. In order to override the method, you need to create a class that extends JPanel. I don't think that there exists a GUI designer that can generate the required code for you. So you have to write the code of the class that extends JPanel.
Here is a minimal example. It displays a blue circle.
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.WindowConstants;
public class Drawing2 extends JPanel {
private JFrame frame;
public Drawing2() {
setPreferredSize(new Dimension(100, 100));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillOval(25, 25, 50, 50);
}
private void showGui() {
frame = new JFrame("Drawing");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(this, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
new Drawing2().showGui();
}
}
Here's what you should see when you run the above code.

How would I draw on a JPanel to then be shown on a JFrame?

I've tried to research how Java's 2D rendering works, but I could never understand it. Here is the code in my main class:
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main{
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setSize(new Dimension(500,500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("JFrame testing");
frame.setVisible(true);
Frame panel = new Frame();
frame.add(panel);
}
}
And then here is for the JPanel class:
import java.awt.Graphics;
import javax.swing.JPanel;
public class Frame extends JPanel{
private static final long serialVersionUID = 1L;
public Frame() {
Graphics g = this.getGraphics();
g.drawRect(0, 0, 100, 100);
this.paintComponent(g);
}
}
I am also getting this exception, but I'm not sure what it means:
Exception in thread "main" java.lang.NullPointerException
at Frame.<init>(Frame.java:10)
at Main.main(Main.java:18)
I'm basically just trying to draw a rectangle onto a panel to be shown on the frame I've created. I've heard about the paintComponent method, but I also don't fully understand that.
You should Never use getGraphics() of a Component.
Try below code
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(0, 0, 100, 100);
//this.paintComponent(g);
}
Edit
"why is super.paintComponent(g); called again inside the method?"
The documentation of paintComponent says it pretty well:
if you do not invoker super's implementation you must honor the opaque
property, that is if this component is opaque, you must completely
fill in the background in a non-opaque color. If you do not honor the
opaque property you will likely see visual artifacts.

Image drawing on a Java component

I'm trying to create a simple application that draws graphics...
package Tests.Drawing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.EtchedBorder;
public class DrawingTest extends JFrame
{
private Canvas drwArea;
private JButton btnClear;
public static void main(String[] args)
{
DrawingTest StartForm = new DrawingTest();
StartForm.setVisible(true);
}
public DrawingTest()
{
//Window...
this.setTitle("Drawing objects test00");
this.setBounds(0,0,510,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
//Drawing area...
drwArea = new Canvas();
drwArea.setBounds(0, 0, 400, 450);
drwArea.setBackground(Color.WHITE);
drwArea.setOpaque(true);
drwArea.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
drwArea.addMouseMotionListener(new MouseMotionAdapter()
{
#Override
public void mouseDragged(MouseEvent e)
{
//Write code to paint on the image...
}
});
this.getContentPane().add(drwArea);
//Clear button...
btnClear = new JButton("Clear");
btnClear.setBounds(410,50,70,30);
btnClear.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//Write code to clear the image...
}
});
this.getContentPane().add(btnClear);
}
private class Canvas extends JLabel
{
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
//The idea of overriding this method is
//achieving persistence...
}
}
}
I have seen that the typical component to draw on is a Jlabel (Is there anyone better by the way?). Using the method “getGraphics” I can use an object that has several methods to paint on the component. My problem is that instead of painting directly on the JLabel, I would like to paint on an image (in memory) and once the painting has finished, send the result to the JLabel. How can I do this? I'm a bit lost...
Thanks in advance.
I would like to paint on an image (in memory)
I suggest that you then create a BufferedImage object of the desired size, get its Graphics2D object by calling createGraphics() on it, and draw on it using this Graphics2D object.
and once the painting has finished, send the result to the JLabel
Then create an ImageIcon out of the BufferedImage above by simply calling
Icon myIcon = new ImageIcon(myBufferedImage);
and then setting the JLabel's icon via myLabel.setIcon(myIcon);
Also you could draw to a BufferedImage that is being displayed within a JPanel's paintComponent method, and this may be an even better way to go if you want to update the image while the program is running. For more on this, please have a look at some of these examples.
Other comments:
Don't draw with a Graphics object obtained by calling getGraphics() on a component. This will return a Graphics object that is short lived, risking disappearing graphics or worse, a NullPointerException. Instead, draw in the JPanel's paintComponent(...) method either directly, or indirectly by drawing on a BufferedImage (yes, you can get its Graphics object via getGraphics()) and then drawing the BufferedImage to the GUI within the paintComponent method.
While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.

JFrame not displaying all the content? Have to resize to show the content

I'm trying to build a simple GUI interface. I have added a background image to the JPanel using the paintComponent method.
The problem is when the output is built it shows only a small window as follows:
I have to resize the output window to show the full image. How can I make the image fit the window?
Here is my new source code:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class test extends JFrame {
public test(){
super("Staff Management");
this.setContentPane(new staff());
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.pack();
}
public class staff extends JPanel{
private ImageIcon i;
public staff() {
i = new ImageIcon("D:\\staff-directory.jpg");
}
#Override
public Dimension getPreferredSize() {
return new Dimension(i.getIconWidth(),i.getIconHeight());
}
public void paintComponent(Graphics g){
super.paintComponent(g);
i.paintIcon(this,g,0,0);
}
}
}
It is just that almost all the answers on this website says to use custom painting of JPanel so I spent a day learning how to do this..
These answers usually suggest you just draw the image using the Graphics.drawImage(...) method. Even the answers you got in your last question suggest this, so I have no idea why you would now try to paint an Icon. There is no reason to create an Icon to hold the image.
if you could show me how to do this with JLabel and Icon that would be a great help
There is no trick. It is just like using a JPanel:
JLabel label = new JLabel( ... );
label.setLayout( new FlowLayout() );
label.add( new JButton("one") );
label.add( new JButton("two") );
Read the Swing tutorial on How to Use Icons if you don't know how to add an Icon to a JLabel.
You even got this advice in your question here: https://stackoverflow.com/a/29091847/131872, so why are you asking this question again?
When you paint component you need to override getPreferedSize() method to define size of your custom component. You can change your class like next:
public class staff extends JPanel{
private ImageIcon i;
public staff() {
i = new ImageIcon("d:\\staff.jpg");
}
#Override
public Dimension getPreferredSize() {
return new Dimension(i.getIconWidth(),i.getIconHeight());
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
i.paintIcon(this, g, 0, 0);
}
}
Also use just pack() instead of this.setSize(894,553);.

JPanel won't display

I got a class that's supposed to launch a game (with main()), and the game's opening screen. The class with main() (named Starter), that extends JFrame, creates a new OpeningScreen class (extending JPanel), and adds it to the JFrame.
For some reason, the OpeningScreen won't be added to the JFrame. Code:
Starter class:
import javax.swing.*;
import java.awt.*;
public class Starter extends JFrame {
public Starter(){
setSize(500,500);
setResizable(false);
setTitle("Ping-Pong Battle");
setDefaultCloseOperation(EXIT_ON_CLOSE);
OpeningScreen openingS = new OpeningScreen();
add(openingS);
setVisible(true);
}
public static void main(String[]args){
Starter starter = new Starter();
}
}
OpeningScreen class:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class OpeningScreen extends JPanel {
public OpeningScreen(){
setBackground(Color.BLACK);
setFocusable(true);
setVisible(true);
}
public void paint(Graphics g){
// Soon code here to be drawn.
}
public void startGame(){
Board board = new Board();
}
}
What's the problem? Thanks
EDIT: The constructor of OpeningScreen does run, but doesn't paint the background black. Also, trying to draw things in paint() doesn't work.
Your problem arises from overriding paint in your OpeningScreen class. The background is not drawn because you never draw it! Call super.paint(g) to fix this.
However, it is generally recommended to use paintComponent() instead of paint(). Just move your code to paintComponent.
This method correctly draws a black background a red square:
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.fillRect(100, 100, 100, 100);
}
I think because you override paint() the background doesn't get painted, so it appears like the Panel isn't added. Commenting out the paint method results in the Window being black for me.
Also, drawing in the paint method works for me, maybe your color is set to black so it doesn't show on the black background ? Try g.setColor(Color.white) before drawing.

Categories