PaintComponent don't seem to get call or to show - java

My problem is really simple : I have this little program, and it just don't show the red box I'm trying to make :
Main
public class Main {
public static void main(String[] args) {
Affichage a = new Affichage();
a.setVisible(true);
}
}
Affichage :
import java.awt.*;
import javax.swing.*;
public class Affichage extends Frame{
public Affichage(){
setTitle("Exo 1 : Galerie");
setSize(1120,560);
Graphique graph = new Graphique();
this.add(graph);
}
}
Graphique :
import javax.swing.*;
import java.awt.*;
public class Graphique extends JComponent {
#Override
public void paintComponents(Graphics g) {
super.paintComponents(g);
Graphics pinceau = g.create();
pinceau.setColor(Color.RED);
pinceau.fillRect(100, 100, 200, 200);
System.out.println("test");
}
}
I bet it's ridicule but I can't find what it is, help me.
PS : yes the test don't get print too

Actually, don't extend JFrame as it is bad practice. Just make an instance of it. To paint, extend JPanel and override paintComponent.
JFrame f = new JFrame();
f.add(new MyPanel());
class MyPanel extends JPanel {
// other stuff
public void paintComponent(Graphics g) {
super.paintComponent(g);
// painting stuff.
}
}
And remember not to mix Swing and AWT components.

You are adding a Swing component (javax.swing.JComponent) to an AWT frame (java.awt.Frame). Noone will call the paintComponents() method, that's why you don't get any output or result. Extend from javax.swing.JFrame instead, so you have a Swing frame with a Swing component.

Related

why wont my background change color?

I was working on this lab in class and when I tried changing the background color it would stay at its default of white can someone please explain where I my programming went wrong.
import javax.swing.*;
import java.awt.*;
public class DemoPoly extends JFrame {
// constructor
public DemoPoly() {
// defines Frame characteristics
int size = 300;
setSize(size,size);
setTitle("a random window");
getContentPane().setBackground(Color.red);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main (String[] args){
// instantiates a JFrame
// exits on close (opional)
JFrame object = new DemoPoly();
}
public void paint (Graphics g){
// This provides the Graphics object g, where
// you are going to use you graphics primitive
// to paint on the content pane of the frame.
int[] arr = {0,100,100,0};
int[] yarr = {0,0,100,100};
Square object = new Square(arr,yarr,Color.red);
AbstractPolygon randSquare = new Square(arr, yarr, Color.red);
}
I see a couple of problems in your code:
Extending JFrame is like saying your class is a JFrame, JFrame is a rigid container, instead create your GUI based on JPanels. See Java Swing extends JFrame vs calling it inside of class for more information.
You're breaking the paint chain by removing the super.paint(g) call on the paint(...) method. When changing your GUI to extend JPanel instead of JFrame you should use the paintComponent(...) method instead. Take the Lesson: Performing Custom Painting in Swing.
You forgot to add #Override notation on the paint(...) method.
You're not placing your program on the Event Dispatch Thread (EDT) which could cause threading issues.
You can solve this by changing your main() method like this:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//Your constructor here
}
});
}
Instead of setting the JFrame size, override the getPreferredSize() method and call pack(). See Should I setPreferred|Maximum|MiniumSize in Java Swing?. The general consensus says yes.
Your problem gets solved by adding
super.paint(g);
on the paint(...) method:
#Override
public void paint(Graphics g) {
super.paint(g); //Never remove this
//Your code goes here
}
With all the above recommendations taken into account, your code should look like this now:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class DemoPoly {
private JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new DemoPoly().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
CustomPanel cp = new CustomPanel();
cp.setBackground(Color.RED);
frame.add(cp);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
class CustomPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
Which produces this output (and is the same output that you'll get with your current code but better because it gives you more control over your components)
I'm don't understand your question. But here is code for change your background to RED;
public class DemoPoly extends JFrame {
public DemoPoly() {
// defines Frame characteristics
int size = 300;
setSize(size, size);
setTitle("a random window");
//change background here
getContentPane().setBackground(Color.red);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
// instantiates a JFrame
// exits on close (opional)
JFrame object = new DemoPoly();
}
}
Your code is well. Maybe use #override in your paint method.

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.

how to Combine MouseMotionListener and JPanel in java

I searched all over the Internet but could not find out why the circle is appears to be distorted beyond the middle of the JFrame(sorry,no image because i needed 10 reputation to post images).
I checked my code but found no errors.I'm a newbie to java GUI programming .
This is my code so far:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class test1 extends JPanel implements MouseMotionListener
{
private static final long serialVersionUID = -2068330714634802982L;
public int Mousex,Mousey;
public void init()
{
addMouseMotionListener(this);
}
public void mouseMoved(MouseEvent e)
{
Mousex=e.getX();
Mousey=e.getY();
repaint();
}
public void mouseDragged(MouseEvent e){}
public void paintComponent(Graphics g)
{
Graphics2D g2=(Graphics2D)g;
g2.setColor(Color.GREEN);
g2.fillOval(Mousex,Mousey,50,50);
}
public static void main(String[] args)
{
test1 t=new test1();
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1305,650);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(t);
frame.setResizable(true);
frame.setVisible(true);
}
}
You need to call
t.init();
to register the MouseMotionListener. Also super.paintComponent(g); in the needs to be invoked in the paintComponent method to repaint the parent container otherwise the last rectangle wont be clearly visible.
You are never calling init() on your panel so you don't add the MouseMotionListener to the panel. Try adding
t.init();
after creating your panel object. Alternatively, add a constructor to your class that adds the MouseMotionListener instead, so it's adden right when you create an object of the class:
public test1 () {
addMouseMotionListener(this);
}

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.

JComboBox hidden behind awt Canvas

Yes, I am mixing awt and swing components, but maybe there is an easy fix because I dont know Java all that well.
My canvas object overrides paint and update:
package demo;
import java.awt.*;
public class rectangle extends Canvas {
public rectangle() {
this.setSize(500,300);
this.setVisible(true);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.YELLOW);
g2.fill3DRect(0, 0, 500, 300, true);
}
public void update(Graphics g) { paint(g); }
}
When my JComboBox opens over top of this it doesnt paint on top of it. As an example, here is a JFrame that demonstrates what i'm talking about:
package demo;
import javax.swing.*;
import java.util.*;
import java.awt.*;
public class ASframe extends JFrame {
public ASframe() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
ArrayList listNames = new ArrayList();
listNames.add("One");
listNames.add("Two");
listNames.add("Three");
listNames.add("Four");
rectangle r = new rectangle();
JComboBox listBox = new JComboBox(listNames.toArray());
listBox.setVisible(true);
JPanel listPane = new JPanel();
listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
listPane.add(listBox);
listPane.add(r);
this.setResizable(false);
this.add(listPane);
this.pack();
}
public static void main(String arg[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ASframe().setVisible(true);
}
});
}
}
Whats really interesting is that if the rectangle is smaller then the JComboBox, no issues at all. So, change the rectangle to 300x20 and it works as expected.
Thanks in advance.
Try telling Swing use the heavyweight component and see if that works.
JComboBox listBox = new JComboBox(listNames.toArray());
listBox.setVisible(true);
// additional line below
listBox.setLightWeightPopupEnabled(false); // use heavyweight component

Categories