Drawing with functions on JFrame or JPanel java - java

I wanted to know if it is possible to use/make a function in another Class to draw an image/oval and then call it in the paint public void in our main Class.
If I have
public class Trydraw{
public void drawrcircle(Graphics g){
g.setColor(Color.RED);
g.drawOval(0, 0, 20,20);
g.fillOval(0,0,20,20);
}
}
And then call it here this way
import java.awt.GridLayout;
import javax.swing.*;
import java.awt.*;
public class Display extends JPanel{
public static void main(String[]haha){
JFrame frame = new JFrame();
frame.setSize(800, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void paint(Graphics g){
super.paint(g);
Trydraw l = new Trydraw();
l.drawrcircle(g);
}
}
Thanks for your future help.

Yes you can, if I get your question correctly.
Your sample code works for me if I add
frame.add(new Display());
to the end of your
public static void main(String[] haha)
method.
With your snippet the paint(g) method will never be called, because it will be executed with the initialization of the JPanel which will be initialized with the initialization the Display class (because of inheritance).
You probably want to create an instance of Display, which automatically initializes the JPanel with the overridden paint(g) method, thus the new Operator.
As the constructor of a JPanel returns a JPanel, the constructor of Display returns a type of JPanel as well, which contains the red circle. This JPanel needs to be added with the add method to your original JFrame.

Related

Drawing to a GUI From the main using another class In Java

I'm a beginner programmer, so I don't know all the vocab, but I understand some of the basics of java.
So I'm trying to Draw in a GUI from the main using another class. I know I'm not being very specific but here's my code, and I'll try to explain what I'm trying to do.
This is my main
import javax.swing.*;
import java.awt.*;
public class ThisMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame theGUI = new JFrame();
theGUI.setTitle("GUI Program");
theGUI.setSize(600, 400);
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ColorPanel panel = new ColorPanel(Color.white);
Container pane = theGUI.getContentPane();
pane.add(panel);
theGUI.setVisible(true);
}
}
This is my other class
import javax.swing.*;
import java.awt.*;
public class ColorPanel extends JPanel {
public ColorPanel(Color backColor){
setBackground(backColor);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
}
}
I'm trying to use the line
ColorPanel panel = new ColorPanel(Color.white);
Or something like it to use things like
drawRect();
In the main and have it draw in the GUI.
This is the code I used that i think came closest to working
import javax.swing.*;
import java.awt.*;
public class ThisMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame theGUI = new JFrame();
theGUI.setTitle("GUI Program");
theGUI.setSize(600, 400);
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//I'm trying to draw a string in the JFrame using ColorPanel but i'm Trying to do it from the main
ColorPanel panel = new ColorPanel(){
public void paintComponent(Graphics g){
super.paintComponent(g);
//This is the line I need to work using the ColorPanel in anyway
g.drawString("Hello world!", 20, 20);
};
Container pane = theGUI.getContentPane();
//The errors occur here
pane.add(panel);
theGUI.setVisible(true);
//and on these brackets
}
}
I'm not really sure what exactly you're trying to do (you haven't replied to my comment to your question for clarification), but I would:
Give your ColorPanel a List<Shape>
Give it a public void addShape(Shape s) method that allows outside classes to insert shapes into this List, and then calls repaint()
And in the ColorPanel's paintComponent method, iterate through the List, painting each Shape item using your Graphics2D object.
Note that Shape is an interface, and so your List can hold Ellipse2D objects, Rectangle2D objects, Line2D objects, Path2D objects, and a whole host of other objects that implement the interface. Also, if you want to associate each Shape with a Color, you could store the items in a Map<Shape, Color>.
The reason why you are not able to compile is caused by this line:
ColorPanel panel = new ColorPanel(Color.white);
because the class ColorPanel is not included in the swing library so you have to code it. This code extends JPanel and includes a constructor that takes a Color parameter. The constructor runs when the panel is instantiated and sets its background color:
import javax.swing.*;
import java.awt.*;
public class ColorPanel extends JPanel {
public ColorPanel(Color backColor) {
setBackground(backColor);
}
}

Jpanel not showing in JFrame

I am writing this code so that it will add JPanels and will change the background color when clicked. The code in the class that runs the JFrame class is:
import javax.swing.*;
public class project9Driver {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Project9 w=new Project9();
w.setVisible(true);
w.setSize(900, 900);
}
}
The Project9 class is:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Project9 extends JFrame implements MouseListener{
JPanel panes[]=new JPanel[64];
public void Project9(){
JFrame mainFrame=new JFrame();
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container mainBox=mainFrame.getContentPane();
mainBox.setLayout(new GridLayout(8,8));
mainBox.addMouseListener(this);
for(int i=0;i<=63;i++){
panes[i].setBackground(Color.WHITE);
mainBox.add(panes[i]);
}
}
public void paint(Graphics g){
super.paintComponents(g);
}
public void mouseClicked(MouseEvent e) {
for(int i=0;i<=64;i++){
if(e.getSource()==panes[i]){
Random xR=new Random();
Random yR=new Random();
Random zR=new Random();
int x=xR.nextInt(255),y=yR.nextInt(255),z=zR.nextInt(255);
panes[i].setBackground(new Color(x,y,z));
}
}
}
}
Whenever I try to run the program, it comes up with an empty GUI window. What am I missing?
Project9 is a Frame, and you're creating another Frame inside of Project9 and you're not showing it, and becouse of that, just Project9 (w) is draw on screen, but it doesn't have anything.
You have to use "this" instead of another frame.
public class Project9 extends JFrame implements MouseListener{
JPanel panes[]=new JPanel[64];
public void Project9(){
//JFrame mainFrame=new JFrame(); delete this.
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container mainBox= this.getContentPane();
Three answer all point out different problems with your code.
You should start with a proper working example. The TopLevelDemo.java code from the Swing tutorial on Using Top Level Containers will show you the basics and the proper way to create GUI components.
You should not even be extending JFrame. It is important that all components are created on the Event Dispatch Thread which is why the invokeLater() code is used in the tutorial.
Use the tutorial for examples of using all Swing components. Other example will show you how to extend JPanel for a more complex GUI. You don't need to extend JFrame.
The original problem I noticed with the code is:
public void paint(Graphics g){
super.paintComponents(g);
}
Don't override the paint() method. There is no reason to do this!
The paint() method is for painting and you are not doing any custom painting.
First problem is this that you are using constructor Project9 w=new Project9();
and in class Project9 you are defining method public void Project9(){ you should remove void keyword.
public Project9(){
//JFrame mainFrame=new JFrame(); delete this.
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container mainBox= this.getContentPane();

How to make a paint class that doesn't get called twice?

I wrote a paint class, and added the jpanel to the frame, but it's getting called twice for some reason, as I put a print statement inside the graphics method, and it printed it twice. The codes below are all the codes I have in my package.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Paint extends JPanel {
static Paint paint = new Paint();
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("Hello");
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(paint);
frame.pack();
frame.setLocation(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I tried your code and paintComponent it's not called twice every time. I don't think you have the control on when the JFrame is calling pack() when you call setVisible. It may depends on how your OS manage the windows.

Creating a simple custom JComponent in Java?

I want to start building my own customized JComponent's for a project at work. I have a simple example below that should just create a ball on the screen. (I found most of it on the internet) but it does provide a decent starting point. My question is why does this code not show the ball in my form? What have I done wrong?
Also what would be all of the basic methods that SHOULD be provided for a custom JComponent?
Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class testBall {
public static void main(String[] args) {
new testBall();
}
public testBall() {
JPanel testPane = new JPanel();
testPane.setBackground(Color.white);
testPane.setLayout(new GridBagLayout());
testPane.add(new MyBall(30,30,10));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(testPane);
frame.pack();
frame.setSize(500, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyBall extends JComponent
{
private static final long serialVersionUID = 1L;
public MyBall() { }
public MyBall(int x, int y, int diameter)
{
super();
this.setLocation(x, y);
this.setSize(diameter, diameter);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(0, 0, 100, 100);
}
}
Where I could find a list of all of the methods that should be overridden in a JComponent class? (I know there are ones that should always be included in JComponent.)
If I make an instance of this component in a class and need to change the color of the circle would I just call there repaint() method from that class?
You are adding the MyBall to testPane (which has a GridBagLayout) without specifying any constraints. (That is, your call to add() has no second parameter.) The default constraints are most likely not what you want. Try using BorderLayout for your test pane, as this uses BorderLayout.CENTER as the default, which is probably reasonable in your case:
testPane.setLayout(new BorderLayout());
This causes the ball to show up for me.
As for your second question, I think your class is fine as defined. The main method you want to implement is paintComponent() as you have. Sometimes it becomes necessary to override the get min/max/preferred size methods, but it really just depends on what you want the component to do. JComponent is not abstract, so you don't have to override anything if you don't want to. It provides a lot of functionality out of the box such as keyboard focus, pluggable look-and-feel, accessibility, etc. As long as you don't want to change any of that stuff, just leave it as is. Implement paintComponent() and the various get*Size() methods and be done with it. (You just kind of have to pick through the methods in the JavaDoc to see what is appropriate to override.)
The other option is to extend a subclass of JComponent, if there as a class that does something similar to what you want to do. For example, JPanel is often a good starting point for impelmenting your own container.
You were probably looking for something more concrete than 'it depends', but right now, if all you want is to draw a ball, then simply override the methods that deal with the rendering of the JComponent (paintCompentent(), and the get*Size() methods).
As a side note, you really should be using SwingUtilities.invokeLater() to create your Swing components on the Swing thread. See the section entitled "Swing's Threading Policy" at http://docs.oracle.com/javase/6/docs/api/javax/swing/package-summary.html.
Made some tweaks around your java class, the only change i did was add your new MyBall directly to the content pane of the JFrame, try to run this and you will see a red circle on your jframe
public class TestBall {
public static void main(String[] args) {
new TestBall();
}
public TestBall() {
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.getContentPane().add(new MyBall(30,30,10));
frame.pack();
frame.setSize(500, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyBall extends JComponent
{
private static final long serialVersionUID = 1L;
public MyBall() { }
public MyBall(int x, int y, int diameter)
{
super();
this.setLocation(x, y);
this.setSize(diameter, diameter);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(0, 0, 100, 100);
}
}
Constructor: we just set location to the points, which are passed throught constuctor parameters. This is the place, in which this component will be located. The same way we set the size (width x height).
paintComponent: here we just paint some oval over passed graphics object.
The other part is just the test, which shows, that the component is correctly created and shown.

Can not draw oval on a JPanel

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);
}
};
}

Categories

Resources