Is this an efficient way? ArrayList<JButton>

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 814 Views - Last Post: 22 June 2013 - 05:46 PM Rate Topic: -----

#16 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 2069
  • View blog
  • Posts: 4,307
  • Joined: 11-December 07

Re: Is this an efficient way? ArrayList<JButton>

Posted 22 June 2013 - 03:30 PM

I think you need two ActionListeners for this. One to start the game, the other to type a letter. Typically, I use anonymous inner classes for my action listeners. All they do is call another method which can then be tested independently. A lot of people prefer non-anonymous classes. YMMV.

Here is an initial restructuring of your code. The typing code looks up the letter directly from the button. No need for looking up in an array of buttons and no need for 26 instances of your listener (although that approach is fine too). You will still need an collection of buttons to reset them inbetween games.

I don't like using ints for the difficulty. An enum is better. A Map would be a nice way of converting from button to enum. However, since you use int values, a list lookup is concise enough.

	public Hangman() {

		ActionListener startGame = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent event) {
				startGame((JButton) event.getSource());
			}
		};
		
		easyButton.addActionListener(startGame);
		mediButton.addActionListener(startGame);
		hardButton.addActionListener(startGame);

		ActionListener typeLetter = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent event) {
				typeLetter((JButton) event.getSource());
			}
		};

		for (char c = 'A'; c <= 'Z'; c++) {
			JButton button = new JButton("" + c);
			button.addActionListener(typeLetter);
			somePanel.add(button);
		}
	}

	private void startGame(JButton button) {
		List<JButton> inOrder = Arrays.asList(easyButton, mediButton, hardButton);
		int difficulty = inOrder.indexOf(button);
		game = new Game(difficulty);
	}

	private void typeLetter(JButton button) {
		button.setEnabled(false);
		button.setBackground(Color.black);
		game.makeGuess(button.getText());
	}


Was This Post Helpful? 0
  • +
  • -

#17 cfoley  Icon User is offline

  • Cabbage
  • member icon

Reputation: 2069
  • View blog
  • Posts: 4,307
  • Joined: 11-December 07

Re: Is this an efficient way? ArrayList<JButton>

Posted 22 June 2013 - 05:46 PM

Quote

Typically, I use anonymous inner classes for my action listeners. All they do is call another method which can then be tested independently.


It's maybe worth mentioning that in Java 8 most people will be doing something similar to this, although the code will look a lot cleaner. Something like this:

	public Hangman() {
		easyButton.addActionListener(e -> {startGame(e);});
		mediButton.addActionListener(e -> {startGame(e);});
		hardButton.addActionListener(e -> {startGame(e);});
		
		for (char c = 'A'; c <= 'Z'; c++) {
			JButton b = new JButton("" + c);
			b.addActionListener(e -> {typeLetter(e);});
			somePanel.add(B)/>;
		}
	}

	private void startGame(ActionEvent event) {
		Object source = event.getSource();
		List<JButton> inOrder = Arrays.asList(easyButton, mediButton, hardButton);
		int difficulty = inOrder.indexOf(source);
		game = new Game(difficulty);
	}

	private void typeLetter(ActionEvent event) {
		JButton source = (JButton) event.getSource();
		source.setEnabled(false);
		source.setBackground(Color.black);
		game.makeGuess(source.getText());
	}



Interestingly, this ends up with 26 ActionListeners for the letters and 3 for starting the game. It's a lot cleaner though which is probably more important.
Was This Post Helpful? 2
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2