Link to home
Create AccountLog in
Avatar of mespinozae
mespinozaeFlag for Costa Rica

asked on

JInternalFrame needs a click to show up

Hello all,

I am creating a chess playing desktop application in Java. At this stage the program needs to open a PGN file (Portable Game Notation) and read a chess game, then show it in a board player.

Thus far everything is working as expected, the only part im having problems is that when the game is loaded it creates a new Board object (to show the game).

Here is a small hierarchy of how Ive set up things:
- juega/Login.java [ Handles the log in as it requires validation ]
- juega/MainScreen.java [ Handles the general layout and calls JInternalFrames as needed]
- visuals/pgnJTable.java [ shows the games list and creates the Board to replay ]

The problem:
  When creating the Board in the pgnJTable the JInternalFrame gets created but put behind something
  I have a JPanel to show a background image in the MainScreen's JFrame, this might be related...

Effect:
  Click on View Game and you get the MainScreen without any JinternalFrames, click anywhere and it shows the Board.

I have uploaded all the code to: http://justpurefan.com/Java/ with a compiled JAR

Any idea of what can be done? I do not want to have to click it to show it up....
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Any lengthy loading operations should be done on a separate thread and not in an event handler. Are you doing that? If not, use SwingWorker (well-documented)
Avatar of mespinozae

ASKER

The entire process is happening in a separate thread, in other words, when the ActionListener in MainScreen calls the choosePGN function the first thing this function does is create a new thread. In this thread the JFileChooser shows up, the function verifies the file, reads its content, creates a chessGame object, instantiates the pgnJTable object and displays the JTable with a button.

The creation of the other JInternalFrame where the Board is going to be shown therefore happens in this same thread.

So the stack trace should look like:
MainScreen::choosePGN
---> thread { showGamesInTable { createBoard } }
>>the first thing this function does is create a new thread. In this thread the JFileChooser shows up

That's not quite right. The file choose should be show in the event handler. What it does with the file should happen in a new thread. Showing the table should again happend in the EDT.

btw, how does the chess game fit in with the JTable?
>> The file choose should be show in the event handle
ok, I will move the JFileChooser routine to the ActionListener then and have it work from there. I just dont really like populating the ActionListener with lots of code and instead I have it call functions which handle all this code.

>> btw, how does the chess game fit in with the JTable?
The JTable only shows the information of the game (White Name, Black Name, Ratings, Result, Tournament...). The user has to click one of the shown games and then the button "View Game", the JTable is in a JInternalFrame and this JIF is disposed upon clicking this button and after creating the Board object (another JInternalFrame) passing as a parameter to the constructor the chess game information.

However it still puzzles me as to why the Board's JIF is not shown on top of everything as it should.

Do you think it has anything to do with the JPanel im using as a background image?
>>ok, I will move the JFileChooser routine to the ActionListener

That's right, though that alone will probably not solve the problem

>>Do you think it has anything to do with the JPanel im using as a background image?

That's not inconceivable. You mean you have a custom panel with a bkg image? If so, please post that class
This is the code for the background image, its a JPanel with an image on top, in the MainScreen class (which extends JFrame) I try this in the constructor:

       bgImage = new bgPanel("src/logo02.jpg");
       bgImage.setBackground(Color.WHITE);
       add(bgImage, BorderLayout.CENTER);
// file: visuals/bgPanel.java
package visuals;
 
 
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.image.*;
 
/**
 * Background image demo
 */
 
public class bgPanel extends JPanel {
  Image bgImage=null;
  String message="";
  
  public bgPanel(String path) {
     
	// double buffering
    super(true);
    
    try {
      getFileImage(path);
     
    }
    catch (Exception ex) {
      message="File load failed: "+ex.getMessage();
    }
  }
    @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
        if (bgImage!=null) {
      g.drawImage(bgImage,300,300,this);
      
    } else {
      g.drawString(message,40,40);
    }
  }
  private void getFileImage(String filePath) throws InterruptedException, IOException {
    FileInputStream in = new FileInputStream(filePath);
    byte [] b=new byte[in.available()];
    in.read(b);
    in.close();
    bgImage=Toolkit.getDefaultToolkit().createImage(b);
    MediaTracker mt=new MediaTracker(this);
    mt.addImage(bgImage,0);
    mt.waitForAll();
  }
  
}

Open in new window

Ok think this is a little bit more demanding than to be worth only 100 points so im raising it to 250.

Update:
  I tried now instead of a JPanel drawing an image I tried with a JPanel using a Border, like the first code Snippet here.
 The problem is a little better now, when calling the Board (a JInternalFrame ) it is shown right away, but transparent so the image from the JPanel can be seen as if it was on top of the JInternalFrame, the letters of the JIF are shown however and it has the focus...

So maybe, if we can the JIF to be "non transparent" it will be fine.

The Board inherits from JinternalFrame and im using an inner class to draw the board (thus far not implemented), tried setting the Board's JIF background color to White and the image is still showing, tried setting the background color for the Board's inner class (which is a JPanel) and no change, the image is still showing.

The second piece of code is the Board class code, in case there is anything you want to check out.


/************ visuals/bgPanel.java *******************************/
package visuals;
 
import java.net.MalformedURLException;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.image.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.border.Border;
 
 
public class bgPanel extends JPanel {
 
    Image bgImage = null;
    String message = "";
 
    public bgPanel(String path) throws MalformedURLException, IOException {
 
        // double buffering
        super(true);
 
        final Border bkgrnd = new CentredBackgroundBorder(ImageIO.read(new URL(path)));
        this.setBorder(bkgrnd);
        this.setFocusable(false);
 
    }
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponents(g);       
    }
}
/*******************************************/
/************ juega/Board.java *******************************/
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package juega;
 
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
 
/**
 *  Talbero, la clase mas importante de todas....
 * Necesita:
 *      Constructor(Partida) => Reproduce partida que viene de parametro
 *      Constructor(Jugador oponent, ColorMio, Tiempo Inicial, Tiempo Incremento, Con Rating?) => partida
 *      Constructor(Partida, int Monitorear) => Para reproducir partidas en vivo
 * 
 */
/**
 *
 * @author purefan
 */
public class Board extends JInternalFrame implements ActionListener {
 
    // De quien es el turno a jugar
    private boolean isWhitesTurn = true;
    // nombre del oponente
    private String opName;
    // nombre mio
    private String myName;
    // control de mi tiempo
    private int myTimeLeft;
    // control de su tiempo
    private int opTimeLeft;
    // a container
    private JPanel _contenedor;
    // btns
    private JButton btnNext;
    private JButton btnPrev;
    private JButton btnEnd;
    private JButton btnStart;
    // partida que estamos reproduciendo
    //private Partida enCurso;
 
 
    public Board(Partida partida) {
        // the constructors parameter is the chess Game
        _contenedor = new MyPanel();
        this.setMaximizable(true);
        this.setBackground(Color.white);
    // another attempt to hide the background image
        this.requestFocus();
        this.add(_contenedor);
 
    }
 
 
 
       public void actionPerformed(ActionEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
  
 
    // Auxiliary class
    class MyPanel extends JPanel implements MouseListener{
 
        public MyPanel() {
            setBorder(BorderFactory.createLineBorder(Color.black));
            this.setBackground(Color.WHITE);
        }
 
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(250, 200);
        }
       
 
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            
 
            // Draw Text
            // Draw basic board constraints
            int width = this.getWidth();
            int height = this.getHeight();
            int dist = width / 8;
            // draw border:
            g.drawRect(0, 0, width, height);
            /*for(int i = 0; i < 0; i++){
                // dibujar las lineas verticales del Board
                g.drawLine(i*dist, 0, i*dist, height);
            }*/
            g.drawString("This right here should not need a click to show up!", 10, 20);
        }
 
    
 
     
 
      
 
    
       
    }
 
 
}

Open in new window

Progress01.JPG
OK - i'll try to take a look later. In a case like this, you'll probably need to make it runnable for me
ASKER CERTIFIED SOLUTION
Avatar of mespinozae
mespinozae
Flag of Costa Rica image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
No problem - glad it's sorted out