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);
}
}
}
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.
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:
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!
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.
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.