So I'm looking at a tutorial here: http://zetcode.com/tutorials/javagamestutorial/basics/
At the very end, they show how to set an image as a background (which is simple). They use 2 codes: Board.java and Image.java (which I've copied below for your convenience).
For some reason, I can't seem to add a JButton to my GUI?
I tried adding the following code to Image.java after the line Image Main = new Image(); , but I can't figure out why it doesn't work. Normally I can just add a JButton to a JPanel using the add command and set the panel to visible with setVisible(true).
JButton start;
start = new JButton("Click Me");
Main.getContentPane().add(start);
I also tried adding a similar code to Board.java instead just to see if it'd work - and it of course didn't. How come my JButton won't show up? I know I'm doing something wrong, but I can't figure it out. Can someone help?
(1) Board.java
package bardejov;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Board extends JPanel {
Image bardejov;
public Board() {
ImageIcon ii = new ImageIcon(this.getClass().getResource("bardejov.jpg"));
bardejov = ii.getImage();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(bardejov, 10, 10, null);
}
}
(2) Image.java
package bardejov;
import javax.swing.JFrame;
import javax.swing.JButton;
public class Image extends JFrame {
public Image() {
add(new Board());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(280, 240);
setLocationRelativeTo(null);
setTitle("Bardejov");
setVisible(true);
}
public static void main(String[] args) {
Image Main = new Image();
}
}
You need to first create a JPanel with Board and Button laid out correctly. Then set this JPanel as the content pane for the JFrame. You are trying to add two different components to the Frame via different methods which is causing the confusion. If you resize the frame may be you will see the button you added in the background.
Related
I am starting to learn how to make graphics in Java. But if I draw something in my Frame and I run the program. those parts of the Frame where I did not draw anything there is the picture of the Frame running behind my Program. hw can I avoid this?
package de.sarah;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class Framemg extends JFrame{
public Framemg() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Zeichnen mit Java");
setSize(400, 300);
setBackground(Color.yellow);
setVisible(true);
}
public void paint(Graphics g) {
g.drawString( "Hellooo", 120, 60 );
}
}
package de.sarah;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
public class Main{
public static void main(String[] args) {
Framemg Frame = new Framemg();
}
}
Don't override paint() of a JFrame.
Custom painting is done by overriding the paintComponent(...) method of a JPanel. Then you add the panel to the frame.
Read the section from the Swing tutorial on Custom Painting for more information and working examples to get you started.
I just started to work with Java.
I have no problems with creating window,button and any graphics.
But, i cant make window with many buttons, graphics and text boxes.
When i add buttons to my window i cant see graphics.
How can i do it?
code:
package today;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.Graphics;
public class mybuttonapp extends JFrame
{
private mybuttonapp()
{
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
//new mybuttonapp().setVisible(true);
//--
JFrame f=new JFrame("Button Example");
f.setVisible(true);
f.setSize(900, 600);
//f.setLayout(null);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel p1 = new JPanel();
p1.setBackground(Color.GREEN);
p1.setPreferredSize(new Dimension (100,100));
p1.setVisible(true);
f.add(p1);
My2d paint1 = new My2d();
JButton b1=new JButton("Click Here");
b1.setBounds(10,10,100,50);
p1.add(b1);
p1.add(paint1);
}
code 2:
package today;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.*;
import java.awt.event.*;
public class My2d extends JComponent
{
public void paint (Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Ellipse2D.Double circle = new Ellipse2D.Double(300,300,50,50);
g2.fill(circle);
}
}
I think what you want to look at are layouts in swing. If I get what you ask and what you're doing you are overwriting whatever you set first.
https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
This link provides explanations to all of the swing layouts.
You need to check how LayoutManagers work in Java. They help you to put the elements in the right place within your container (JFrame/JPanel).
https://docs.oracle.com/javase/tutorial/uiswing/layout/layoutlist.html
Normally I work with a combination of BorderLayout and GridBagLayout, since it is quite flexible - but many users feel GridBagLayout is too complicated, especially for beginners.
I've looked at a ton of other questions where people have similar issues to what I'm having here (most solutions found by simple mistakes) but I can't for the life of me figure out why my graphics won't display in my jframe. I'm pretty new to Java Graphics so I'd appreciate all the help that I can get. (If someone thinks this is a repeat question, all I ask is that you wait until I get an answer before you close it)
Oh, also, when I run the program, it tells me that the repaint method is called, if that helps in some way
package game.try5;
import java.awt.Dimension;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Window {
public Window() {
JFrame frame = new JFrame("Epic Game");
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GamePanel panel = new GamePanel();
frame.add(panel);
frame.setVisible(true);
}
public static void main(String[] args){
Window window = new Window();
}
}
.
package game.try5;
import java.awt.Graphics;
import javax.swing.JPanel;
public class GamePanel extends JPanel{
GameObject go = new GameObject(0,0,false,"Dog.jpg");
public GamePanel(){
repaint();
System.out.println("Repaint method called");
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(go.getImg().getImage(), go.getxLoc(), go.getyLoc(), 50, 50, null);
System.out.println("Graphics method called");
}
}
.
package game.try5;
import java.awt.Dimension;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Window {
public Window() {
JFrame frame = new JFrame("Epic Game");
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GamePanel panel = new GamePanel();
frame.add(panel);
frame.setVisible(true);
}
public static void main(String[] args){
Window window = new Window();
}
}
Comment out frame.setLayout(null); and you'll most likely see the game.
The default layout of a JFrame is currently a BorderLayout
An object added to a BorderLayout without a constraint defaults to the CENTER.
An object in the CENTER of a BorderLayout is stretched to the available with and height.
Since the code calls frame.setSize(800,600); that available width and height is 800x600 pixels less the frame decorations.
A better all round approach is to:
Have the custom painted component override getPreferredSize() to return a sensible value.
Add the component to a container.
Lastly, pack the top level window. This will make the frame the smallest size it needs to be in order to display the content.
This code won't fill the rectangle. I tried to extend JComponent but I received an error. How would I extend JComponent?
package com.lewis.GooseEgg;
import java.awt.*;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class GooseEgg extends Canvas{ //I couldn't extend JComponent
//How would I also extend JComponent
protected void paintComponent(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0,0, 100, 100);
}
public static void main(String[] args) {
//This is just all the basic stuff I learned
JFrame frame = new JFrame();
GooseEgg goose = new GooseEgg();
frame.setResizable(false);
frame.setTitle("Goose Egg");
frame.add(goose);
frame.pack();
frame.setSize(900, 900);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//The website keeps asking me to add more detail because it says my post is mostly code so I added this. If anyone wants to tutor me at Java
//I could pay money.
}
}
You don't need to extend from Canvas and JComponent: You should only extend from JComponent.
Also you should not do pack() and setSize(…). They both set the size of your frame, this does not make sense. Either do pack() (in which case you also need to specify a preferred size e.g. by overriding getPreferredSize() or setting it with setPreferredSize(…)) or do setSize(…).
Changing Canvas to JComponent and removing the pack() method call seems to produce the correct result.
I am trying to add a JPanel to a JLayeredPane with only partial success. I am able to see both of the panels separately, but not when I add them together. When I put them both together, only the DEFAULT_LAYER shows. Any thoughts would be great.
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.ImageIcon;
import javax.swing.JLayeredPane;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Container;
import java.awt.Component;
import java.awt.Insets;
import java.util.ArrayList;
import java.awt.LayoutManager;
public class ImageEditorView
{
public static int dimensionWidth = 1280;
public static int dimensionHeight = 640;
private Color currentColor = Color.WHITE;
private JLayeredPane layeredPane;
private JPanel createEditPanel()
{
final CirclePanel editPanel = new CirclePanel();
//editPanel.setLayout(new CircleLayout(true));
editPanel.setBounds(50, 0, 150, 150);
editPanel.setOpaque(true);
return editPanel;
}
private JPanel createImageView()
{
JPanel imageView = new JPanel(new GridBagLayout());
imageView.setPreferredSize(new Dimension(dimensionWidth, dimensionHeight));
imageView.setBounds(0, 0, dimensionWidth, dimensionHeight);
imageView.setBackground(currentColor);
return imageView;
}
private void addToLayeredPane(JComponent component, int level)
{
//This prints out what is expected. values of 1 and 100 respectfully
System.out.println("The level has a value of " + level);
layeredPane.add(component, level);
}
public void createAndShowGUI()
{
JFrame f = new JFrame("ImageEditor");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
layeredPane = new JLayeredPane();
//Both createImageView and createEditPanel return with the type JPanel
addToLayeredPane(createImageView(), JLayeredPane.DEFAULT_LAYER);
addToLayeredPane(createEditPanel(), JLayeredPane.PALETTE_LAYER);
f.setSize(dimensionWidth, dimensionHeight);
f.setContentPane(layeredPane);
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
}
class CirclePanel extends JPanel
{
#Override
protected void paintComponent(Graphics g)
{
g.drawOval(0, 0, g.getClipBounds().width, g.getClipBounds().height);
}
}
A JPanel is opaque by default. So you will only see the panel that has been added to the top layer. Try:
panel.setOpaque(false);
on the top panel.
If you need more help then post a proper SSCCE that demonstrate the problem. The code you posted does not compile and therefore is not executable.
Edit:
The problem is your addToLayeredPane(...) method. You are using a layer parameter of "int". It needs to be Integer.
Since you are adding the component using an int value the component is added to the panel normally and is painted in its ZOrder, which basically means the last component added is painted first so your "imageview" is painted on top of the "editview".
Also, you still are not using setOpaque(false) on the "editpanel" as I suggested. The code will only appear to work because you are NOT doing custom painting properly. You should always invoke super.paintComponent(g) at the start of your painting method. This will automatically paint the background which is why you need to make the panel transparent.