I have added the image in the src and bin directories and cross-checked that the name of the image file is correct
Here is the main class
import javax.swing.*;
public class apples
{
public static void main(String args[])
{
JFrame frame = new JFrame();
MyDrawPanel wid = new MyDrawPanel();
frame.add(wid);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(300,300);
}
}
and here is the class that does the image adding part
import java.awt.*;
import javax.swing.*;
public class MyDrawPanel extends JPanel
{
public void paintComponent(Graphics g)
{
Image image = new ImageIcon("b.png").getImage();
g.drawImage(image,20, 20, this);
}
}
frame.setVisible(true); should be last code line inside public static void main(String args[]), because you setSize to already visible JFrame (just torso contains only Toolbar with three Buttons)
every Swing code lines in public static void main(String args[]) should be wrapped into invokeLater(), more info about in Oracle tutorial Initial Thread
public class MyDrawPanel extends JPanel returns zero Dimension (0, 0) you have to override getPreferredSize for (inside) MyDrawPanel extends JPanel, use there new Dimension (300, 300) from frame.setSize(300,300); and then replace this code line (frame.setSize(300,300);) with frame.pack()
Image image = new ImageIcon("b.png").getImage();
a) don't to load any FileIO inside paintComponent, create this Object as local variable
b) 1st code line inside paintComponent should be super.paintComponent() and without reason to be public, but protected (public void paintComponent(Graphics g))
c) Dimension set in g.drawImage(image,20, 20, this); doesn't corresponding with frame.setSize(300,300);, for why reason is there empty space
d) most important (as mentioned in comments) Image image = new ImageIcon("b.png").getImage(); isn't valid Java path
try to use getClass().getResource("b.png"); instead of simply giving the file name.
Because it sometimes doesn't receive the image, so extract the path and resource.
You have to add your image (or any file) in the main project file when you work with eclipse or other frameworks
and if you decides to specialize a specific folder in the project -to hold images for example- you can write Image image = new ImageIcon("src\\b.png").getImage();//replace the src with folder name
Or add the full (absolute)path
You're declaring a JFrame called frame and correctly declaring a class that inherits from Panel that can be drawn upon. The method paintComponent(Graphics G) in MyDrawPanel.Java is called upon every time the image needs to be rewritten.
I tested out your code in my own IDE and it works for me. I think that, as others also have suggested, that your picture needs to be dragged into your Eclipse IDE. Just drag-and-drop it into your Java-project.
Related
Modifiers.java:
package game;
import java.awt.*;
import java.io.*;
import javax.swing.*;
public class Modifiers extends Data{
public static void setupJcomponents(){
frame.setUndecorated(true);
frame.setSize(MW,MH);
frame.setResizable(false);
frame.setVisible(true);
frame.setLayout(null);
for(int btn=0; btn<4; btn++) {
Buttons[btn] = new JPanel();
Buttons[btn].setBounds(btn*100,0,100,100);
Buttons[btn].setVisible(true);
Buttons[btn].setBackground(new Color(btn*50,btn*50,btn*50));
frame.getContentPane().add(Buttons[btn]);
}
menuBackground.setBounds(0,0,MW,MH);
menuBackground.setVisible(true);
menuBackground.setBackground(Color.black);
healthIndicator.setText(String.valueOf(healthValue));
healthIndicator.setFont(new Font("Terminal", Font.PLAIN, 100));
healthIndicator.setBounds(600,600,100,100);
healthIndicator.setForeground(Color.blue);
try{
PixelFont = Font.createFont(Font.TRUETYPE_FONT, new File("PixelFont.ttf"));
} catch (IOException e) {
PixelFont = new Font("Terminal", Font.PLAIN, 100);
} catch(FontFormatException e) {
PixelFont = new Font("Terminal", Font.PLAIN, 100);
}
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(PixelFont);
frame.getContentPane().add(healthIndicator);
frame.getContentPane().add(menuBackground);
}
}
Data.java:
package game;
import java.awt.*;
import javax.swing.*;
public class Data {
// this is where I will declare and alter all variable that will be used
public static JFrame frame = new JFrame();
public static JLabel healthIndicator = new JLabel();
public static JPanel Buttons[] = new JPanel[5];
public static JPanel menuBackground = new JPanel();
public static final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
public static final int MW = (int) screenSize.getWidth();
public static final int MH = (int) screenSize.getHeight();
public static Font PixelFont;
public static int maxHealth = 100;
public static int healthValue = maxHealth;
}
Frame.java:
package game;
public class Frame {
public static void main(String[] args) {
Modifiers.setupJcomponents();
}
}
whenever i rum Frame.java the menu Background disappears and the text altogether stops showing up. but if the path to the .ttf file is wrong it just skips over the font and uses the default instead. How do i get this font to load properly as well as not cause my background background to disappear? I have tried changing the path to the .ttf file and turning various parts of the code into comments, but even if the font of the health indicator is a default font, these errors will still occur, however if i try removing the try-catch loop then the errors aren't there anymore.
There are all kinds of problems with the code. Not exactly sure why the Fonts is causing an issue, but it has something to do with the overall structure of your code and you aren't using Swing the way it was designed to be used.
whenever i rum Frame.java the menu Background disappears and the text altogether stops showing up
What appears to be directly related to the above question is that the setVisible(true) statement should be executed AFTER all the components have been added to the frame. This will make sure all the components are painted.
Note this will still only work by chance because you happen to add the "background" panel to the frame last. Swing paints components in the reverse order that are added to any given panel.
Regarding other problems.
your painting code only works by chance. You should not be adding all your components directly to the frame. Swing is not designed to paint components in 3 dimensions directly when the components overlap one another. Swing is designed to have a parent child relationship. So that would mean you add your "background" panel to the frame. Then you add a panel containing the buttons to the "background" and you add the "health" component to the background.
Related to above you should NOT be using a null layout. Swing was designed to be used with a layout manager. This will make sure components don't overlap. So in your case you can use a BorderLayout for the "background" panel. Then you can add the "buttons" panel to the BorderLayout.PAGE_Start and the "health" component to the `BorderLayout.PAGE_END. This will ensure that the components are at the top/bottom of the background panel.
Don't set the size of the frame. Instead you use the setExtendedState(JFrame.MAXIMIZED_BOTH) property. The frame will be the size of the screen. The "GamePanel" will be take up all the space of the frame. So there is no need to set or use hardcoded values.
Don't use static variables and method. This indicates poor design. What you should be doing is creating a GamePanel class, which would essentially be your background panel. This class would contain the instance variables needed for the game. It would create the "buttons" panel and the "health" component and add it to itself.
Variable names should NOT start with upper case characters.
So I've been trying to create a simple graphics program to run on Windows 10. From what I can infer, this is how my textbook would like me to create this program:
import java.awt.*;
public class DrawLine1 {
public static void main (String[]args) {
DrawingPanel panel = new DrawingPanel(1281, 721);
Graphics g = panel.getGraphics();
g.drawLine(1, 1, 69, 69);
}
}
However, when I try to compile it, cmd returns the following error:
D
rawLine1.java:4: error: cannot access DrawingPanel
DrawingPanel panel = new DrawingPanel(1281, 721);
^
bad source file: .\DrawingPanel.java
file does not contain class DrawingPanel
Please remove or make sure it appears in the correct subdirectory of the sourcepath.
1 error
Is this an error with the code I wrote or with how I set up Java, and how do I fix it?
Looks like the code you've written is incomplete -- the compiler appears to be complaining that it can't find the DrawingPanel class, and if it doesn't exist, then you also need to create and compile the DrawingPanel code first. But having said that, I wouldn't recommend that you use this code or whatever tutorial suggests it as it's making some key bad recommendations
For one, you need to display any drawing JPanel (assuming DrawingPanel is a JPanel) in a top level window for it to be displayed. For Swing GUI's this would mean you would need to create a JFrame and put the drawing JPanel into it, and then set the JFrame as visible via setVisible(true)
Drawing with a components Graphics object in this way -- by calling getGraphics() is not recommended as the Graphics object obtained in this fashion is not guaranteed to persist. For instance, assuming that you get this code to work, if you minimized and restored your GUI, your line would disappear.
Swing and AWT graphics are passive -- you would override your JPanel's paintComponent method and do your drawing inside of this method.
You should start Swing and AWT GUI's on the Swing event thread. This is usually done by placing this code into a Runnable's run() method and then passing the Runnable into a SwingUtilities.invokeLater(...) method call.
For example:
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
public class SimpleLine extends JPanel {
private static final int PANEL_WIDTH = 400;
public SimpleLine() {
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_WIDTH));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // so JPanel can do its own housekeeping graphics
int x1 = 1;
int y1 = x1;
int x2 = PANEL_WIDTH - 2;
int y2 = x2;
g.drawLine(x1, y1, x2, y2);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SimpleLine");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleLine());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Looks like you're working with the textbook Building Java Programs. I was able to reproduce your problem, which is not a problem with your code nor with how you have setup Java (assuming you are running Java 8).
Your code is referencing another java class, DrawingPanel, provided by the textbook's author on the author's website.
To continue on your learning path with that textbook, and to get your program to compile, you'll need to download the DrawingPanel class from the textbook website:
http://www.buildingjavaprograms.com/DrawingPanel.java
Then put that java file in the same location as your DrawLine1.java file.
Recompile as you did before, and your code should compile with no errors.
I have 2 issues.
First issue: I have to set the JFrame as non resizable, however, an error is thrown up when I enter in frame.setResizable(false);
Second issue: I have ran into the problem of the JFrame not fitting the component within it perfectly. I have set the dimensions for the JFrame to 600x720 and the board component as being 600x600. However, when I extend the JFrame I can see that there is more of the component to be revealed. How would I change this to accommodate the component to fit snugly but also leave space for another component of size 100x120? My understanding of this is that JFrame sets the size with the borders included, however, I want the space within the JFrame to be exactly 600x720 pixels without including the border.
The code is set out below.
Game Class
package snake;
//This class is used to run the game.
public class Game {
/**
* #author HyperBlue
*/
//Declaring a static variable of type Board. This can be accessed from anywhere in the program. The fact that it is static means that it cannot be edited.
public static Board board;
public static void main(String[] args) {
// TODO Auto-generated method stub
//Creates an object board from the Board() construct
board = new Board();
}
}
Board Class
package snake;
//Importing allows us to use pre-defined classes in Java, this contains its methods. We can also import entire packages which contain a number of classes in that package.
//This class allows us to assign/capture the width and height of an object.
import java.awt.Dimension;
//The Toolkit is an abstract class containing abstract and (possibly) non-abstract methods. Abstract classes cannot be instantiated (i.e. we cannot make an object from them). Abstract methods have no body (no code), for example we declare it as "public abstract boolean isChanged() ;", the semi colon shows it has no body (i.e. no {}).
import java.awt.Toolkit;
//ActionEvent gets information about an event (input) and its source. You can create an object from this.
import java.awt.event.ActionEvent;
//The ActionListener defines what should be done when a certain action is performed by the user.
import java.awt.event.ActionListener;
//This imports the JFrame class from the swing package.
import javax.swing.JFrame;
import javax.swing.Timer;
//This class is used to create the game board.
//The ActionListener is implemented because it is implementing an interface. What ActionListener does is it handles events; the ActionListener defines what should be done when a certain action is performed by the user.
public class Board implements ActionListener {
//The JFrame is the window in which everything will be placed into, this will provide the framed window (what is visible to us) in which the game will run in. We are creating a variable frame of type JFrame.
public JFrame frame;
//Creating a variable drawBoard of type DrawBoard. This allows us to add the component of drawBoard to the Board.
public DrawBoard drawBoard;
//Defining a new Timer called ticker. This is using the form new Timer(int delay in milliseconds, ActionListener listener). What the timer does is it allows threads to schedule the execution of instructions. In this case to constantly refresh the drawBoard component at regular intervals. This will give the appearance of motion. What "this" does is it is in reference to the current instance,
public Timer ticker = new Timer(20, this);
//This is a constructor for the class Board. This will allow us to create an object.
public Board() {
//Making an instance of dimension dim and assigning it to the size of the screen.
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
//Declaring instance of the JFrame 'frame'. This JFrame is called to declare a title for this frame - "Snake".
frame = new JFrame("Snake");
//JFrame is initially set to invisible, so we use the setVisible method (setting it to true) to make the JFrame 'frame' visible.
frame.setVisible(true);
frame.setPreferredSize(new Dimension(600, 720));
frame.getContentPane().add(drawBoard = new DrawBoard());
frame.pack();
//What this does is it places the JFrame 'frame' into the middle of the user's screen, this diminishes the issue of not all screens being the same resolution and size. This is done by setting the (x, y) position of the JPanel. For example, the x position is gained by dividing the size of the monitor by 2 and negating the size of the JPanel by 2 from that value, this places it in the middle of the screen's x axis. This is true for the y-axis too.
frame.setLocation((dim.width / 2) - (frame.getWidth() / 2), (dim.height / 2) - (frame.getHeight() / 2));
//Sets the operation which will happen when the user closes the JFrame 'frame', the EXIT_ON_CLOSE exits the application using the System exit method. This means that when the JFrame is closed, the application will be exited (closed).
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Starts the timer, this starts is sending action events to its listeners.
ticker.start();
}
//Overriding the actionPerformed method from the ActionListener class.
#Override
//This is the actionPerformed method. We parse it the ActionEvent e, what this is is an object which gives information about the event and its source. This allows us to perform an action based upon a specific event (e.g. a keyboard key pressed).
public void actionPerformed(ActionEvent e) {
//This repaints this component for every tick
//drawBoard.repaint();
}
}
DrawBoard Class
package snake;
//Allows use of default sRGB colours.
import java.awt.Color;
//Graphics is an abstract class that allows us to draw onto components.
import java.awt.Graphics;
import javax.swing.JPanel;
//Warnings will not be thrown (are suppressed).
#SuppressWarnings("serial")
//This class is used to create the board component in which the snake can move on.
//What extending does is it allows us to inherit the methods and attributes (properties) of another class. In this case, the DrawBoard class (subclass - inherits state and behaviour from all of its ancestors) inherits properties from the JPanel class (superclass - gives properties to its subclasses).
public class DrawBoard extends JPanel{
//Declaring the colour 'yellow' as the hex colour code (turned to decimal using a hex calculator so Java can use it) which was chosen in the design stage.
public static Color yellow = new Color(13816442);
//We are overriding the protected method in order to define our own body (and properties) for the paintComponent method. Overriding this allows us to define how we will paint the component DrawBoard. Protected means that it can only be accessed by things within the same package.
#Override
//A component is an object which has a graphical representation that can interact with the user (e.g. buttons).
//What this does is it paints the component using the graphics class, defined as instance g.
protected void paintComponent(Graphics g) {
//'Super.' refers to the method calling its super class, which in this case is JPanel. Doing this allows me to use in built 'drawings' such as rectangle and oval, which can be drawn by calling their methods.
super.paintComponent(g);
//Setting the colour in which graphics objects are made to the colour defined in the colour 'yellow'
g.setColor(yellow);
//Filling in a rectangle which starts at the point (0, 120) - [this is from the top left of the screen, with (0, 120) referring to 120 pixels down] and has a width and height of (600, 600), in other words provides a background of colour 'yellow' defined.
g.fillRect(0, 120, 600, 600);
}
}
Regarding:
How to Get JPanel to Fit Snugly With It's Components?
Let the layout managers do this work for you.
Suggestions:
Don't set sizes or preferred sizes.
Instead let the component's preferred size and your layout managers do the sizing for you.
If you do need to actively have a hand in setting some sizes, override getPreferredSize() and return an appropriate dimension, but do so taking care not to upset the preferred size of the constituent components. This must be done with care.
Re " I have set the dimensions for the JFrame to 600x720 and the board component as being 600x600. However, when I extend the JFrame I can see that there is more of the component to be revealed." -- You're forgetting the size of the top bar of the JFrame, something that may change size depending on the look and feel. Again, don't set the JFrame's size, and this will be a moot point.
To center a JFrame, simply call frame.setLocationRelativeTo(null); after it has been packed.
Avoid over-use of comments as these make your code nearly unreadable.
If you have problems and need help with an error such as you mention here: "I have to set the JFrame as non resizable, however, an error is thrown up when I enter in frame.setResizable(false);", then show the offending code and the error message.
Don't call frame.setVisible(true); until all components have been added and the JFrame has been packed.
For example
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.*;
public class Game {
public static Board board;
public static void main(String[] args) {
board = new Board();
}
}
class Board implements ActionListener {
public JFrame frame;
public DrawBoard drawBoard;
public Timer ticker = new Timer(20, this);
public Board() {
frame = new JFrame("Snake");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setPreferredSize(new Dimension(600, 720));
frame.getContentPane().add(drawBoard = new DrawBoard(), BorderLayout.CENTER);
frame.getContentPane().add(new BottomComponent(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
ticker.start();
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
class DrawBoard extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
public static Color yellow = new Color(13816442);
public DrawBoard() {
setBorder(BorderFactory.createTitledBorder("Draw Board"));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(yellow);
g.fillRect(0, 120, 600, 600);
}
}
class BottomComponent extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = 120;
public BottomComponent() {
setBorder(BorderFactory.createTitledBorder("Bottom Component"));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
}
The variable was made, the image is loaded into the variable and the paintComponent is asked to display the image in my JPanel. I can't see my mistake.
public class Main extends JFrame {
public static void main(String[] args) {
JFrame frame = new Main();
frame.setSize(1524, 715);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Animatieproject Stijn Mannaerts: Free Kick");
frame.setContentPane(new Voetbalveld());
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
class Voetbalveld extends JPanel {
private ImageIcon afbIntro;
public Voetbalveld() {
afbIntro = new ImageIcon("scr/afbeeldingen/Intro.jpg");
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
afbIntro.paintIcon(null, g, 0, 0);
}
}
That isn't how painting is done. Why not use Graphics.drawImage() instead? Check out this tutorial: http://docs.oracle.com/javase/tutorial/uiswing/painting/
Your code seems right to me. Make sure you don't want src instead of scr. Next, if your image folder is inside source folder of your project then you might want to try this:
afbIntro = new ImageIcon(Voetbalveld.class.getResourceAsStream("scr/afbeeldingen/Intro.jpg"));
or
afbIntro = new ImageIcon(Voetbalveld.class.getResourceAsStream("afbeeldingen/Intro.jpg"));
depending on your file structure. The path in the second example needs to be relative to the file Main.java.
The frame class
import javax.swing.JFrame;
public class Main
{
public static void main(String[] args)
{
Jframe frame = new JFrame("Animatieproject Stijn Mannaerts: Free Kick");
frame.setSize(1524, 715);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new Voetbalveld());
frame.setVisible(true);
}
}
The panel class
import javax.swing.*;
import java.awt.*;
public class Voetbalveld extends JPanel
{
public void paintComponent(Graphics g)
{
ImageIcon afbIntro = new ImageIcon("scr/afbeeldingen/Intro.jpg");
/*The following are two methods for image sizing,
*Use the one that best fits your code:
*
*g.drawImage(afbIntro.getImage(), x, y, null);
*Fill in the arguments for x and y to locate your upper left corner
*The image will be in it's original size with the designated upper left corner
*
*g.drawImage(afbIntro.getImage(), x, y, w, h, null);
*Fill in the arguments for w and h to set the width and height of your image
*The image will be in it's scaled size (w and h) and starting at the
*designated upper left corner (x and y)
*/
}
}
You spelled src wrong. You have scr.
"scr/afbeeldingen/Intro.jpg"
Fix that
I have a class with two JFrames and am trying to draw a line on a particular frame .
I tried the code below but it only appears in the first frame which is the success frame.
It also appears above all the other components of the success frame thus making all other
components invisible. It does not appear in the comp Frame.
How do I correct this.
Here is the code I have so far :
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
public class lineGUI{
public static void main(String []args){
Success s=new Success();
s.setVisible(true);
}
}
class Success extends JFrame{
JPanel alas =new JPanel();
JFrame comp =new JFrame();
public Success(){
JPanel panel=new JPanel();
getContentPane().add(panel);
setSize(450,450);
JButton button =new JButton("press");
panel.add(button);
comp.setSize(650,500);
comp.setTitle("View Report");
JRootPane compPane=comp.getRootPane();
Container contePane=compPane.getContentPane();
contePane.add(alas);
ActionListener action =new ActionListener(){
public void actionPerformed(ActionEvent e){
if (e.getSource()==button){
comp.setVisible(true);
}
}
};
button.addActionListener(action);
JButton button2=new JButton("access");
alas.add(button2);
}
public void paint(Graphics g) {
comp.paint(g);
Graphics2D g2 = (Graphics2D) g;
Line2D lin = new Line2D.Float(100, 100, 250, 260);
g2.draw(lin);
}
}
You've got some crazy code up there. Suggestions:
Don't draw directly in a JFrame, but in a the paintComponent method of an object derived from JComponent such as JPanel or JComponent itself.
Your drawing directly in another component's paint(...) method is not kosher at all. Why not simply share the data between classes, and use the data (the ints) to draw where desired.
You would rarely want to have a GUI display more than one JFrame at a time. Usually one window is the main window (the JFrame), and it often owns any other windows which would be dialog windows such as JDialogs.
Read the graphics tutorials to learn the correct way to do Swing Graphics
Two things:
If you want to draw in the "comp" frame, then you should extend that frame explicitly to overload its paint method. Right now you're overloading the paint method of "Success" frame. The line comp.paint(g) is using the paint method of comp (a standard JFrame) to draw on the Graphics object of the "Success" frame. You probably want to make that into super.paint(g) instead, then put this paint function into it's own JFrame and create comp from that.
http://pastebin.com/ZLYBHpmj
(Sorry, first post, couldn't figure out how to get Stackoverflow to quit complaining about format)