public class Rec extends JFrame {
public Rec (){
JFrame jframe = new JFrame();
jframe.setSize(500, 500);
jframe.setVisible(true);
}
public void render (Graphics g){
g.setColor(Color.red);
g.fillRect(0,0,50,50);
}
public static void main(String[] args) {
Rec frame = new Rec();
frame.render(g);
}
}
Why does this not work? I am aware I may need a paintComponent, if so how would I go about doing this? Any help would be great, Thank You!
The thing is that painting in a JFrame is not what you should be doing. It is better (in this instance) to set the contentpane as a JPanel, and paint inside the JPanel.
Take this short snippet as an example:
import java.awt.*;
import javax.swing.*;
public class Rec {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame rec = new JFrame();
rec.setSize(50, 150);
rec.setContentPane(new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(0, 0, 50, 50);
}
});
rec.setVisible(true);
}
});
}
}
Result:
//May be this is what you are looking for.
public void paintComponent(Graphics g) {
// Create a copy of the passed in Graphics object
Graphics gCopy = g.create();
// Change the properties of gCopy and use it for drawing here
// Dispose the copy of the Graphics object
gCopy.dispose();
}
//or might be this
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Dimension;
import javax.swing.JFrame;
public class DrawingCanvas extends JPanel {
public DrawingCanvas() {
this.setPreferredSize(new Dimension(600, 75));
}
#Override
public void paintComponent(Graphics g) {
// Draw a rectangle
g.fillRect(100, 100, 100, 100);
}
public static void main(String[] args) {
JFrame frame =new JFrame("Drawing");
frame.getContentPane().add(new DrawingCanvas());
frame.pack();
frame.setVisible(true);
}
}
Related
I am trying to create a simple drawing program which contains a toolbar and a drawing area. The program's main window is a JFrame. I have added a JToolBar and a JPanel (drawingPanel) on which to draw. However, the line is not drawn on drawingPanel but behind it (I can see the line when I remove drawingPanel - just comment out CreateDrawingPanel();). How can I draw the line on drawingPanel?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
public class UserInterface extends JPanel
{
static JFrame frame;
static JPanel drawingPanel;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
CreateFrame();
}
});
}
private static void CreateFrame()
{
frame = new JFrame("Interface");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.add(new UserInterface());
}
public UserInterface()
{
setLayout(new BorderLayout());
CreateToolBar();
CreateDrawingPanel();
repaint();
}
private void CreateToolBar()
{
JToolBar toolbar = new JToolBar(JToolBar.VERTICAL);
JButton button = new JButton("Some button");
toolbar.add(button);
add(toolbar, BorderLayout.WEST);
toolbar.setBackground(Color.black);
toolbar.setFloatable(false);
}
private void CreateDrawingPanel()
{
drawingPanel = new JPanel();
add(drawingPanel, BorderLayout.CENTER);
drawingPanel.setBackground(Color.white);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawLine(100, 100, 120, 500);
}
}
All your drawing is on the UserInterface object, as this is where you override paintComponent().
Remove the paintComponent() override, and change the createDrawingPanel():
private void CreateDrawingPanel()
{
drawingPanel = new JPanel(){
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawLine(100, 100, 120, 500);
}
};
add(drawingPanel, BorderLayout.CENTER);
drawingPanel.setBackground(Color.white);
}
You could either define your drawingPanel like this:
drawingPanel = new JPanel(){
protected void paintComponent(Graphics g){
//Your draw Code
}
};
or you could create a class that inherits from JPanel:
public class DrawingPanel extends JPanel{
public DrawingPanel(){
//...
}
protected void paintComponent(Graphics g){
//Your draw Code
}
}
and use it like this:
drawingPanel = new DrawingPanel();
I am working on learning how to create custom components. I would like to be able to include all of the methods that it calls to start with and to be able to change even the border method. Below my code does not repaint the paintBorder(...) method
public void paintBorder(Component t, Graphics g, int x, int y, int h, int w) {
super.paintBorder(g);
g.setColor(Color.YELLOW);
g.fillOval(100, 100, 50, 50);
System.out.println("PaintBorder");
}
Why would this not be being painted. The code in the paintComponent(...) does work and paint the circle but what if I want to set the border to something different or even if I just want to see a message go to the console with a println(...).
Paint Call:
There are three methods called
paintComponent()
paintBorder()
paintChildren()
How can I get my paintBorder() to be called? I would imagine that if I make a instance of this in another class than I should be able to call repaint() which calls update which intern schedules a call to paint which calls the three methods listed above (paintComponent, paintBorder, paintChildren)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
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.green);
testPane.setLayout(new BorderLayout());
testPane.add(new Ball(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(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyBall extends JComponent{
private static final long serialVersionUID = 1L;
public static Color colorBall = Color.red;
public MyBall() {
super();
System.out.println("MyBall (0)");
}
public MyBall(int x, int y, int diameter){
super();
this.setLocation(x, y);
this.setSize(diameter, diameter);
System.out.println("MyBall (1)");
}
public void paintBorder(Graphics g) {
super.paintBorder(g);
g.setColor(Color.YELLOW);
g.fillOval(100, 100, 50, 50);
System.out.println("PaintBorder");
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(colorBall);
g.fillOval(0, 0, 50, 50);
System.out.println("paintComponent");
}
public void paint(Graphics g) {
super.paint(g);
paintComponent(g);
paintBorder(this, g,10,10,10,10);
paintChildren(g);
System.out.println("Paint");
}
}
Working Code: I was creating an instance of a different ball class which was something that I did not see. If a person is going to over write the paintBorder(...) method in a class the extends JComponent(...) how should the border be painted? Does anyone have any good links for such a task?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
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.green);
testPane.setLayout(new BorderLayout());
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(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class MyBall extends JComponent
{
private static final long serialVersionUID = 1L;
private Color colorBall = Color.red;
public void setColorBall(Color c)
{
this.colorBall = c;
}
public MyBall()
{
super();
System.out.println("MyBall (0)");
}
public MyBall(int x, int y, int diameter)
{
super();
this.setLocation(x, y);
this.setSize(diameter, diameter);
System.out.println("MyBall (1)");
}
public void paintBorder(Graphics g)
{
super.paintBorder(g);
g.setColor(Color.YELLOW);
g.fillOval(100, 100, 50, 50);
System.out.println("PaintBorder");
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(colorBall);
g.fillOval(0, 0, 50, 50);
System.out.println("paintComponent");
}
public void paint(Graphics g)
{
super.paint(g);
paintComponent(g);
paintBorder(g);
paintChildren(g);
System.out.println("Paint");
}
}
There is no such method in JComponent
public void paintBorder(Component t, Graphics g, int x, int y, int h, int w)
It's method of border so it's never invoked in JComponent. Override
protected void paintBorder(Graphics g)
Instead and add your code there.
I am trying to draw a rectangle in the class "Graphics", but for some reason the rectangle does not appear, but the program returns no errors. I have never experience issues such as this before so I am rather confused.
Main()
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main
{
public Main()
{
JFrame window = new JFrame();
Sound soundCall = new Sound();
Graphics graphicsCall = new Graphics();
final JPanel container = new JPanel();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(container);
window.setSize(600, 400);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Main();
}
});
}
Graphics()
import java.awt.Color;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Graphics extends JPanel
{
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(500, 500, 500, 500);
}
}
EDIT FOR HOVERCRAFT
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main
{
public Main()
{
JFrame window = new JFrame();
Sound soundCall = new Sound();
Draw drawCall = new Draw();
final JPanel container = new JPanel();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(drawCall);
window.setSize(600, 400);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Main();
}
});
}
}
Through adding this window.getContentPane().add(drawCall); asks me to change drawCall to a Component
EDIT 2:
public class Draw
{
public class Graphics extends JPanel
{
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(0, 0, 500, 500);
}
}
}
ERROR
The method add(Component) in the type Container is not applicable for the arguments (Draw)
You add your graphicsCall variable to nothing, and so it will not be displayed. Solution: add it to a container such as that JPanel that you just created, or perhaps directly to the JFrame's contentPane.
i.e., change this:
JFrame window = new JFrame();
Sound soundCall = new Sound();
Graphics graphicsCall = new Graphics();
final JPanel container = new JPanel();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(container);
to this:
JFrame window = new JFrame();
Sound soundCall = new Sound();
Graphics graphicsCall = new Graphics();
// final JPanel container = new JPanel();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(soundCall);
As an aside, you will want to re-name that class from Graphics to something else, or else you risk confusing yourself or your compiler since there already exists a critical Java class with that name.
Also, avoid using setSize(...). Better to have your drawing JPanel override getPreferredSize() and to call pack() on your JFrame.
Edit
As per MadProgrammer's astute observation, you're drawing outside of the bounds of your component.
Edit 2
Regarding your latest code, this:
public class Draw
{
public class Graphics extends JPanel
{
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(0, 0, 500, 500);
}
}
}
is useless dreck. Why are you needlessly wrapping a class inside of a class? Instead why not simply:
public class Draw extends JPanel {
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(0, 0, 500, 500);
}
#Override
public Dimension getPreferredSize() {
// return an appropriate Dimension here
}
}
I am trying to set background color of my screen to green.
My code so far:
package game;
import java.awt.*;
import javax.swing.JFrame;
public class Game extends JFrame {
public static void main(String[] args) {
DisplayMode dm = new DisplayMode(800, 600, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
Game g = new Game();
g.run(dm);
}
public void run(DisplayMode dm) {
setBackground(Color.GREEN);
setForeground(Color.WHITE);
setFont(new Font("arial", Font.PLAIN, 24));
Screen s = new Screen();
try {
s.setFullScreen(dm, this);
try {
Thread.sleep(5000);
} catch (Exception E) {
}
} finally {
s.restoreScreen();
}
}
#Override
public void paint(Graphics g){
g.drawString("Check Screen", 200, 200);
}
}
When I run the program, I get this:
Screen should be green according to line:
setBackground(Color.GREEN);
Why does the background is not being set to green when I run the program?
You need to add a call to super.paint (g); in your paint () method.
#Override
public void paint(Graphics g){
super.paint (g);
g.drawString("Check Screen", 200, 200);
}
This will ensure that the component will draw itself correctly, including the background color, then draw your text.
Generally, whole approach is very bad. Even if it works with getContentPane().setBackground(Color.GREEN) it won't probably work because you are calling a Thread.sleep(5000) on EDT (or you will have issues soon or later). Use proper component for repetitive task's (refreshing of your screen): Swing Timer.
Instead of overriding JFrame's paint method, it's far better to use JPanel and to override it's paintComponent method. So, something like this:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Game extends JFrame {
JFrame frame = new JFrame();
public Game() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Panel());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Game();
}
});
}
class Panel extends JPanel {
Timer timer;
Panel() {
setBackground(Color.BLACK);
setForeground(Color.WHITE);
refreshScreen();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("arial", Font.PLAIN, 24));
g.drawString("Check Screen", 200, 200);
}
public void refreshScreen() {
timer = new Timer(0, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
});
timer.setRepeats(true);
//Aprox. 60 FPS
timer.setDelay(17);
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(650, 480);
}
}
}
I think I'm being a bit of an idiot, given that I haven't done Swing programming in a while, but I'm trying to draw a simple image to screen, and I'm not getting what I expected
public class ImageApp {
public static void main(String[] args) throws MalformedURLException, IOException {
final Image image = ImageIO.read(new File("/Library/WebServer/Documents/image.gif"));
final JPanel component = new JPanel(){
public void paint(final Graphics g) {
System.out.println("Drawing image "+image.getWidth(null)+" "+image.getHeight(null));
g.drawString("hello", 0,0);
g.drawImage(image,this.getWidth()/2,this.getHeight()/2, 100, 100, Color.blue,this);
super.paint(g);
}
};
final JFrame frame = new JFrame();
frame.add(component);
frame.setSize(100, 100);
frame.pack();
frame.setVisible(true);
}
}
This renders a blank window which doesn't seem to be sized to 100,100. Is there some other step I need to perform to get the graphics to appear on screen, or the size to be respected?
I'm using JDK6 on OSX 10.6
In Swing, you should override paintComponent(), not paint().
Addendum: e.g., see below. In a comment, #eugener raises an excellent point about using a JLabel as an alternative image container.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImageApp {
public static void main(String[] args) throws IOException {
final Image image = ImageIO.read(new File("image.jpg"));
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
final JPanel component = new JPanel() {
#Override
public void paintComponent(final Graphics g) {
g.drawImage(image, 0, 0, null);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(
image.getWidth(this), image.getHeight(this));
}
};
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(component);
frame.pack();
frame.setVisible(true);
}
});
}
}
Try this:
public class ImageApp {
public static void main(String[] args) throws MalformedURLException, IOException {
final Image image = ImageIO.read(new File("/Library/WebServer/Documents/image.gif"));
final JPanel component = new JPanel() {
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
System.out.println("Drawing image " + image.getWidth(null) + " " + image.getHeight(null));
g.drawString("hello", 0,10);
g.drawImage(image, this.getWidth() / 2, this.getHeight() / 2, 100, 100, Color.blue, this);
}
};
final JFrame frame = new JFrame();
frame.add(component);
frame.setSize(100, 100);
frame.setVisible(true);
}
}