views:

80

answers:

3

Hello! I'm building a Tic Tac Toe game in Java with a Swing GUI, and it renders correctly in Ubuntu 10.4 and Windows XP. This is how it looks like in Ubuntu:

http://img266.imageshack.us/img266/2432/tictactoe2.png

When I copied the bin-folder with all the class files and tried to run the program in Windows 7 it looked like this instead:

img413.imageshack.us/img413/6144/tictactoe1.gif
img708.imageshack.us/img708/4387/tictactoe2.gif

I just can't understand what's wrong. As I said, it works perfectly in Ubuntu 10.4 and Windows XP.

I would be very happy if someone could help me out! I'll post the code related to the GUI, just in case it is needed to solve the problem.

Here is the code I use to initialize the GUI:

//Initializing GUI.
    frame = new JFrame();  //Creating the window.
    frame.setTitle("Tic Tac Toe"); //Setting the title of the window.
    frame.addMouseListener(this);
    frame.getContentPane().add(BorderLayout.CENTER, grid.getPanel());  //Adding the grid panel.
    info = new JLabel(" Initializing game...");         //Creating info text.
    frame.getContentPane().add(BorderLayout.SOUTH, info);  //Adding info text.

    //Setting GUI properties.
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300, 300);
    frame.setVisible(true);

The panel with the grid itself is created in my GameGrid class, which have a method "JPanel getPanel()". Here is the initialization of that panel (the code belongs in the constructor of GameGrid):

     GridBox temp;
    layout = new GridLayout(getHeight(), getWidth());
    panel = new JPanel(layout);
    panel.setBorder(
        BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder("Click in a box to place a marker:"),
                    BorderFactory.createEmptyBorder(5,5,5,5)));

    //Creating a GridBox for each cell, and adding them to the panel in the right order..
    for(int i = 0; i < getHeight(); i++) {    
        for(int j = 0; j < getWidth(); j++) {
            temp = new GridBox(j, i);
            temp.addMouseListener(listener);
            panel.add(temp);
        }
    }

GridBox is a subclass of JPanel, which I modified to automatically show the contents of the grid at the coordinates specified.

class GridBox extends JPanel {
    private static final long serialVersionUID = 1L;
    int fontsize, x, y, value, signHeight, signWidth;
    char print;
    FontMetrics fm;
    LineMetrics lm;

    public GridBox(int a, int b) {
        x = a;     //TODO - input control
        y = b;
    }

    public Move getMove() {
        Move m = new Move(x, y);
        return m;
    }


    public void paintComponent(Graphics g) {
        Border blackline = BorderFactory.createLineBorder(Color.black);
        setBorder(blackline);
        Dimension size = getSize();
        Rectangle2D rect;
        fontsize = (int)(size.getHeight()*0.75);
        value = getGridValue(x, y);
        if(value == EMPTY)
            print = ' ';
        else if(value == 0)
            print = 'X';
        else if(value == 1)
            print = 'O';
        else
            print = (char)value;


        Font font = new Font("Times New Roman", Font.PLAIN, fontsize);
        g.setFont(font);
        fm = g.getFontMetrics();
        rect = fm.getStringBounds(Character.toString(print), g);
        signHeight = (int)rect.getHeight();
        signWidth = (int)rect.getWidth();


        g.setColor(Color.black);
        g.drawString(Character.toString(print), (size.width/2)-(signWidth/2), (size.height/2)-(signHeight/2)+fm.getAscent());
    }
}

Thanks in advance!

+4  A: 

There's an obvious problem in the you change the border whilst repainting the component. That's going to cause all sorts of problems.

Tom Hawtin - tackline
Thanks a lot! I moved "Border blackline = BorderFactory.createLineBorder(Color.black); setBorder(blackline);" to the constructor, and now it works!But why didn't it work before I did that? I realize, of course, that it is unnecessary to set the border every time the component is painted, but I can't understand how that could cause so much trouble..
Greensea
@Greensea It'll change the offsets, and presumably invalidate layout up the component tree. I think it's safe to say that all bets are off at that point.
Tom Hawtin - tackline
Ah, I think I understand now. I thought setBorder() replaced the old border with the new one, but obviously that's not how the method works. Thanks for the help!
Greensea
+1  A: 

Also, I don't see where you paint the background of the panel. You should have

super.paintComponent(g);

at the top of the method.

camickr
A: 

camickr: Oh, since the constructor takes an argument it isn't called automatically, right?

(I'm Greensea who posted this question, I wasn't able to log in the same way as before)

Greensea