Why my objects doesn't show up on JPanel/Java - java

I am trying to display 2 objects Tank on JPanel, the tank gets image with ImageIcon. The JPanel shows up but my Tanks do not. I cannot find where am i wrong. A friend of mine send me the code that he can display tanks but i cannot display it with my computer.
My Tank class to get image
public class Player extends Tank {
private Image img;
public Player(int x, int y){
super(x, y);
ImageIcon ii = new ImageIcon("src/TankD.gif");
img = ii.getImage();
}
public Image getImg() {
return img;
}
public String toString() {
return "This is player tank";
}
}
My class to draw image
public class DrawTanks extends JPanel{ // DRAW IMAGE
private ArrayList<Tank> list = new ArrayList<>();
private Tank a;
public DrawTanks() {
Tank t1 = new Player(100, 200);
Tank t2 = new Bot(200, 100);
a = t1;
list.add(t1);
list.add(t2);
setPreferredSize(new Dimension(100,200));
setLocation(new Point(200, 200));
}
#Override
public void paintComponent(Graphics g){
for (Tank i: list)
g.drawImage(i.getImg(), i.getX(), i.getY(), null);
}
My main class
public class Window extends JFrame{
public static void main(String[]args){
Window win = new Window();
}
public Window(){
JPanel pan = new JPanel();
DrawTanks tanks = new DrawTanks();
this.add(tanks);
this.setTitle("Tank");
this.setSize(900,900);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}

JPanel pan = new JPanel();
DrawTanks tanks = new DrawTanks();
this.add(tanks);
Why are you creating the "pan" object?
By default a JPanel uses a FlowLayout which respects the panels size.
In your DrawTanks class you use:
setPreferredSize(new Dimension(100,200));
to randomly set the size of the panel.
But then you create the tanks:
Tank t1 = new Player(100, 200);
Tank t2 = new Bot(200, 100);
where the location of each tank is outside the preferred size of the panel. So the tanks are probably painted but they are outside the bounds of the panel so you can't see them.
The solution:
get rid of the "pan" pane and just add your DrawTanks panel directly to the frame
give your DrawTanks a reasonable preferred size so all components added to it can be painted.

Related

How to add a JPanel graphic to a JFrame without covering the JFrame

I'm trying to add a small tornado graphic (upside down pyramid) to my Frame. I can get the tornado by adding it to the frame in the main method but when I do that all I see is the tornado graphic and not the GUI underneath it.
So, I'm now trying to add the Tornado graphic to the frame when its created in the createComponents method but it now doesn't appear at all. Instead all I can see it the GUI in the frame.
I' probably missing something easy but I can't seem to figure it out. I'm not sure what I need to to in order to get the GUI and the tornado graphic both to appear.
public class EFScaleViewer {
public static void main(String[] args) {
// TODO Auto-generated method stub
TornadoFrame frame = new TornadoFrame();
frame.setTitle("EF Scale");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Here is where I create the frame and am trying to add the tornado:
public class TornadoFrame extends JFrame{
private JButton submit;
private JLabel label;
static JLabel errorLabel;
static JTextField textBox;
JPanel tornado = new TornadoComponent();
private static final int FRAME_WIDTH = 400;
private static final int FRAME_HEIGHT = 300;
//Constructor for the frame
public TornadoFrame() {
super();
setSize(FRAME_WIDTH, FRAME_HEIGHT);
createComponents();
}
private void createComponents()
{
textBox = new JTextField(" ");
submit = new JButton("Submit");
label = new JLabel("Please enter a windspeed:");
errorLabel = new JLabel("Error Message " );
JPanel panel = new JPanel();
panel.add(label);
panel.add(textBox);
panel.add(submit);
panel.add(errorLabel);
panel.add(tornado);
add(panel);
}
}
I know this is working but I may be missing something so here is where I create the tornado:
public class TornadoComponent extends JPanel {
public void paintComponent(Graphics g) {
int[] xPoints = {100,200,0};
int[] yPoints = {0,200,200};
int nPoints = 3;
g.drawPolygon(xPoints, yPoints, nPoints);
}
}
You have to set the JPanels size for it to be able to display Graphics.
static class TornadoComponent extends JPanel {
public TornadoComponent() {
setPreferredSize(new Dimension(500, 500));
}
#Override
public void paintComponent(Graphics g) {
//Whatever
}
}
And in order to trigger paintComponent(Graphics g) you have to add tornado.repaint(); at the end of your createComponents() function.
private void createComponents() {
//All your components
panel.add(tornado);
add(panel);
tornado.repaint();
}
Now the Polygon is shown but not at the right place (slightly off the image)
Therefore we have to arrange your JPanels a bit:
private void createComponents() {
textBox = new JTextField(" ");
submit = new JButton("Submit");
label = new JLabel("Please enter a windspeed:");
errorLabel = new JLabel("Error Message " );
JPanel upper = new JPanel();
upper.setLayout(new BoxLayout(upper,BoxLayout.X_AXIS));
upper.add(label);
upper.add(textBox);
upper.add(submit);
upper.add(errorLabel);
JPanel lower = new JPanel();
lower.setLayout(new BoxLayout(lower,BoxLayout.X_AXIS));
lower.add(tornado);
JPanel over = new JPanel();
over.setLayout(new BoxLayout(over,BoxLayout.Y_AXIS));
over.add(upper);
over.add(lower);
add(over);
tornado.repaint();
}
Basically I make some boxes...
Over
Upper
... your stuff with text
Lower
Our tornado
Now our tornado is the wrong way round...
int[] xPoints = {100,200,150};
int[] yPoints = {0,0,150};
And voilĂ :
We just created a very basic tornado that is not aiming at anything :)
If you want to change the tornados position later you just have to recall tornado.repaint(); and you are all set.

Using JButtons with Canvas

I'm currently trying to create a primitive HUD inside a JFramewindow for a test game I am working on. In the course of doing this, all my attempts have been thwarted. Either the panel which contains all the buttons that are meant to represent the HUD does not display, or, the Canvas I attempt to draw to appears to not exist as no graphics I draw to it appear.
What I believe the problem is, is that the layers are not 'overlapping', and thus one is blocking out the other. However, I tried using a Flowlayout()(just for testing purposes) & that still did not fix my issue. So right now, I am at a loss for trying to have a HUD of buttons/Labels.
For visual purposes, I am trying to do something like this:
But I am actually getting this (just a test drawn tile, no HUD):
Here is the code that is involved:
public static void createDrawFrame(int width, int height) {
f = new JFrame();
c = new Canvas();
c.setPreferredSize(new Dimension(width, height));
c.setFocusable(false);
f.add(c);
f.pack();
f.setSize(width, height);
f.setLocationRelativeTo(null);
And
public static JFrame getDrawFrame() {
f.setVisible(true);
return f;
}
And
public static JFrame createHUD(JFrame f, Game game) {
Panel p = new Panel();
p.setLayout(new FlowLayout());
p.setSize(100, 100);
p.setLocation(300, 0);
Button b0 = new Button("Settings");
Button b1 = new Button("Exit");
MenuListeners mListeners = new MenuListeners(game);
b0.addActionListener(mListeners);
b1.addActionListener(mListeners);
p.add(b0);
p.add(b1);
f.add(p);
return f;
}
are called here:
private void init() {
Display.createDrawFrame(width, height);
Display.createMenuFrame(width, height);
this.f = Display.getDrawFrame();
this.c = Display.getCanvas();
this.f = HUDDisplay.createHUD(this.f, this);
MapAssets.init();
}
And are rendered here:
private void render() {
b = c.getBufferStrategy();
if(b == null) {
c.createBufferStrategy(3);
return;
}
do {
do {
g = b.getDrawGraphics();
g.clearRect(0, 0, width, height);
state.render(g);
b.show();
}while(b.contentsLost());
g.dispose();
}while(b.contentsRestored());
}
Hopefully I illustrated this problem correctly. To recap, I just want to know why my buttons are not displaying within the JFrame as they should be. Thanks for any help.
I think you can use JFrame's add method with BorderLayout to position the canvas and the buttons. I changed your code to show (demonstrate) it can be done. I hope it is what you are looking for.
I added the components (Canvas and Panel with buttons) to the JFrame using code like this to make them visible:
frame.add(panel, BorderLayout.NORTH); // panel with buttons
frame.add(canvas, BorderLayout.CENTER);
Here are links to Oracle's Java tutorials on Swing for further details; see the sections on Swing Components and Laying Out Components Within a Container.
Example code:
import java.awt.*;
import javax.swing.*;
public class FrameLayoutTest {
private static JFrame f;
private static Canvas c;
public static void main(String [] args) {
init();
}
private static void init() {
//Display.createDrawFrame(width, height);
createDrawFrame(400, 400);
//Display.createMenuFrame(width, height);
createHUD();
//this.f = Display.getDrawFrame();
//getDrawFrame();
//this.c = Display.getCanvas();
//this.f = createHUD(this.f, this);
//MapAssets.init();
}
public static void createDrawFrame(int width, int height) {
f = new JFrame();
c = new Canvas();
c.setBackground(Color.blue);
c.setPreferredSize(new Dimension(width, height));
c.setFocusable(false);
f.add(c, BorderLayout.CENTER); //f.add(c);
f.pack();
f.setVisible(true); // getDrawFrame()
f.setSize(width, height);
f.setLocationRelativeTo(null);
}
public static void createHUD() {
Panel p = new Panel();
p.setLayout(new FlowLayout());
p.setSize(100, 100);
p.setLocation(300, 0);
Button b0 = new Button("Settings");
Button b1 = new Button("Exit");
//MenuListeners mListeners = new MenuListeners(game);
//b0.addActionListener(mListeners);
//b1.addActionListener(mListeners);
p.add(b0);
p.add(b1);
f.add(p, BorderLayout.NORTH); //f.add(p);
}
}

Cannot see the contents in the JLayeredPane in a JPanel

I am trying to create a board class that extends JPanel for a backgammon game and a JLayeredPane to create a dragging area for my checkers but i cant even print a simple rectangle to the panel. It does print the image but not the JLabel.
Here is my JPanel class
public class BoardPanel extends JPanel{
private JLayeredPane lp;
private BufferedImage imageBoard;
private final int WIDTH = 1000;
private final int HEIGHT = 800;
private ArrayList<Slot> slotSet1;
private ArrayList<Slot> slotSet2;
private ArrayList<Slot> slotSet3;
private ArrayList<Slot> slotSet4;
private CheckerSet ch1;
public Checker chc;
public BoardPanel(){
initComponents();
}
private void initComponents(){
lp = new JLayeredPane();
setPreferredSize(new java.awt.Dimension(1500, 1000));
//lp.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
lp.setBorder(javax.swing.BorderFactory.createTitledBorder("asdadsaddadsadasdadsa"));
lp.setMaximumSize(new java.awt.Dimension(1124, 904));
lp.setMinimumSize(new java.awt.Dimension(1124, 904));
try {
imageBoard = ImageIO.read(getClass().getResource("/images/board.jpg"));
} catch (IOException e) {
System.out.println("file error");
}
JLabel label = new JLabel();
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setOpaque(true);
label.setBackground(Color.BLACK);
label.setForeground(Color.black);
label.setBorder(BorderFactory.createLineBorder(Color.black));
label.setBounds(0, 0, 50, 50);
lp.add(label,JLayeredPane.DEFAULT_LAYER);
}
public void paintComponent(Graphics g){
//g.drawImage(imageBoard,0,0,null);
}
}
And there is the main
public static void main(String[] args){
JFrame f = new JFrame();
//GamePanel gp = new GamePanel();
BoardPanel gp = new BoardPanel();
f.add(gp);
//f.getContentPane().add(gamePanel);
f.setSize(new Dimension(1500, 1000));
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
How can i resolve it? Thanks guys
You will have to add a Layout to your JLayeredPane, like a GridLayout for example. Try this:
GridLayout gl = new GridLayout(20, 21);
lp.setLayout(gl);
after initializing lp. Then you can add all components that you Need to the GridLayout, for instance lp:
gl.add(lp)
The Layout will manage how the things will be displayed; in this case, it will fill the grid from the GridLayout, first the first row (of which 20 exist), then the second one and so on (I don't think you actually Need 20 rows, it is just like that in my example code)

JComponent with JButton togather

I have a problem using JComponent and JButton togather.
public class GameWindow extends javax.swing.JFrame{
private javax.swing.JLabel freeCardLabel;
private javax.swing.JPanel NewGameBody2;
private Game game;
public GameWindow (int rozmer, int numberOfPlayers, int numberOfTreasures){
/*create a mazeboard*/
game = new Game();
game.newGame(rozmer, numberOfPlayers, numberOfTreasures);
/* the graphic rendering */
JFrame gameWindow = new JFrame();
gameWindow.setSize(1000, 730);
/* create panel for button*/
JPanel buttonPanel = new JPanel();
/* create button */
JButton button = new JButton("OK");
//button.setBorder(BorderFactory.createEmptyBorder());
//button.setContentAreaFilled(false);
button.setPreferredSize(new Dimension(40,40));
buttonPanel.add(button);
buttonPanel.setMinimumSize(new java.awt.Dimension(150, 700));
gameWindow.setContentPane(buttonPanel);
GameComponent GC = new GameComponent(rozmer, game);
gameWindow.add(GC);
gameWindow.setTitle("Labyrinth - The Game");
gameWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameWindow.setVisible(true);
gameWindow.setResizable(false);
gameWindow.getContentPane().setBackground(Color.gray);
}
this is my GameWindow class. I would like to have something like that:
while GameComponent GC = new GameComponent(rozmer, game); will draw the Labyrinth. With the code posted above the button will display only without labyrinth.
GameComponent is using simply:
#Override
public void paintComponent(Graphics g){
image = null;
offset = calculateOffset(rozmer);
super.paintComponent(g);
/* draw the whole field */
for (int i = 0; i < rozmer; i++){
for (int j = 0; j < rozmer; j++){
selectImage(i, j);
g.drawImage(image, offset+150+j*63+j*1, offset+63*i+i*1, this);
}
}
/* draw free card */
selectImage(-2, -2);
g.drawImage(image, offset+270+(rozmer-1)*63, offset+63*(rozmer-1)-50, this);
}
}
and extends JComponent class.
I would like to have both button and my Labyrint in one window. Can anyone help me please? Thank you so much.
EDIT: After overriding getPreferredSize() in GameComponent it paint both, altough the Labyrinth is cut and button is in the middle right :(

Adding JLabels to a Panel inside a Panel inside another Panel

I have one "main" panel. I'd like to have a "side" panel inside the main one. The side is composed of two other panels, let's call one graphicPanel and one supportPanel. I'm trying to add labels to the SupportPanel from the main one, but no changes happen.
Here is my side panel:
public class LateralSupportPane extends JPanel{
private final static int WIDTH = 240;
private final static int HEIGHT = 740;
private GraphicPanel gp;
private SupportPanel sp;
public LateralSupportPane(){
this.gp = new GraphicPanel();
this.sp = new SupportPanel();
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
this.setLayout(new GridLayout(2, 1));
//this.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(gp);
this.add(sp);
this.setVisible(true);
}
public void addLabel(String label){
sp.addLabel(label);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
gp.paintComponent(g);
}
public void addLabel(String label){
sp.addLabel(label);
}
Here my supportPanel:
public class SupportPanel extends JPanel{
private JLabel label;
private final static int WIDTH = 240;
private final static int HEIGHT = 370;
public SupportPanel(){
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
label = new JLabel();
label.setText("<html>BlaBla</html>");
this.setLayout(new GridLayout(10, 1));
this.add(label);
this.setVisible(true);
}
public JLabel getLabel() {
return label;
}
public void addLabel(String text){
JLabel label = new JLabel(text);
if(this.getComponentCount() < 10){
this.add(label);
} else {
this.remove(0);
this.add(label);
}
}
From the main panel I call the addLabel of the side panel.
EDIT: Here is the frame with all panels. The board itself is a panel added into a frame. The board also has another panel, that are the black rectangle and the area where the string is, together. Then the side panel is composed by 2 other panels, the GraphicPanel (the black rectangle) and the supportPanel, that is the area where I'd like to have my labels.
Board
Validating all panels made no progress.
Not sure if i undurstend it correctly, but it seams, that you have to validate your panels after inserting new label;
public static void main(String[] args) {
JFrame frame = new JFrame("test");
frame.setSize(900, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new CardLayout());
frame.setVisible(true);
LateralSupportPane p = new LateralSupportPane();
frame.add(p);
frame.validate();
p.addLabel("test 2");
p.validate();
}
as you see, after adding a label, validation is performed and object is painted on form.
your method addLabel(String label) should have this method called at end of it.

Categories