Question

I have some code for a Scrabble Game I am writing (actually rewriting), and it is split up into 3 classes so far. The Tile class seems to be generating a BorderFactory artifact when it is put in the window. Why is this artifact appearing, and how can I eliminate it?

*If you don't see the artifact, try resizing the window slowly.

Here is the Scrabble class.

import javax.swing.JFrame;
import java.awt.BorderLayout;
public class Scrabble extends JFrame implements Runnable
{
  public Board board;
  public Scrabble()
  {
    super("Scrabble!");
    board = new Board();
    addBorderLayoutObjects();
  }
  public void run()
  {
    makeSettings();
    setVisible(true);
  }
  public void makeSettings()
  {
    setSize(850, 900);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    //this.setResizable(false);
  }
  public void addBorderLayoutObjects()
  {
    getContentPane().add(BorderLayout.CENTER, board);
  }
  public static void main(String[] args)
  {
    Scrabble s = new Scrabble();
    javax.swing.SwingUtilities.invokeLater(s);
  }
}

Here is the Board class.

import javax.swing.JPanel;
import java.awt.Point;
import java.awt.Color;
import java.awt.GridLayout;
public class Board extends JPanel
{
  public Tile [][] board;
  public Board()
  {
    super(new GridLayout(15, 15));
    board = new Tile[15][15];
    makeBoard();
  }
  public void makeBoard()
  {
    for(int k = 0; k < 225; k++)
    {
      board[k/15][k%15] = new Tile(new Color(0xCBC4A8), Color.BLACK);
    }
    for(int a = 0; a < 15; a++)
      {
        for(int l = 0; l < 15; l++)
        {
          add(board[a][l]);
        }
      }
  }
}

And the Tile class.

import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Point;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
public class Tile extends JPanel implements MouseListener
{
  private Color color;
  private Color border;
  public Tile(Color _color, Color _border)
  {
    color = _color;
    border = _border;
  }
  public void mouseEntered(MouseEvent e){}
  public void mouseExited(MouseEvent e){}
  public void mousePressed(MouseEvent e){}
  public void mouseReleased(MouseEvent e){}
  public void mouseClicked(MouseEvent e){}
  @Override
  public void paintComponent(Graphics g)
  {
    g.setColor(color);
    setBorder(BorderFactory.createLineBorder(border, 2));
  }
}
Was it helpful?

Solution

This is your first problem (and possibly your second)

public void paintComponent(Graphics g)
{
    g.setColor(color);
    setBorder(BorderFactory.createLineBorder(border, 2));
}

Firstly, you must call super.paintComponent or take responsibility for its actions. This will clear and prepare the Graphics context for further painting.

Secondly, you should never modify any UI component from within a paintXxx method that may cause it be invalidated or repainted. Doing so will end you an infinite loop of burning CPU...

Set the border within the constructor or change it as the program needs, do not do so from within the paint method...

Updated with additional examples

When you need to change the border, simply call setBorder on the instance of the title you want change....

public Tile(Color _color, Color _border)
{
    color = _color;
    border = _border;
    setBorder(BorderFactory.createLineBorder(border, 2));
}

or

Title tile = new Tile(Color.RED, Color.BLUE);
//...
title.setBorder(BorderFactory.createLineBorder(Color.GREEN, 2));

Check out How to use borders for more info...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top