Hi, first time poster, and fairly new to java swing.Im trying to make a scrabble game and am stuck while trying to place a letter on the board, or even removing one for that matter. The playing board is just an array of JButtons all derived from a ScrabbleButton object, some are subclassed for double word scores or player tiles. The problem is, I cant place a tile on the board by overwriting one of the buttons in the array with a new ScrabbleButton object


here is the code for the board being initialised

public void buildBoard()
		{
			layout= new GridLayout(15,15);
			
			board.setLayout(layout);
		
			
			
			for(int i=0;i<button.length;i++)
			{
			button[i] = new ScrabbleButton();
			}
			
			
			
			//top left double word placement
			button[16]= new DoubleWordButton();
			button[32]= new DoubleWordButton();
			button[48]= new DoubleWordButton();
			button[64]= new DoubleWordButton();
			
			//top right double word placement		
			button[28]= new DoubleWordButton();
			button[42]= new DoubleWordButton();
			button[56]= new DoubleWordButton();
			button[70]= new DoubleWordButton();
			
			//lower left double word placement		
			button[196]= new DoubleWordButton();
			button[182]= new DoubleWordButton();
			button[168]= new DoubleWordButton();
			button[154]= new DoubleWordButton();
			
			//lower right double word placement		
			button[208]= new DoubleWordButton();
			button[192]= new DoubleWordButton();
			button[176]= new DoubleWordButton();
			button[160]= new DoubleWordButton();

			
			
			
			//Manual Placement of Triple Word Scores 
			button[0]= new TripleWordButton();
			button[14]= new TripleWordButton();
			button[105]= new TripleWordButton();
			button[119]= new TripleWordButton();
			button[210]= new TripleWordButton();
			button[224]= new TripleWordButton();
			button[7]= new TripleWordButton();
			button[217]= new TripleWordButton();
			button[112]= new CenterButton();
						
			//placement of double letter buttons
			button[3]= new DoubleLetterButton();
			button[11]= new DoubleLetterButton();
			button[36]= new DoubleLetterButton();
			button[38]= new DoubleLetterButton();
			button[45]= new DoubleLetterButton();
			button[52]= new DoubleLetterButton();
			button[59]= new DoubleLetterButton();
			button[92]= new DoubleLetterButton();
			button[96]= new DoubleLetterButton();
			button[98]= new DoubleLetterButton();
			button[102]= new DoubleLetterButton();
			button[108]= new DoubleLetterButton();
			button[116]= new DoubleLetterButton();
			button[122]= new DoubleLetterButton();
			button[126]= new DoubleLetterButton();
			button[128]= new DoubleLetterButton();
			button[132]= new DoubleLetterButton();
			button[165]= new DoubleLetterButton();	
			button[179]= new DoubleLetterButton();
			button[172]= new DoubleLetterButton();
			button[186]= new DoubleLetterButton();
			button[188]= new DoubleLetterButton();
			button[213]= new DoubleLetterButton();
			button[221]= new DoubleLetterButton();
			
			
			
			
			
			//placement of triple letter buttons
			button[20]= new TripleLetterButton();
			button[24]= new TripleLetterButton();
			button[76]= new TripleLetterButton();
			button[80]= new TripleLetterButton();
			button[84]= new TripleLetterButton();
			button[88]= new TripleLetterButton();
			button[136]= new TripleLetterButton();
			
			button[140]= new TripleLetterButton();
			button[144]= new TripleLetterButton();
			button[148]= new TripleLetterButton();
			button[200]= new TripleLetterButton();
			button[204]= new TripleLetterButton();
			button[207]= new TripleLetterButton();
			
			for(int i=0;i<button.length;i++)
			{
				button[i].addActionListener(this);
			}
			
			for(int i=0;i<button.length;i++){
				board.add(button[i]);
				}

at the moment i have a separate button to trigger a change, here is the listener:

public void actionPerformed(ActionEvent e)
		{
			

			
			
			if(e.getSource()== actionButton)
			 {
				this.button[7]= null;
                                this.button[7]= new PlayerTile("Z");
				this.validate();
				this.repaint();
			 }
					
		}

thats just a snippet but its the spot where i think im going wrong. The button listener is working because i can use it to alter border colour etc. Until i solve the problem Im only trying to replace the 8th square in the scrabble board. Ive seen similar posts that solve the problem with the validate() and repaint() functions but no joy! Any help would be appreciated because it has me stumped and i think its just some step ive overlooked on the swing side of things.

Thanks :)

What the error/bug are you seeing? You mean it does nothing at all or it throws an exception on your console?

There is no error, when i change the ScrabbleButton in the array it does not visually appear as changed, nor when i try to remove it do the rest of the buttons shift

OK, I am not sure whether you need to actually render the whole page instead of delete one and repaint. The reason is that the old object is still attached to the panel you are displaying. Even though you discard it from your variable, the display is still there. You need to remove the object from the panel display before you discard the object from your variable.

this.button[7] = null  // <-- You just discard the object from your variable
                       //     but the physical object is still in your display.
                       //     Therefore, repaint won't help because it still
                       //     have the old object in it.

This didnt work, although i did manage to remove the board array of buttons from the border jpanel and make it reappear which is a first. adding the code in lines 3 and 4 doesnt make a change when the board is added again and repainted.

this.border.remove(board);
				this.button[5]= null;
				this.button[5]= new DoubleLetterButton();
				this.border.add(board,BorderLayout.CENTER);
		
				this.border.revalidate();
				this.border.repaint();

DoubleLetterButton is a subclass of scrabblebutton on of which it is replacing on line 4, I thought this was possible but is this where i am going wrong??

Hmm... You may read this especially where the TestFrame.java is to verify how to remove the object. You seems to remove the whole board instead of the button??? However, you could removeAll() and recreate the board again, but that may be too slow.

Edited 5 Years Ago by Taywin: n/a

yes i tried to remove the whole board, is there some special way to remove a button from an array other than overwrite? Still stuck with this its so frustrating!

If you want to specify and replace a component at a particular grid position, you should switch to GridBagLayout.

Store the gridx and gridy values in your ScrabbleButton class as you add them to the panel. On click, you will know which component to remove and replace in your layout. You can remove it with a direct reference to the object. Add your new button to the container with the gridx and gridy values of the button you're replacing.

Edit: You could also create an extended JPanel component like "BoardSlot" that displayed your button. If both components had references to one another, you could swap out your buttons without removing anything from the top-level board container.

Edited 5 Years Ago by Ezzaral: n/a

no this thread is full of missintepretations,

1/ unknow GUI with static JComponents & Methods (tons of tutorials and runnables examples)
2/ unknow List<JPanel> myPanels = new ArrayList<JPanel> (lots of mistakes inc null prerformance)
3/ good concept doesn't required created JComponents on RunTime
4/ good concept doesn't *** by created JComponents on RunTime
5/ all posts in this treads are about ***,
6/ good concept doesn't required this.button[7] = null
7/ nothing special, just about concepts and Runtimes rules
8/ ActionPerformed isn't best of for creations anything on Runtime, java.swing.Action is near to be thread safe
9/ there are conflict on EDT

to OP please to try for test purposes container.setVisible(fasle), remove/add/change containers content, (excelent would be if you are to able to use java.swing.Timer (100ms) or pack Visible#true inside InvokeLater)then container.setVisible(fasle), result that's speaking about EDT issues

Edited 5 Years Ago by mKorbel: n/a

@mKorbel: I'm really trying to understand what you have written, but honestly I cannot. It just doesn't make any sense to me.

Really I don't think there is any reason to replace a tile button in the layout. Just change what it is displaying. A tile is initially empty and then displays the letter you placed on it. That doesn't require a new JButton.

hmmm, I'm don't understood this reply too :-), I will try to be decoded my Navajo

this thread plagued with a lack of knowledge of Swing, nor about Action, Timer and EDT

create 15x15 of JButtons on EDT (from ActionListener) is complete nonsense and takes a few seconds just for initialize of plain vanilla JButtons, this's job just for BackGround Task

never, never and why to set myButtonArray[int]= null; or replace that with new JButton, :-) <phaaa> someone very long reading similair posts </phaaa> :-)
- JButton properties, can be changed at any time as you wanted with validate + repaint, packed into InvokeLater,
- there is a presumption that was used some LayoutManager

any changes on Runtime are job for java.swing.Timer(shortDealay but more that NativeOs Latency >70 and <150) + java.swing.Action + (feel free to use) Visible#false/true for JPanel that' contains JButton

Edited 5 Years Ago by mKorbel: timer

Swapping out a single button in the layout would not pose a performance problem, but I agree that rebuilding the whole thing is unnecessary and undesirable.

Since little info was given about the other responsibilities of ScrabbleButton and the rest of the program, it's hard to make good suggestions on how things might be better organized. It seems the button just needs to change it's text and there is no reason to remove it from the GUI at all.

This article has been dead for over six months. Start a new discussion instead.