Java: Paint Method Doesn't Run - java

I've looked at several other posts, and I have yet to find a clear answer. I don't entirely understand the paint method, which is probably my problem, but nowhere can I find a clear explanation. Can someone help me get this one working? The issue is that the paint method is not running. Everything else seems to work fine, but I do not see the oval I tell the program to render in the frame.
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
#SuppressWarnings("serial")
public class TestObject extends Component {
MouseResponder mouseListener = new MouseResponder(); // Creates a new mouse listener.
WindowResponder windowListener = new WindowResponder(); // Creates a new window listener.
Frame mainFrame = new Frame(); // Makes a new frame.
public TestObject() {
mainFrame.setSize(400,500); // Makes the new frame 400 by 500 in size.
mainFrame.setLocationRelativeTo(null); // Sets the location of the window to center it.
mainFrame.setTitle("A Test program!"); // Sets frame label.
mainFrame.setBackground(new Color(199,199,199)); // Sets the background color of the window.
mainFrame.addWindowListener(windowListener); // Adds the window listener so close works.
mainFrame.addMouseListener(mouseListener); // Adds the mouse listener to the frame.
mainFrame.setVisible(true); // Makes the new frame visible.
System.out.println("[TestObject] Window" + // Prints a console message when main window is launched.
" configured and launched.");
}
public void paint(Graphics pane) {
System.out.println("[TestObject] Painting.");
pane.setColor(Color.BLACK);
pane.drawOval(10,10,10,10);
}
}
Other Info:
MouseResponder and WindowResponder are separate functioning classes.
The TestObject class seen above is called by a main class which
creates a new TestObject. The frame displays successfully as I
specify.
Thank you for any help!
-Docithe

You are late for your homework buddy !
Take a new java file.
Create a class
Make it extend JFrame
override the paint method
put a println in it
Take a second file
put a main in it
instanciate your first class and call show
move the window around, println should print out, meaning your code in paint is executing.
That's the way to do it in OOP, and for sure in java. Read more.

paint() is responsible for rendering a component when it is visible.
At least in your code snippet, you did not add the test-component to the frame - thus, it is not displayed and not painted.
public TestObject() {
//...
mainFrame.add( this );
//...
}
This still might not work because your Test Component is 0x0 pixel.
So you also
#Override
getPreferredSize(){
return new Dimension( 20, 20 );
}

you are mixing two things here, creating a frame and creating a component. If I understand you correctly, you want to create a frame and within that frame have a custom component draw an oval.
The component is just this:
public class TestObject extends Component {
public void paint(Graphics pane) {
System.out.println("[TestObject] Painting.");
pane.setColor(Color.BLACK);
pane.drawOval(10,10,10,10);
}
}
and your main program looks more like this:
public static void main(String[] args)
{
MouseResponder mouseListener = new MouseResponder();
WindowResponder windowListener = new WindowResponder();
Frame mainFrame = new Frame();
mainFrame.setSize(400,500);
mainFrame.setLocationRelativeTo(null);
mainFrame.setTitle("A Test program!");
mainFrame.setBackground(new Color(199,199,199));
mainFrame.addWindowListener(windowListener);
mainFrame.addMouseListener(mouseListener);
mainFrame.add(new TestObject());
mainFrame.setVisible(true);
}
I am not saying this code will run, but it splits the two things in what they should be, a main program creating the frame, and a component painting an oval. I agree with Snicolas on the reading more...

Related

Java Swing panels and graphics stopped displaying

I'm new to Java Swing (and fairly new to Java in general) and I've been messing around with Swing for a while, but after making some changes my panels stopped displaying and I don't know why.
When using isDisplayable() on my JPanel object it returns false. After more investigation my program does not seem to display graphics at all.
Even a simple piece of code doesn't work for me anymore:
public class window extends JFrame {
window(){
setBounds(100,100,1200,700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(Color.black);
setVisible(true);
}
public static void main(String[] args) throws IOException{
new window();
}
I have no idea what I changed for this to happen, but all I get is a blank a completely blank window.
Any help is appreciated a lot!
See the code comments.
import java.awt.Color;
import javax.swing.*;
public class BlackWindow extends JFrame {
BlackWindow(){
setBounds(100,100,400,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// sets the frame black, not the content pane
//setBackground(Color.BLACK);
getContentPane().setBackground(Color.BLACK);
setVisible(true);
}
public static void main(String[] args) {
new BlackWindow();
}
}
This example also speaks to a few general principles we follow when using Swing's JFrame:
Don't extend the JFrame class, just use an instance of one.
Don't do anything significant to the coloring or styling of a frame, instead color (for example) a JPanel and add it to the frame.

How do I call a method which has Graphics g as its parameters?

So I am making a game and after someone wins, I want a method to run which displays "x has won" or "y has won". Now my problem is that if I make method to draw a string containing a victory message, then my IDE doesn't allow me to as I can't run a method with Graphics g as the parameters apparently.
Is there any other way to display a message on a JFrame screen?
Here is my code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;`
//nothing wrong here :P
public class Demonstration extends JFrame {
private JButton b1;
private JButton b2;
public Demonstration () {
//My constructor
JPanel panel = new JPanel();
panel.setLayout(null);
add(panel);
handler h = new handler();
b1 = new JButton("yes");
b2 = new JButton("no");
//A sub - class to handle events. Created below
b1.setBounds(34, 34, 34, 34);
//random
panel.add(b1);
b1.addActionListener(h);
b2.setBounds(56, 56, 56, 56);
// random again
panel.add(b2);
b2.addActionListener(h);
setTitle("Demonstration");
setBackground(Color.BLACK);
setDefaultCloseOperation(3);
setSize(720, 720);
setVisible(true);
}
}
That was my Panel.
public static void main (String[] args) {
new Demonstration();
}
So let us say I made the handler class later on and I want it to run a piece of code which has an if / else for which button was clicked (.getSource()) and I want to use Graphics to redesign the interface and print out victory messages, how would I do that?
Of course you can run methods that take a Graphics as a parameter. Any Swing application does so. You can do it manually, too, though in that case the question is typically how to get the right Graphics instance for drawing where you want to draw.
Sometimes what you want to do is extend some JComponent (often JPanel) and override its paintComponent(Graphics) method. The Graphics object received by that method is appropriate for drawing on that component. You then make sure an instance of that component is among the components managed by one of the application's top-level windows.
Alternatively, sometimes it may be suitable to change the data in a different component, such as the text of a JLabel or JButton, or the contents of a JTextArea.
Consider also that for displaying an announcement message of some flavor, a popup dialog might be suitable. There are various ways to construct and diaplay such a dialog, but JOptionPane provides some shortcuts that might be useful to you.
Is there any other way to display a message on a JFrame screen?
Don't try to do custom painting.
I would use a JOptionPane.
Read the section from the Swing tutorial on How to Make Dialogs for more information.
You would use the simple JOptionPane.showMessageDialog(...) method.

Java, swing opening new JFrame from another class

I have this piece of code:
public class GUI extends JFrame {
private PlaneUI planeui;
public GUI(PlaneUI planeui) {
this.planeui = planeui;
}
//We have put the code that creates the GUI inside a method
public GUI() {
start();
planeui.display();
} ...
This is just a test and I need the method "planeui.display" to work when the program starts, together with the method "start();" which already works.
public final class PlaneUI extends JFrame {
public void display() {
//Creates a new JPanel object
JPanel panelStart = new JPanel();
getContentPane().add(panelStart);
//Changing the default layout from Flowlayout to absolute
panelStart.setLayout(null);
setTitle("Reservationer"); //Sets the window title
setSize(236, 256); //Sets the default size of the window
setLocationRelativeTo(null); //Start location of the window (centered)
setDefaultCloseOperation(EXIT_ON_CLOSE); //Exits the window
}
}
I have imported the needed libraries and I feel like the problem lies in an object that isn't created correctly since I get a nullpointerexception. I tried running this planeUI class in the main method and it worked correctly. I just can't get it to work this way..
In function PlaneUI.display() add one last line setVisible(true) because your adding everything but not displaying anything
you have to add this into your display() method:
setVisible(true);
Otherwise, all you are doing is setting all the aspects of the JFrame and adding the JPanel to it. You have to make it visible afterwards.

Java running main method of other class, when JButton is pressed

I am trying to develop a JFrame which has two buttons that would let me to call the main method of other classes. The first try was to put it directly into the actionPerformed of each button, this will cause the JFrame of the other class to open but showing only the title of it and not showing any contents of the JPanel additionally freezing the program (can't even press close button, have to go into task manager or eclipse to kill it). The second try was adding a method call in actionPerformed, and adding the method will this time call the main method of other class however the same result (freeze of program).
For testing purposes I have placed the call to main method of other class, straight in this class main method which has proven to me that the frame of other class has successfully appeared, including all its JPanel contents, functionality etc.
I know I could make some kind of infinite loop in my main method to wait until a boolean is set to true, but then I though there must be some less-expensive way to get it working. So here I am asking this question to you guys.
Here is the code of the 2nd try;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Chat {
public static void main (String[] args) {
JFrame window = new JFrame("Chat Selection");
//Set the default operation when user closes the window (frame)
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set the size of the window
window.setSize(600, 400);
//Do not allow resizing of the window
window.setResizable(false);
//Set the position of the window to be in middle of the screen when program is started
window.setLocationRelativeTo(null);
//Call the setUpWindow method for setting up all the components needed in the window
window = setUpWindow(window);
//Set the window to be visible
window.setVisible(true);
}
private static JFrame setUpWindow(JFrame window) {
//Create an instance of the JPanel object
JPanel panel = new JPanel();
//Set the panel's layout manager to null
panel.setLayout(null);
//Set the bounds of the window
panel.setBounds(0, 0, 600, 400);
JButton client = new JButton("Run Client");
JButton server = new JButton("Run Server");
JLabel author = new JLabel("By xxx");
client.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//run client main
runClient();
}
});
server.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//run server main
}
});
panel.add(client);
client.setBounds(10,20,250,200);
panel.add(server);
server.setBounds(270,20,250,200);
panel.add(author);
author.setBounds(230, 350, 200, 25);
window.add(panel);
return window;
}
private static void runClient() {
String[] args1={"10"};
ClientMain.main(args1);
}
}
Only one main method is allowed per application. Honestly I am not sure what you are trying to do or think is supposed to happen when you call main on other classes. When you call main on other classes all you are doing is calling a method that happens to be called main and passing args to it. Your freezing is probably because you are not using Swing correctly:
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
The problem you're having is that Java Swing is single threaded. When you're running the main function of the other class, however you do it, the GUI won't be able to keep running until it returns. Try spawning off a new thread that calls the second main method.
private static void runClient() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
String[] args1={"10"};
ClientMain.main(args1);
}
});
}
EDIT: Updated, as per #Radiodef's suggestion. Missed at the top when you said this second class had to display things on the GUI. Definitely want to go with the invokeLater then.

Basic paintComponent not being called by repaint()?

I'm using the book Headfirst java, and I have put together a program that I thought would compile fine. But when the window is created, the background or oval isn't showing up.
import javax.swing.*;
import java.awt.*;
public class setup {
public static void main(String[] args) {
JFrame f = new JFrame();
System.out.println("Created Frame");
JPanel myJPan = new JPanel();
System.out.println("Created Panel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(300,300);
System.out.println("Set Size");
f.setLocationRelativeTo(null);
f.setContentPane(myJPan);
f.setVisible(true);
System.out.println("Made Visible");
myJPan.repaint();
}
// #Override ???
// "protected void" ??
public void paintComponent(Graphics g) {
// super.paintComponent(); ???
g.fillRect(0,0,300,300);
System.out.println("painted");
int red = (int) (Math.random()*255);
int green = (int) (Math.random()*255);
int blue = (int)(Math.random()*255);
System.out.println("Got Random Colors");
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
System.out.println("Set Random Colors");
g.fillOval(70,70,100,100);
System.out.println("Filled Oval");
}
}
See my answer to this question . It provides an example of the proper way to set up a JPanel.
Like other commenters/answerers have stated, paintComponent belongs to the JPanel class. What this means for you is that you need to create a class (let's call it MyPanel) that extends JPanel. (Note: you can either make a new .java file for this class if you are in eclipse or make it an inner class, it should work either way).
Once you have done that, simply cut the paintCOmponent method from your setup class and paste it into your new MyPanel class.
And finally, within your setup class, instead of creating a JPanel object, create a MyPanel.
Basically, this MyPanel object is your own custom JPanel object that does whatever you want it to! It's almost like magic!
On a side note (this will hopefully help you better format your code in the future), and hopefully more experience Java programmers will agree with me on this, I would also recommend that you create your own custom JFrame object as well. Only for this one, you won't override any methods other than the constructor. Instead, in your constructor for this custom JFrame, you will make all of the specifications for the window (such as your setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE and setSize(300,300) calls). This constructor is also where you will instantiate your MyPanel object (as well as any other component objects in your window) and maybe give it a few ActionListeners.
Then, in another class (such as your setup class), have a main method that has 1 line: one that instantiates a 'JFrame` object. This will automagically create the window.
Oh and one more vitally import thing: you must call setVisible(true) on your JFrame if you want it to display. I am not sure why it is setup that way.

Categories

Resources