public void paint(Graphics g){
g.setColor(Color.red);
g.drawString("hello",50,50);
}
the background of the frame looks strange and transparent.
This problem only happens when I draw a string, but when I draw a rectangle or any another shape, the frame looks good.
this is the code:
import javax.swing.*;
import java.awt.*;
public class B extends JFrame {
public B() {
this.setTitle("programme");
this.setSize(400, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.setVisible(true);
}
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawString("hello", 50, 50);
}
}
this is the result:
Thank you for helping .
I have found the answer.
The problem happened because I didn't pass the object (g) to the constructor in paint method
This is the whole code :
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JFrame;
class B extends JFrame {
public B() {
this.setTitle("programme");
this.setSize(400,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
// I have added the previous line and it solved the problem
g.setColor(Color.red);
g.drawString("hello", 50, 50);
}
}
public class main {
public static void main(String[] args) {
B obj = new B();
}
}
Anyway thank you for helping.
strange, at my place everythings works fine.
Try in constructor use:
super("programme");
instead setTitle("programme");
if doesn't work add
setBackground(Color.lightGray);
in constructor.
Anyway, when you want to paint String you should use JLabel class.
Related
So I am trying to create a simple program that prints out a rectangle but I am having this problem and I don't know how to fix it. Here is my code:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
public class GraphicsEditor extends JPanel{
public void drawShape(Graphics g) {
super.drawShape(g);
g.setColor(Color.BLUE);
g.drawRect(100, 100, 120, 150);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
GraphicsEditor ga = new GraphicsEditor();
frame.setSize(1280, 720);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(ga);
}
}
The error is when I am trying to add the super in here:
public void drawShape(Graphics g) {
super.drawShape(g);
g.setColor(Color.BLUE);
g.drawRect(100, 100, 120, 150);
}
A JPanel has no drawShape(Graphics) method, so calling the 'super' method makes no sense. When you think you're overriding a method, be sure to add the #Override notation to get a compiler warning when the method is incorrectly spelled, uses the wrong arguments, or is just entirely non-existent (as is the case here).
The correct way to go about this is to override the paintComponent method, call the (existing) super method, then immediately call the drawShape method with the Graphics instance provided to the paintComponent method.
This is the result when the GUI is shrunk down:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
public class GraphicsEditor extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawShape(g);
}
// #Override // does NOT override an existing method!
public void drawShape(Graphics g) {
//super.drawShape(g);
g.setColor(Color.BLUE);
g.drawRect(100, 100, 120, 150);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
GraphicsEditor ga = new GraphicsEditor();
frame.setSize(280, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(ga);
}
}
I have to draw an archery target with two black lines in the innermost circle that forms a cross, but every time i adjust the lines so that the lines are closer to the centre it goes behind the image instead of appearing on top. How can I stop this? Does it need to have a separate set of instructions entirely?
This is my code:
package sumshapes;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.*;
public class SumShapes extends JFrame
implements ActionListener {
private JPanel panel;
public void paint(Graphics g)
{
g.setColor(Color.BLACK);
g.drawLine(250, 200, 250, 200);
g.drawOval(140,90,200,200);
g.setColor(Color.BLACK);
g.fillOval(140,90,200,200);
g.drawOval(162,109,155,155);
g.setColor(Color.BLUE);
g.fillOval(162,109,155,155);
g.drawOval(183,129,112,112);
g.setColor(Color.RED);
g.fillOval(183, 129, 112, 112);
g.drawOval(210,153,60,60);
g.setColor(Color.YELLOW);
g.fillOval(210, 153, 60, 60);
g.setColor(Color.BLACK);
}
public static void main(String[] args) {
SumShapes frame = new SumShapes();
frame.setSize(500,400);
frame.setBackground(Color.yellow);
frame.createGUI();
frame.setVisible(true);
}
private void createGUI(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout (new FlowLayout());
}
public void actionPerformed(ActionEvent event) {
Graphics paper = panel.getGraphics();
paper.drawLine(20,80,120,80);
}
}
All your drawing should go into the paintComponent method of a lightweight component, such as a JPanel.
There should never be a need to call getGraphics. If you wish to change the drawing upon a particular action you should a) program the logic into paintComponent b) alter the logic in the Action c) call repaint on the Component
For example:
private JPanel panel = new JPanel(){
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);//call parent method first thing
//paint here
}
#Override
public Dimension getPreferredSize(){//provided so you can size this component as necessary
return new Dimension(500,400);
}
};
....
frame.add(panel);
frame.pack();
As an aside, I'd recommend placing all calls to to Swing components on the EDT - this means wrapping your Swing calls in the main method with SwingUtilities. eg
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable(){
#Override
public void run() {
SumShapes frame = new SumShapes();
....
}
});
}
I'm new to programming and I can't seem to sort this problem: how can I make the frame of my app change? It's a Minesweeper game. The program logic is good, events are working, but the frame itself isn't repainting itself... I did not have this kind of problem with applets.. how can I make this work?
public void paint(Graphics g) {
Graphics2D g2=(Graphics2D)g;
_Main.toPaint(g2);
}
public void update(Graphics g) {
Graphics offgc;
Image offScreen=null;
Dimension d=size();
offScreen=createImage(d.height, d.width);
offgc=offScreen.getGraphics();
offgc.setColor(getBackground());
offgc.fillRect(0, 0, d.width, d.height);
offgc.setColor(getForeground());
paint(offgc);
g.drawImage(offScreen,0,0,this);
}
Seems you draw your graphics wrong. For custom paintings you need to use paintComponent(...) method of JComponent, for example of JPanel, instead of paint() method and custom update(). For updating your component graphics just call repaint() method.
Here is simple example with drawing for you,try and examine that:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JPanel{
private Random rand = new Random();
public static void main(String... s){
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Example example;
f.add(example = new Example());
JButton b = new JButton("repaint");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
example.repaint();
}
});
f.add(b, BorderLayout.SOUTH);
f.setSize(200,200);
f.setVisible(true);
}
public Example(){
setBackground(Color.WHITE);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
for(int i =0; i<10;i++){
int nextInt = rand.nextInt(getHeight()-10);
int nextInt2 = rand.nextInt(getWidth()-10);
g.fillRect(nextInt2, nextInt, 10, 10);
}
}
}
Also read recommendations of Andrew Thompson.
Try using the JFrame class. Let's say your JFrame is called frame. Try frame.pack(), then frame.repaint(). The only problem with this is that I don't know how to make the frame.repaint() method invoke itself mid-Thread; it wants to wait until the Thread is terminated.
I tried to override method paintComponent in inner class JPanel and paint some picture. But if I load image in the constructor, method paintComponent is not calling. If load image in main class, everythig is fine. What is it? Here's the code, that does'nt work
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
JFrame window;
//Image image=new ImageIcon("D://domik.png").getImage();
class JPanelExt extends JPanel {
Image image;
public JPanelExt (){
image=new ImageIcon("D://domik.png").getImage();
System.out.println("constructor");
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("paint");
g.drawImage(image, 0, 0, this);
g.drawRect(0, 400, 100, 100);
}
}
public Main(){
window=new JFrame("Flowers");
window.setSize(430, 480);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanelExt flower1 =new JPanelExt();
flower1.setBounds(100, 100, 200, 200);
flower1.setToolTipText("House");
window.setLayout(null);
window.add(flower1);
}
public static void main(String[] args) {
Main main=new Main();
}
}
And sysout writes only "constructor"
But if I change code this way
public class Main {
JFrame window;
Image image=new ImageIcon("D://domik.png").getImage();
class JPanelExt extends JPanel {
//Image image;
public JPanelExt (){
//image=new ImageIcon("D://domik.png").getImage();
System.out.println("constructor");
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("paint");
g.drawImage(image, 0, 0, this);
g.drawRect(0, 400, 100, 100);
}
And sysout writes "constructor","paint"
I can't understand this ))
Your "problem" is the order of statements in the Main constructor.
First you are constructing a new frame. Second, you set it visible. At this point it is painted and also calls the paint methods on its associated panels. Also at this point, there is no associated panel. Third, you construct a new JPanelExt and add it to the frame. This will not cause the frame to be repainted.
Put the call
window.setVisible(true);
at the end of the construction process. Then you will see your image.
I have a JFrame created with GUI builder of Netbeans, which contains a JPanel only. I have created a method getPanel for getting a reference to this JPanel:
public class ShowDrawings extends JFrame {
public ShowDrawings() {
initComponents();
}
public JPanel getPanel(){
return panel;
}
private JPanel panel;
}
In my main function I am doing:
public class Main {
public static void main(String[] args){
ShowDrawings sd = new ShowDrawings();
sd.setSize(800, 600);
Graphics g = sd.getPanel().getGraphics();
g.setColor(Color.BLACK);
g.drawOval(400, 300, 50, 50);
sd.getPanel().paint(g);
sd.repaint();
sd.setVisible(true);
}
}
But it does not draw anything. Please help me.
I have looked some related questions but they are all suggesting extending JPanel and overriding its paint method. But I did not want to do that way.
Thanks.
I have looked some related questions but they are all suggesting
extending JPanel and overriding its paint method. But I did not want
to do that way
You should not override JPanel paint() method, rather paintComponent(..). This is best practice and should be done if you want code that will not produce anomalies. Also doing it in your current approach (as you have seen) makes creating persistent drawings a lot harder as they are wiped away on repaint()
Rather extend JPanel and override paintComponent(Graphics g) not forgetting to call super.paintComponent(g) as first call in overridden paintComponent(..) method. Also dont forget to override getPreferredSize() of JPanel so that we can return correct dimensions and pack() may be called on JFrame (+1 to #mKorbels comment):
Here is some example code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
initComponents();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel testPanel = new JPanel() {
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
Graphics2D g2d = (Graphics2D) grphcs;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GREEN);
//g2d.drawOval(10,10,100,100);//I like fill :P
g2d.fillOval(10,10,100,100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
};
frame.add(testPanel);
frame.pack();
frame.setVisible(true);
}
}
The first time you repaint() your ShowDrawings sd frame anything you've painted like this (sd.getPanel().getGraphics().drawOval(...)) would be erased by the original JPanel#paintComponent() method.
As Andrew Thompson has written:
Do not use Component.getGraphics(). Instead, subclass and override the paint() (AWT), or paintComponent() (Swing) method.
Component.getGraphics() simply can't work. Java uses a callback mechanism for drawing graphics. You are not supposed to "push" graphics information into a component using getGraphics(). Instead you are supposed to wait until Java calls your paint()/paintComponent() method. At that moment you are supposed to provide the Component with the drawings you would like to do.
If you're just checking/debugging something you could even do something like this:
class Test {
private JPanel panel = new JPanel() {
public void paintComponent(Graphics g) {
g.setColor(Color.BLACK);
g.drawOval(400, 300, 50, 50);
}
};
}