Randon de string em um JTable

Pessoal ja procurei no forum mas não encontrei oque estou tentando fazer, se alguém puder me ajudar agradeço. A minha dúvida é a seguinte.
Tenho um vetor de string com nomes, quero selecionar aleatoriamente esses nomes e lançar para um Jtable, mas não sei como fazer isto. Ha tem uma condição os nomes não podem repetir mais de 2 vezes seguidas em cada coluna. Se alguem puder me ajudar fico grato.
Abaixo o fonte do que eu consegui.


import java.awt.Color;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;

public class Tabela extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JTable jTable = null;

	
	public Tabela() {
		super();
		initialize();
	}

	private void initialize() {
		this.setSize(446, 288);
		this.setResizable(false);
		this.setContentPane(getJContentPane());
		this.setTitle("JFrame");
	}

	
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(getJTable(), null);
			jContentPane.add(getJButton(), null);
		}
		return jContentPane;
	}

private JButton jButton = null;  
String[] nome = {"Paulo","Carlos","Maria"}; 
String nomes;
//Paulo deve repetir 4 vezes
//Carlos deve repetir 2 vezes
//Maria deve repetir 3 vezes
//Observação nenhum nome pode repetir mais de 2 vezes na mesma coluna.


	private JTable getJTable() {
		if (jTable == null) {
			jTable = new JTable(3,3);
			jTable.setRowHeight(25);
			jTable.setBackground(Color.yellow);
			jTable.setEnabled(true);
			jTable.setBounds(new Rectangle(43, 142, 351, 75));
		}
		return jTable;
	}

	
	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton();
			jButton.setBounds(new Rectangle(233, 45, 145, 35));
			jButton.addActionListener(new ActionListener(){
		        public void actionPerformed(ActionEvent e) {
		        	MandarNomes();
		        	}
		        	
			    	
			        });
		}
		return jButton;
	}
	public void MandarNomes(){
		
		for(int i=0;i<=8;i++){
			Random randomNum = new Random();   
			this.nomes = nome[randomNum.nextInt(3)];   
		        System.out.println(nomes);
		     
			
		}
		}

	
} 

esquece a JTable…
vc ta confuso com o negócio dae

vc pode fazer assim… usar um método que sorteia os nomes de uma coluna e armazena num arraylist, dae vc passa esse arraylist pra table normalmente…


public ArrayList getColunaNomes() {

   String nomes[] = new String { "Paulo", "Joao","Vivian" };

   ArrayList<Integer> nomesSorteados = new ArrayList<Integer>;

   for ( int i = 0; i < suaTabela.getRowCount(); i++ ) {

      int sorteado = -1;

      // agora aqui da pra usar métodos mais práticos como a recursividade pra fazer isso.. fiz do jeito mais rapido mesmo
      // aqui ele só adiciona no array enquanto o numero sorteado nao existir no array
      for( ; ; ) {

         // pra dar um numero de 1 a 3.. vc teria q mudar isso pro numero de nomes q tem no seu array
         sorteado = (int) Math.round(Math.random()*2)+1; 

         // se o nome ja existe, executa novamente o random.. senão, sai do for com um break
         if (!nomesSorteados.contains( sorteado )) {
            break;
         } 
      }

      nomesSorteados.add( nomes[sorteado] ); // coloca um dos nomes sorteados no arraylist
   }

}

elaborei um algoritmo para fazer o sorteio, mas tem que tomar cuidado para não entrar em loop infinito com situações como 3 nomes distintos e 7 colunas na tabela, pois é impossível preencher a coluna repetindo no máximo 2 vezes o mesmo nome.

[code]String nomes[] = new String {“Paulo”, “Joao”,“Vivian”};
String tabela[][] = new String[3][3];
for(int i=0; i<tabela.lenght, i++) {
loop1: for(int j=0; j<tabela[i].lenght, j++) {
tabela[i][j] = sorteiaProximo(nomes, tabela[i]);
}
}

public static String sorteiaProximo(String elementos[], String jaSorteados[]) {
Random r = new Random();
while(true) {
String sorteado = elementos[r.nextInt[elementos.lenght]];
int existe = 0
for(int i=0; i<jaSorteados.lenght; i++){
if(jaSorteados[i].equals(sorteado))
existe++;
}
if(existe<2)
return sorteado;
}
} [/code] Obs: código não compilado

Até!

Cuidado. Testar na lista se um nome existe e então sortea-lo novamente é um processo extramamente ineficiente, principalmente se o número de nomes for próximo ou menor do que o número de colunas (o que é o caso).
O ideal é você embaralhar a lista, depois usar a lista embaralhada.

Assim você pode pegar um nome por vez, sem a preocupação dele já ter sido inserido ou não. Se a lista de nomes acabar, embaralhe-a novamente e continue o processo.

public List<String> getColunaNomes(int quantidade) {
   List<String> nomes = Arrays.asList(new String[] { "Paulo", "Joao","Vivian" });
   List<String> sorteados = new ArrayList<String>();

   //Garante que a lista de nomes irá começar embaralhada
   //Talvez vc pode atribuir 0 se vc puder começar de um conjunto inicial.
   int count = nomes.size();

   //Repete enquanto a quantidade de nomes indicada não foi sorteada
   while (sorteados.size() < quantidade) {
       if (count == nomes.size()) {
          //Se todos os nomes foram usados, embaralha a lista e começa de novo
          count = 0;
          Collections.shuffle(nomes);
       }
       sorteados.add(nomes.get(count));
       count = count + 1;
   }
}

Para que o nome não se repita mais do que duas vezes, basta ter uma lista de nomes que corresponda a pelo menos a metade do tamanho do número de colunas.

Só a título de exemplo, uma usuária do GUJ já teve um problema com a abordagem de “sortear e testar que existe”, ao ponto da aplicação J2ME dela travar:

A solução foi usar o algorítmo que propus acima.

Muito obrigado pessoal vou dar uma olhada nos códigos e ver se consigo resolver meu problema.

Boa ViniGodoy, sempre que foi necessário sortear alguns valores sem repetir eu ia sorteando até encontrar um valor valido, agora percebo que não é uma boa ideia, pois como você mesmo disse, pode acontecer de demorar um seculo para encontrar esse valor ou encontrar na primeira tentativa, levando o programa a demorar um tempo incalculável!

Vivendo e aprendendo! :smiley:

Até!

Esse processo só é interessante se seu espaço amostral é muito maior do que o número de amostras que vc vai retirar. Isso é, vc tem, por exemplo, 1000 números possíveis, e vai escolher só 5.
Possivelmente vc vai conseguir sortear os 5 sem problemas.

Se o tamanho for próximo ou inferior (100 números para escolher 99) o esforço para escolher os últimos números será incrível. Nesse caso, é melhor usar o sort.

O sort da lista tem tempo de O(n), onde N é o tamanho da lista.
Uma outra vantagem desse algorítmo é que seu tempo é constante, o que pode ser importante se vc precisar de previsibilidade.

Obrigado pelas informações! é por isso que adoro tanto esse fórum!

Pessoal as strings estão saindo aleatorias como eu queria, mas não estou conseguindo introduzilas na tabela 3x3 na forma acima em que em cada coluna cada nome não pode repetir mais de 2 vezes, é que estou começando java agora e não sei muita coisa.

Apos ter o algorítimo de sorteio, é só criar um TableModel que satisfaça sua necessidade, a assinatura do construtor pode ser a seguinte:

public MyTableModel(String[] titulos, List<String>... colunas ){...}

depois na hora de construir a JTable pode ser assim:

... MyTableModel model = new MyTableModel(new String[] {"Coluna 1", "Coluna 2", "Coluna 3"}, getColunaNomes(3), getColunaNomes(3), getColunaNomes(3)); JTable tabela = new JTable(model); ...

hehe ficou feia a assinatura, mas nada que uns getter e setter não resolva :smiley: