Why my image doesn't load on contentPane except on CENTER? - java

I am currently still learning Java GUI and stumped on this problem. I just wonder why can't i load it anywhere except on center and how do i load my image anywhere else?
import java.awt.*;
import javax.swing.*;
public class GUI {
public static void main(String[] args) {
GUI gui = new GUI();
gui.go();
}
public void go() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
Player player = new Player();
panel.setBackground(Color.darkGray);
JButton button = new JButton("shock me");
panel.add(button);
frame.getContentPane().add(BorderLayout.EAST, panel);
frame.getContentPane().add(BorderLayout.NORTH, player);
//frame.getContentPane().add(BorderLayout.CENTER, player);
frame.setSize(200,200);
frame.setVisible(true);
}
}
Here's my player class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.util.Random;
import javax.swing.*;
public class Player extends JPanel{
public void paintComponent(Graphics g) {
Image image = new ImageIcon("Source/hero.jpg").getImage();
g.drawImage(image, 3, 4 , this);
}
}

Player does not override getPreferredSize() to return a value. Since it does not do that, the BorderLayout will not assign it any height in the PAGE_START or PAGE_END constraints, and no width in the LINE_START and LINE_END constraints. The component is being added, it just has no width/height.
The CENTER will stretch both a component's width and height to the available space, that is why it is visible there.

Related

JComponent not appearing

I'm trying to create a super simple component, and it's not appearing.
Component class:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;
public class Player extends JComponent{
public Player()
{
}
public void paint(Graphics g)
{
g.setColor(Color.green);
g.fillRect(40,40,150,150);
}
}
Panel Class im adding it to:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import javax.swing.JPanel;
public class Game extends JPanel{
public Game()
{
this.setBackground(Color.yellow);
this.setPreferredSize(new Dimension(500,500));
Player p = new Player();
this.add(p);
}
}
And the JFrame:
import javax.swing.JFrame;
public class Launcher {
public static void main(String[] args) {
JFrame frame = new JFrame("Key Collector Demo");
frame.add(new Game());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
}
}
The only thing showing up is the yellow background.
JFrame and JPanel are working fine; this problem consistently happens to me when building jcomponents. What am I missing?
Any help would be greatly appreciated!
Coordinates that you are using to draw a component are defined in the space of that component.
If you do this:
public void paint(Graphics g)
{
g.setColor(Color.green);
System.out.println(getSize());
g.fillRect(40,40,150,150);
}
You will see that at the moment it is attempted to get drawn its size is 1x1. So drawing it from 40,40 obviously takes it out of the visible area of the component.
Now change the method to:
public void paint(Graphics g)
{
g.setColor(Color.green);
System.out.println(getSize());
setSize(45, 45);
g.fillRect(40,40,150,150);
}
Now you can see small filled rectangle. This is because you forced the size to be 45x45 and now there are 5 pixels to show in the space of the component while the remaining part is still out of the area.
Do not assume the Player panel to have a fixed size.
For a first test your paint method could look like this:
public void paint(Graphics g) {
g.setColor(Color.green);
g.fillRect(0,0,getWidth(),getHeight());
}
The next problem is that the component probably has no size or position. Add a LayoutManager to your panel and add the component:
public Game() {
this.setBackground(Color.yellow);
this.setPreferredSize(new Dimension(500,500));
this.setLayout(new BorderLayout());
Player p = new Player();
this.add(p, BorderLayout.CENTER);
}
With that, your player might take the full space and you see green instead of yellow. Play around with the LayoutManager and the player's preferredSize.

Java Swing GUI BorderLayout: Location of components

I'm new to Java and I'm playing around with a simple GUI example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class DrawTest {
class DrawingPanel extends JPanel {
private Rectangle2D shape;
public DrawingPanel(Rectangle2D shape) {
this.shape = shape;
}
public void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
super.paintComponent(g2D);
g2D.setColor(new Color(31, 21, 1));
g2D.fill(shape);
}
}
public void draw() {
JFrame frame = new JFrame();
Rectangle2D shape = new Rectangle2D.Float();
final DrawingPanel drawing = new DrawingPanel(shape);
shape.setRect(0, 0, 400, 400);
frame.getContentPane().add(BorderLayout.NORTH, new JButton("TestN"));
frame.getContentPane().add(BorderLayout.SOUTH, new JButton("TestS"));
frame.getContentPane().add(BorderLayout.EAST, new JButton("TestE"));
frame.getContentPane().add(BorderLayout.WEST, new JButton("TestW"));
frame.getContentPane().add(BorderLayout.CENTER, drawing);
frame.pack();
frame.setSize(500,500);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
public class DrawMain {
public static void main(String[] args) {
DrawTest test = new DrawTest();
test.draw();
}
}
As expected, this code produces a frame with the rectangle at the centre and buttons around it. However, if I change the code like this:
frame.getContentPane().add(BorderLayout.NORTH, drawing);
frame.getContentPane().add(BorderLayout.SOUTH, new JButton("TestS"));
frame.getContentPane().add(BorderLayout.EAST, new JButton("TestE"));
frame.getContentPane().add(BorderLayout.WEST, new JButton("TestW"));
frame.getContentPane().add(BorderLayout.CENTER, new JButton("TestC"));
the "TestC" button gets a huge area in the middle while the rectangle doesn't get enough space. This is even true if I remove the other buttons (TestS, TestE, TestW): I get a huge TestC button and a tiny part of the rectangle (even not the scaled rectangle) at the top.
Why doesn't the rectangle get enough space when it's drawn at the top (NORTH) but does get it when it's drawn at the CENTER?
The DrawingPanel should #Override getPreferredSize() to return an appropriate size.
The layout manager will then take that preferred size as a hint. Some layout managers will expand a component's height or width according to the logic of the layout and constraint. E.G. a BorderLayout will stretch components in the PAGE_START / PAGE_END to the width of the content pane, and LINE_START / LINE_END to the height of the tallest of either of those, or the CENTER. A GridBagLayout OTOH will completely hide / remove a component for which there is not enough space to display it at the preferred size, and that's where 'pack' comes in.
So change frame.setSize(500,500); (which is no better than a guess) to frame.pack();, which will make frame the minimum size it needs to be, in order to display the components it contains.

How to anchor a drawing/line of a jpanel inside a jframe?

I want to make the line I draw of a jpanel not change when I resize the jframe that its on. I just want it to remain in it's original position and if I resize the jframe its on to be smaller, then part of the line should be hidden rather than the line being resized?
import javax.swing.JFrame;
import java.awt.*;
public class GUIIntroduction {
public static void main(String[] args){
DrawPanel panel = new DrawPanel();
JFrame app = new JFrame();
panel.setBounds(0,0,60,60);
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.add(panel);
app.setSize(600,600);
app.setVisible(true);
}
}
import java.awt.Graphics;
import javax.swing.JPanel;
public class DrawPanel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.drawLine(0,height,width,0);
}
}
g.drawLine(0,height,width,0);
If you don't want the size of the line to change, then why are you using dynamic variables in the painting method
The values of width and height change as the frame is resized.
Just use:
g.drawLine(0, 100, 100, 0);

how to do auto-resizing drawings in JPanel?

what's the easiest way to have a drawing in a JPanel that resizes whenever the user resizes the JFrame?
I know that I can auto resize the panel with a BorderLayout but the drawings are not resized in this case. I am new to java and GUI programming and there are probably numerous solutions.
please give me a hint into the right direction to make e.g. the rectangle in
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
public class DrawRect extends JPanel {
#Override
protected void paintComponent(Graphics g) {
g.drawRect(20, 20, 100, 100);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
DrawRect panel = new DrawRect();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(200, 200));
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
auto-resizing whenever the frame is resized.
Provide positions and sizes as a proportion of the width and height of the panel. Whenever the panel is resized, the rendering engine will schedule a call to the paintComponent() method and the rectangle will be drawn proportionally. E.G.
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
public class DrawRect extends JPanel {
#Override
protected void paintComponent(Graphics g) {
int w = getWidth();
int h = getHeight();
g.drawRect(w/10, h/10, w/2, h/2);
}
/* A custom component should give the layout manager hints as to
its preferred size. */
#Override
public Dimension getPreferredSize() {
return new Dimension(200,200);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
DrawRect panel = new DrawRect();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
frame.getContentPane().setLayout(new BorderLayout());
Insert the line before you add the component to the GUI.
You should study layoutmanagers, since it is a unique concept in Java.

Creating a mouselistener over a single Jpane

it's my first post so I hope it'll not be too cringeworthy. So I am trying to create a hex-based strategy game, not quite there yet but anyways.
To achieve a hex-based game I would like to create a field made of hexes which the user should be able to click, and receive the coordinates of that pixel. At the moment I can produce either a field of hexes or a mouselistener/mouseadapter but not both. The last one executed replaces the other on the screen.
If the pane.add(New HexMap()); is switched with pane.add(new MouseListener()); the listener works but the line is not printed
I've looked around for quite some time but the posts that I've encountered had either dealt with changing the background color which the mouselistener can do, because background is independent of the mousesensorhttp://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html? The other examples I've come by have been too advanced for me, because they're using multiple panes, and I have not been able to comprehend themhttp://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html.
So what I'm looking for is a way to add a mouselistener over a single pane, displaying the hexes. Would this be possible?
E.G adding the hexMap after the mouselistener would not overwrite the mouselistener but rather act as an addition
A single line has been created acting as a placeholder for the hexes.
The code:
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
public class GraphicsSetup extends JPanel{
public static final int FRAME_WIDTH = 600;
public static final int FRAME_HEIGHT= 400;
private static JFrame frame;
public static void main(String[] args){
GraphicsSetup draw = new GraphicsSetup();
}
public GraphicsSetup(){
HexMap hexMap = new HexMap();
JPanel panel = new JPanel();
frame = new JFrame("HexExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(FRAME_WIDTH,FRAME_HEIGHT);
Container pane = frame.getContentPane();
pane.setBackground(new Color(20, 100, 30));
pane.add(new MouseListener());
pane.add(new HexMap());
frame.setVisible(true);
}
public class HexMap extends JComponent{
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
g2d.drawLine(0,0, FRAME_WIDTH, FRAME_HEIGHT);
}
}
class MouseListener extends JComponent{
public MouseListener(){
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
System.out.println("Mouse Event" + me);
}
});
}
}
}
Yours Sincerely
I'm not entirely sure what you're after, but try adding your components to your panel object. Such as:
panel.add(new MouseListener());
panel.add(new HexMap());
And then add this to the content pane of your frame:
pane.add(panel);
If you're wondering how to arrange your interface differently, read about layout managers here:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
Edit
Try the following:
Set the layout manager to use a BorderLayout:
JPanel panel = new JPanel(new BorderLayout());
Add your components to the panel and set their location:
panel.add(new MouseListener(), BorderLayout.NORTH);
panel.add(new HexMap(), BorderLayout.CENTER);
Add the panel to the frame content pane:
pane.add(panel);
This will work but the size of the MouseListener panel is quite small...you'll need to figure that out next...

Categories

Resources