Dynamiczne tworzenie nowych komponentów. Jak to zrobić?

0

Witam.
Chciałbym aby mój program po wciśnięciu JButtona pobierał z z listy wybraną wcześniej liczbę, a następnie generował nowe komponenty (JTextField) w ilości równej tej liczbie. (Później jeszcze będę chciał pobierać z tych pól wpisane wartości ale na razie to pomijam).

Javę konsumuję dopiero od ok miesiąca, także proszę o wyrozumiałość i nie krytykowanie mnie:)
Wszystko zjadam na platformie ECLIPSE( jeśli to ma jakieś znaczenie).

Mam taki oto kod i brakuje mi pomysłu jak zrobić coś takiego jak opisałem wyżej(chcę aby te nowe JTextField'y pojawiały się w panelu 2):

import java.awt.*;
import javax.swing.*;

import java.awt.event.*;
import java.applet.*;
import java.awt.event.ActionListener;
public class wykres extends JApplet implements ActionListener {
	
    JButton guzik;
    JComboBox lista;
    JPanel panel1, panel2;
    JLabel napis;
    
    public void init()
    {    	
    	this.setSize(700,700);
    	this.setLayout(null);
        
        panel1 = new JPanel();
        this.add(panel1);
        
        napis = new JLabel("Ile wartości wprowadzić? ");
        panel1.add(napis);
                
        panel2 = new JPanel();
        panel1.add(panel2);        
        
        guzik = new JButton("ok");
        guzik.addActionListener(this);
        panel1.add(guzik);
      
        lista = new JComboBox();
        lista.setEditable(false);
        lista.addItem(2);
        lista.addItem(3);
        lista.addItem(4);
        lista.addItem(5);
        lista.addItem(6);
        panel1.add(lista);
       
    }
    
    
    public void actionPerformed(ActionEvent e) 
    { 
      if (e.getSource() == guzik) 
      { 
    		  int x =(int) lista.getSelectedIndex();
    		  int x1 = x+2;
    		  
    		  	panel2.removeAll();
    		  	for (int i=1;i<=x1;i++)
    	  		{
    	  			panel2.add(new JLabel("Wartość "+i+":"));
    	  			panel2.add(new JTextField(4));
    	  		} panel2.revalidate();
    	  		
      }
     }
    

    public void paint(Graphics g)
    {
        guzik.setBounds(60,30,50,25);
        lista.setBounds(20, 30, 35, 25);
        napis.setLocation(10, 10);
        
        panel1.setLayout(null);
        panel1.setBounds(0, 0, 700, 700);
        panel1.setBackground(Color.LIGHT_GRAY);
                
        panel2.setBounds(500, 25, 150, 400);
        panel2.setBackground(Color.GRAY);
        
       super.paint(g);
        
      
    }
    

  
}

EDIT:

Problem mam po części rozwiązany: robią mi się dynamicznie JTextField'y(dodałem nowy kod do akcji guzika) ale mam za to kolejny problem: używam validate() aby po zmianie liczby na liście i ponownym kliknięciu w "ok" wszystkie komponenty z panelu 2 znikały i pojawiały się od nowa. Efekt jest taki że wszystkie komponenty znikają ale ich zanik polega na tym że nie mogę w polach wpisać ale nadal je widzę. (znikają dopiero jak rozciągam sobie okienko).
Nie wiem też jak dodać etykiety do każdego tekstfield'a abym później mógł z nich pobierać dane:(

0

Nie rozumiem po co tworzysz dwa okienka:

       panel1 = new JPanel();
        this.add(panel1);
 
        napis = new JLabel("Ile danych chcesz wprowadzić? ");
        panel1.add(napis);
 
        panel2 = new JPanel();
        panel1.add(panel2); 

spokojnie możesz dodawać komponenty od paneli -> JPanel. Ogólnie to jest taka zasada: tworzysz jedno okienko i ładujesz do niego tyle paneli (JFrame) ile potrzebujesz. Wykorzystanie np z GridBagLayout albo z Box daje możliwość dowolnego rozmieszczenia komponentów w okienku.

Ja by zrobił to w ten sposób:
najepiej osobne pliki, wtedy nie masz chaosu.

plik z klasą JPanel:

import ...
class Cokienko extends JPanel
{
private Cpanel panel;
public Cokienko()
 {
 setSize(szerokosc, wysokosc);
 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//aby po nacisnięciu "krzyżyka" kończył się proces programu a nie tylko stawał się nie widoczny
 Container kontener=getContentPane();
 panel=new Cpanel();
 kontener.add(panel);
 setVisible(true);
 }
}
//koniec klasy

import ...
plik z klasą JFrame:

class Cpanel extends JFrame
{
private boolean zmiana_krajobrazu;
public Cpanel()
 {
 zmiana_krajobrazu=false;
 //tutaj tworzysz swoje komponenty
 }


//nie jest to za dobre rozwiązanie ale na początek starczy:
public void paintComponent(Graphics g)
 {
 super.paintComponent(g);
 if(zmiana_krajobrazu==false)
  {
  add(poczatkowe komponenty)
  }
 else
  {
  add(komponenty po wcisnieciu przycisku)
  }
 }
}


 

musisz polaczyc jeszcze przycisk z polem zmiana_krajobrazu. Po wcisnieciu zmienia się na true i wywoływane jest repaint().

Powinno działać:)

0

tworzę dwa panele po to aby w drugim umieścić wszystkie pola do których będę wpisywał dane.... a po ponownym wciśnięciu w przycisk "guzik" cała zawartość drugiego panelu z utworzonymi komponentami się usuwa po czym komponenty będą generowane od początku:)
nie jestem jeszcze aż tak zaawansowany aby pracować na plikach i importować to i owo ( bo jeszcze takich rzeczy nie potrafię).

I jak na razie już wymyśliłem jak moje komponenty maja być generowane:) Teraz nie wiem jak zrobić coś takiego żeby te komponenty mi znikały do końca tak jak powinno byc? Niby mi te pola kasuje ale nadal je widzę i żeby całkowicie znikły muszę poruszać krawędzią apletu.

A chyba jeszcze większy mankament mam taki że nie wiem jak później mam dynamicznie pobrać dane z tych wygenerowanych pól, bo polom tekstowym nie można nadać etykiety:( Jak pobrać dane z tych pól?

0

Utwórz dodatkowe pole w klasie typu np. ArrayList<JTextField> pola, a obsługe przycisku napisz tak:

      if (e.getSource() == guzik)
      {
                      int x =(int) lista.getSelectedIndex();
                      int x1 = x+2;

                              panel2.removeAll();
                              pola.clear();
                              for (int i=1;i<=x1;i++)
                              {
                                      panel2.add(new JLabel("Wartość "+i+":"));
                                      JTextField tf=new JTextField(4);
                                      panel2.add(tf);
                                      pola.add(tf);
                              } 
                              panel2.revalidate();
                              panel2.repaint(); //tego brakowało

      }
     }

Zawartość konkretnego pola odczytasz tak

  pola.get(i).getText();
0

Niby wiem o co chodzi z tym ArrayList ale mi się wysypuje wszystko po kliknięciu w "guzik". ( co ciekawe na początku jak zrobiłem tego text araya to wszystko działało a jak zacząłem dalej robić pętlę czytającą dane z pól to przestało działać- nawet jak powróciłem do tego co miałem wcześniej:( ).

Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException
at wykres.actionPerformed(wykres.java: i tutaj linijka kodu)

pojawiają się dwa takie błedy ze wskazaniem na linijki kodu w których pojawia się "pola" tj

pola.clear();

i

pola.add(tf);

a później pokazują się błędy (Unknown Source)

tak to wygląda jak bym źle zadeklarował ArrayList :( a wcześniej mi działało.

0

Zadeklarowałeś pewnie dobrze, ale nie utworzyłeś. Dodaj (w metodzie init())

 pola = ArrayList<JTextField>();
0

dokładnie tak jak napisałeś- jak napisałem tamtego posta to chwile potem zdałem sobie z tego sprawę.
Bardzo mi pomogłeś. PZDR

1 użytkowników online, w tym zalogowanych: 0, gości: 1