Kłopot z porównaniem tekstu TextField z tekstem w bazie

0

Witam,

Piszę okienkową aplikację z użyciem Swing. Stworzyłem sobie okienko do logowania. I teraz mam problem z porównaniem tego co wpisuje w okienkach logowania z tym, co mam zapisane w bazie. Robię to w następujący sposób:

	Connection conn = null;
		try {
			Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance();
			conn = DriverManager.getConnection(url, user, password);
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery("SELECT * FROM LOGOWANIE");
			while (rs.next()) {
				if ( (rs.getString("user") == l.getJTextFieldUser()) && (rs.getString("pass") == l.getJPasswordFieldPass()) )
					//operacja1
				else 
					//operacja2
			}
			rs.close();
			stmt.close();
			conn.close();
		} catch (Exception e) {
			System.err.println(e.getMessage());
		  } 

getJTextFieldUser() i getJPasswordFieldPass() są to metody innej klasy, które zwracają stringi z wpisanym do nich tekstem.

Cokolwiek nie wpisałbym w okienku to zawsze wykonuje się operacja2. Nawet jak poprawny login wpiszę. Dodatkowo nawet jak porównam rs.getString("user") == "admin", czyli z takim samym stringiem jak mam zapisane w bazie to nadal wykona się operacja2, czyli w else. Nie mam pojęcia w jaki sposób mogę to porównać, żeby zwracało mi poprawnie. Dodam, że połączenie z bazą działa mi prawidłowo, gdyż z samym wyświetlaniem danych z bazy nie ma problemów. Jeżeli potrzeba więcej informacji, to mogę wrzucić więcej kodu. Proszę o pomoc.

0

Operator == porównuje referencje. Zawartość stringów porównuje się tak: s1.equals(s2)

0

Tak trochę poza tym, to raczej lepiej w bazie przechowywać jakiś hasz hasła (np. SHA1 - java ma klasy do tego) zamiast oryginału hasła ;)

0

Juz teraz wszystko działa. bardzo dziękuję za pomoc. Dawno nie programowałem w Javie i zupełnie wypadło mi to z głowy.

A co do haseł w bazie, to muszę na szybko zrobić projekt na zaliczenie na poniedziałek, więc nie zagłębiam się w takie rzeczy.

0

Mam kolejny problem. Mianowicie odczytuję dane z bazy w taki sposób:

public static ResultSet pobierzDane() {
		try {
			Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_READ_ONLY);
			ResultSet rs = stmt.executeQuery("SELECT * FROM budowa");
			//conn.close();
			return rs;
			} catch (Exception e) {
				System.err.println(e.getMessage());
				return null;
			  }
	}

I potem wyświetlam to w JTable i działa elegancko. Ale niestety jeżeli zmienię zapytanie SQL np na takie: "SELECT nazwa FROM budowa" czyli, że chcę pojedyncza kolumnę, bądź kolumny, to wtedy program się wysypuje, a w tabeli nie ma żadnych danych. Mógłby ktoś podsunąć jakąś możliwą przyczynę?

0

Używasz w obu przypadkach tej samej JTable?

0

Tak, ale te dwa przypadki nie odbywają się w jednym czasie. Ja robię tak, że jak już mam dane w rs, to potem zapisuję to w tablicy String[][] i wtedy tą tablicę wrzucam do JTable.

0

W drugim przypadku jest za mało danych, musisz zmieniać ilość kolumn w JTable.

0

Dzięki za odpowiedź. Rzeczywiście było za mało danych, a wynikało to z tego, że w JScrollPane wpisałem na sztywno jakieś nazwy kolumn, tak dla sprawdzenia, no i w przypadku innej liczby kolumn wyskakiwał błąd.

0

Teraz mam kłopot z dodaniem kolumny do tabeli. Mianowicie zależy mi na tym, aby przy wrzucaniu pobranych danych z bazy do tabeli, dodawało mi na początku kolumnę z cyframi numerującymi wiersze.

	public static String[][] tablica(ResultSet rs) {
		try {
			int i = 0;
			while (rs.next()) {
				for (int j=0; j <= rs.getMetaData().getColumnCount(); j++) {
					if (j==0)
						tabela[i][j] = Integer.toString(i+1);
					else 
						tabela[i][j] = rs.getString(j);
				}
				i+=1;
			}
			
			return tabela;
		} catch (Exception e) {
			System.out.println(e.getMessage());
			return null;
		  }
	}

Ten kod niestety nie działa. W JTable nic się nie wyświetla. Natomiast jeżeli warunek w instrukcji for dam na taki:
j < rs.getMetaData().getColumnCount() to wtedy dane są wyświetlane, no ale niestety ucina mi dane z ostatniej kolumny, gdyż brakuje jednej iteracji. Jakiś błąd musi być w tej ostatniej iteracji. Ilość kolumn w JTable mam ustawioną na poprawną. Kolejny raz proszę o jakąś wskazówkę.

0

Imo, kod dopisujący do tablicy jest poprawny (chociaż ja bym napisał inaczej):

    int i = 0;
    while (rs.next()) {
       tabela[i,0] = Integer.toString(i+1);
       for (int j=1; j <= rs.getMetaData().getColumnCount(); j++) {
           tabela[i][j] = rs.getString(j);
       }
       i+=1;
    }

Cała metoda jest natomiast dość zagadkowa. Zwraca tablicę, której nie tworzy.

0

Tworzenie tablicy mam w konstruktorze. Na początku tak zapisałem i potem nawet nie zmieniałem, ale rzeczywiście można ją utworzyć jako zmienną lokalną w tej metodzie, w której jest używana.
Co do mojego problemu, to może wina leży gdzieś w JScrollPane, bądź JTable, ale nie mam pojęcia co to mogłoby być.
Jeszcze dodam, że przy próbie wyświetlania w JTable nic nie ma, prócz nazw kolumn, ale za to w konsoli wyświetla się liczba kolumn... Nie wiem czy to coś znaczy.
W ostateczności zrobię bez tych numerów. Dzięki za pomoc.

0

Wrzucę kod, w którym generuję GUI i wrzucam do JTable dane z tablicy. Może tutaj jest jakiś błąd...

jScrollPaneWyswietl = new JScrollPane();
		String[] names = {"Lp","Nazwa","Wlasciciel1","Wlasciciel2","Adres","NIP","REGON"};
					
		TableModel jTableWyswietlModel = 
			new DefaultTableModel(TabelaDanych.tablica(Inwestorzy.pobierzDane()),names);
										
		jTableWyswietl = new JTable(jTableWyswietlModel);
		jScrollPaneWyswietl.setViewportView(jTableWyswietl);
	}
0

Czy w konsoli nie wyświetla ci się żaden wyjątek? Czy jesteś pewien, że nie wychodzisz poza rozmiar tablicy? Pamiętaj, że jej drugi wymiar musi być wielkości rs.getMetaData().getColumnCount() + 1, a pierwszy - rozmiaru ResultSetu, przy czym ty tę tablicę tworzysz w konstruktorze - skąd wiesz, jak duża ma być?

0

Działa :) Znowu takie banalne niedopatrzenie. W konstruktorze zapomniałem zwiększyć o jeden ten drugi wymiar tablicy. A co do określania rozmiaru w konstruktorze, to ten konstruktor miałem z parametrem wejściowym ResultSet i właśnie na jego podstawie określałem rozmiar tablicy. Ale już zrobiłem tworzenie tej tablicy po prostu w tej metodzie, jako zmienną lokalną.

0

A wie ktoś może jak zrobić coś takiego, że mam komponent, w którym ma być podana data YYYY-MM-DD i żebym mógł wcisnąć w strzałkę przy tym komponencie i wtedy pojawia mi się kalendarz i z niego wybieram datę. Może jest gdzieś jakieś info o tym?;> Bo na googlach znalazłem tylko w javascript, nic więcej.

Ewentualnie, jak w JTextField zrobić, aby domyślnie było tak na szaro wpisane jaki format daty ma być, po czym po kliknięciu w to, ta podpowiedź znika. I oczywiście, jeżeli nic się nie wpisze, to żeby potem sczytywało puste pole a nie ta podpowiedź.

1

http://www.google.pl/#q=swing+date+chooser
W samym swingu chyba nie ma.

0

Mam taki problem. Otóż w bazie mam tabelę BUDOWY, która zawiera klucz obcy id_pracownik z tabeli PRACOWNIK. I teraz w momencie dodawania nowego wiersza do tabeli BUDOWY, chcę zrobić comboBox z wyborem nazwisk pobranych z tabeli PRACOWNIK. Z tym sobie poradziłem. Ale teraz nie wiem jak rozwiązać sytuację, aby po sczytaniu z comboBoxa nazwiska, jakoś odczytać id odpowiadające temu pracownikowi i to id dodać do tabeli BUDOWY. Mam nadzieję, że jakoś zrozumiale to napisałem.

1

Utwórz klasę Pracownik z polami nazwisko,id_pracownika i metodą

public String toString()
{
    return nazwisko;
}

Do Comboboxa dodawaj obiekty klasy Pracownik, wyświetli się tylko nazwisko.

0

A do comboboxmodel nie można dodawać tylko String[] ? Nie wiem w jaki sposób dodac obiekty i do tego żeby po wybraniu danego nazwisko odczytać potem z tego id.

1

Do JComboBox możesz dodać obiekt dowolnego typu, metoda toString() zostanie użyta przy wyświetlaniu.
Pobierasz zaznaczony obiekt, rzutujesz na klasę Pracownik i odczytujesz dowolne informacje.

 ...  = (Pracownik)(cb.getSelectedItem()).getId();
0

Dzięki wielkie za te wszystkie wskazówki. W pewnym momencie zatraciłem tą całą ideę obiektowości w moim projekcie ze względu na to, że nie ma z programowaniem do czynienia na co dzień. Ale teraz powoli to sobie układam i zaczyna wyglądać tak jak powinno.

0

Czy do JTable też można dodawać całe obiekty, tak jak w przypadku JComboBoxa? Żeby potem przy wybieraniu jakiegoś wiersza, łatwo odczytać obiekt i jego dane i ewentualnie wykorzystać to do modyfikacji rekordu w bazie, bądź jego usunięcia? Jeżeli nie, to czy jest jakieś sprytne rozwiązanie tego. Bo obecnie dane z bazy najpierw sczytuję do tablicy String[][], i potem tą tablicę wrzucam do JTable. No ale takie rozwiązanie w żaden sposób nie ułatwia dalszej komunikacji z bazą w celu chociażby usunięcia z bazy zaznaczonego wiersza w JTable.

0

JTable odpowiada tylko za to jak wyświetlać, za to co wyświetlać odpowiada TableModel. TableModel może być prawie wszystkim, w szczególności może być tablicą lub kolekcją (ArrayList,Vector) obiektów jakiejś klasy. Ważne by miał trzy metody, których znaczenie łatwo odgadnąć po nazwach: getColumnCount(), getRowCount() i getValueAt().

0

Stworzyłem już sobie klasę ModelTabeli, ale teraz nie wiem jak to dalej rozwiązać. Co ma konkretnie robić konstruktor tej klasy? Do tworzenia listy obiektów mam stworzyć osobną klasę? Nie za bardzo pojmuję ten cały schemat działania. Co gdzie tworzyć i gdzie wywoływać. Już tyle dni to męczę, że mam wielki mętlik w głowie. Byłbym bardzo wdzięczny za kolejne wskazówki. Oczywiście mógłbym zostawić to wyświetlanie tak jak mam obecnie, ale chciałbym nauczyć się to robić na obiektach, gdyż w przyszłości jestem pewien, że mi się to przyda. Byłbym niezmiernie wdzięczny za kolejne wskazówki.

0

Fragment mojego programu (JTable wyświetla listę studentów przechowywaną w pliku CSV).
Klasa Student (tylko pola)

public class Student
{
    private String imie=null;
    private String nazwisko=null;
    private String indeks=null;
    private String pesel=null;
    private boolean deleted=false;
    private boolean printable=false;
}

Istotne fragmenty klasy StudentsModel

public class StudentsModel extends AbstractTableModel
{
    private String[] columnNames={"Imię","Nazwisko","Indeks","Czy drukować","Skreślony"};
    private Class[] columnClasses={String.class,String.class,String.class,Boolean.class,Boolean.class};
    //kolumna typu Boolean jest przez domyślny renderer klasy JTable wyświetlane w postaci JCheckBoxa
    private ArrayList<Student> studenci=new ArrayList<Student>(); //dane
    //------------------------
    public int getColumnCount()
    {
        return columnNames.length;
    }
    //------------------------
    public int getRowCount()
    {
        return studenci.size();
    }
    //------------------------
    public Object getValueAt(int wiersz,int kolumna)
    {
        Student s=studenci.get(wiersz);
        switch(kolumna)
        {
            case 0:
                 return s.getImie();
            case 1:
                 return s.getNazwisko();
            case 2:
                 return s.getIndeks();
            case 3:
                 return s.isPrintable();
            case 4:
                 return s.isDeleted();
        }
        return null;
    }    
    //------------------------
    public Class getColumnClass(int kolumna)
    {
    	return columnClasses[kolumna];
    }
    //------------------------
    public String getColumnName(int kolumna)
    {
    	return columnNames[kolumna];
    }
    //------------------------
    public void setStudenci(ArrayList<Student> studenci)
    {
        this.studenci=studenci;
    }
    //------------------------
    public boolean isCellEditable(int wiersz,int kolumna)
    {
        return true; // wszystko jest edytowalne
    }
}

Tworzenie obiektu JTable

StudentsModel model=new StudentsModel();
JTable tabela=new JTable(model);
JScrollPane sp=new JScrollPane(tabela);
//po wykonaniu zapytania (u mnie po odczytaniu wybranego pliku CSV)
//utworzenie danych (u mnie dane są typu studenci ArrayList<Student>)
model.setStudenci(studenci);
model.fireTableDataChanged();

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