• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Java AWT i SWING

VPS Starter Arubacloud
0 głosów
999 wizyt
pytanie zadane 16 września 2016 w Java przez Kacperos_89 Początkujący (400 p.)

Witam :)

Napisałem krótką aplikacje używając SWING'a (JTextField, JButton i JLabel) i AWT. Problem zaczyna się gdy używam rysowania (Graphic gDC), wtedy znikają mi wszystkie elementy JFrame. Teoretycznie pokazują się gdy odnajdę je kursorem na ślepo. Proszęo podpowiedź jak mogę to naprawić :)

A tak wygląda aplikacja:

 

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class JApp extends JFrame
{
	private JTextField textFieldKilometry, textFieldLitry;
	private JButton buttonLicz;
	private JLabel labelWynik;
	
	String spalanie = "Spalanie";
	Font spalanieFont = null;
	Font opisFont = null;
	
	String kilometry;
	
	public void paint(Graphics gDC)
	{
		gDC.setFont(spalanieFont);
		FontMetrics rozmiarCzcionki = gDC.getFontMetrics();
		
		int spalanieSzerokosc = rozmiarCzcionki.stringWidth("Spalanie");
		int spalanieWysokosc = rozmiarCzcionki.getHeight();
		
		int srodekX = (getWidth() - spalanieSzerokosc) / 2;
		int srodekY = (getHeight() + spalanieWysokosc) / 2;
		
		gDC.clearRect(0, 0, getSize().width, getSize().height);
		gDC.drawString(spalanie, srodekX, 60);
		
		gDC.setFont(opisFont);
		gDC.drawString("Podaj przejechane kilometry:", 30, 100);
		
		gDC.setFont(opisFont);
		gDC.drawString("Podaj ilość litrów zatankowanego paliwa:", 30, 130);
		
		gDC.setFont(opisFont);
		gDC.drawString("Spalanie na 100 kilometrów to:", 30, 225);
	}
	
	public JApp()
	{
		ActionListener buttonLiczAL = new ActionListener() 
		{			
			public void actionPerformed(ActionEvent e) 
			{
				if(e.getSource() == buttonLicz)
					kilometry = textFieldKilometry.getText();
					double km = Double.parseDouble(kilometry);
					System.out.println(kilometry);
			}
		};
		
		setLayout(null);
		
		textFieldKilometry = new JTextField();
		textFieldKilometry.setBounds(300, 55, 100, 20);
		
		textFieldLitry = new JTextField();
		textFieldLitry.setBounds(300, 85, 100, 20);
		
		buttonLicz = new JButton("Oblicz");
		buttonLicz.setBounds(150, 130, 100, 20);
		buttonLicz.addActionListener(buttonLiczAL);
		
		labelWynik = new JLabel("JApp");
		labelWynik.setBounds(150, 150, 100, 50);
		
		add(textFieldKilometry);
		add(textFieldLitry);
		add(buttonLicz);
		add(labelWynik);
	}

	
	
	public static void main(String[] args) 
	{
		JApp main = new JApp();
		main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		main.setSize(420, 300);
		main.setVisible(true);
	}

}

 

6 odpowiedzi

0 głosów
odpowiedź 16 września 2016 przez Trucik Obywatel (1,130 p.)
Kompletnie nie rozumiem, ani założeń ani kodu.

W metodzie paint wrzucasz jako Font nulle.

Listener pobiera wartość z pola parsuje na double i wyświetla w konsoli.

Napisz proszę co to miało robić, a może będzie mi łatwie się połapać. Wrzuciłem do kompliatora bo zaciekawała mnie tak magia, ale tak jak się spodziewałem po wciśnięciu guzika widze w kosoli wartość z JTextField'a i tyle.

Kiedy chcesz wywoływac metodę update?
0 głosów
odpowiedź 16 września 2016 przez Kacperos_89 Początkujący (400 p.)

Po pierwsze powiedz mi proszę czy widzisz wszystkie elementy graficzne? W okienku powinny być: 4 linijki tekstu rysowanych przez gDC Graphics, 2 JTextField, 1JButton i 1 JLabel. Widzisz to wszystko zaraz po uruchomieniu aplikacji czy może widzisz coś takiego:

Aplikacja nie jest jeszcze kompletna. Ma to być kalkulator do liczenia spalania, ActionListiner działa na razie tak marnie żeby tylko sprawdzić czy działa. Aplikacja jest nie dokończona właśnie przez to że źle się wyświetla. Na tym screenie brakuje jeszcze jednego JTextField, JButton i JLabel. textfield i button pojawia mi się dopiero gdy najadę na nie myszką z label już się tak nie dzieje. I teraz moje pytanie. Dlaczego nie wyświetlają mi się prawidłowo wszystkie elementy JFrame? Dodam że gdy usunę z kodu wszystkie elementy gDC Graphics to wtedy elementy JFrame wyświetlają się prawidłowo.

0 głosów
odpowiedź 16 września 2016 przez Trucik Obywatel (1,130 p.)

 

Tłumaczę na czym polega magia Twojej aplikacji.

Biblioteka swing rysuje wszystkie elementy od nowa w przypadku zmian. Metoda paint jest wywoływana przez wątek, na który nie masz wpływu np. w sytuacji powiększania okna minimalizacji itd.

Tworzysz sobie elementy w konstruktorze (i to jest w miarę dobre podejście). Metoda paint zostaje wywołana poza Twoją kontrolą przez wątki swinga. Dodatkowo pole rysowania uruchamia się na całej powierzchni okna przysłaniając poprzednio osadzone(a tak naprawdę wyrysowane) komponenty. 

Twoje elementy nie znikają, ale zostają "nadrysowane", dlatego po kliknięciu swing znów rysuje kliknięty przez Ciebie komponent, jak to nazwałeś "w ciemno".

Rozwiązaniem powinno być użycie kilku JPanel. Pierwszy dla wypełniania przez użytkownika, drugi aby coś tam rysować. Nie mniej rysowanie nie powinno odbywać się w sposób, nad którym nie masz kontroli. Metoda paint powinna być taktowana timerem co zadany czas no i oczywiście mieć inna nazwę by nie być wywoływana przez swinga w nieznanym przez Ciebie momencie.

Mam nadzieję, że pomogłem:)

p.s. swing stracił support i nie jest rozwijany. Oracje (twórca Java) rekomenduje używanie JavaFX

 

 

 

komentarz 17 września 2016 przez mbabane Szeryf (79,260 p.)
tworca Javy jest zdaje sie Sun Microsystems, Oracle ich tylko wykupilo.
komentarz 18 września 2016 przez Trucik Obywatel (1,130 p.)
Masz racje.

Powinienem napisać: Właściciel, który utrzymuje standard języka i wciąż rozwija go od przeszło 7 lat wycofał support dla biblioteki swing i rekomenduje używanie JavaFX :).
0 głosów
odpowiedź 17 września 2016 przez Kacperos_89 Początkujący (400 p.)
Oj no to mam kolejne problemy. Nie mogę znaleźć nigdzie jak w jaki sposób wywołać Graphics gDC ręcznie. Po za metodą paint. Nie wiem też w jaki sposób dodać tą metodę paint do panelu. Jak byś mógł podać jeszcze jakieś pomocne informacje to bym był wdzięczny :)
0 głosów
odpowiedź 18 września 2016 przez Trucik Obywatel (1,130 p.)

Rysujesz obiekt JFrame, do niego powinieneś wstawić obiekt typu JPanel, powiedźmy że jest to taki JFrame bez paska na górze (choć nie do końca) nie mniej w ramach jego rozmiaru (Bounds) możesz ograniczyć przestrzeń rysowania przez funkcje paint lub componentPaint.

Ten kawałek należy wkleić do ciała klasy JApp. Stworzysz w niej klasę wewnetrzną panel, która później zostanie dodana do tego głównego okna.

            @Override 
            public void paint(Graphics gDC) {
                super.paint(gDC);

              gDC.setFont(spalanieFont);
             FontMetrics rozmiarCzcionki = gDC.getFontMetrics();
              
              int spalanieSzerokosc = 10;
              int spalanieWysokosc = 10;
               
              int srodekX = (getWidth() - spalanieSzerokosc) / 2;
              int srodekY = (getHeight() + spalanieWysokosc) / 2;
               
              gDC.clearRect(0, 0, getSize().width, getSize().height);
              gDC.drawString(spalanie, srodekX, 60);
               
              gDC.setFont(opisFont);
              gDC.drawString("Podaj przejechane kilometry:", 30, 100);
               
              gDC.setFont(opisFont);
              gDC.drawString("Podaj ilość litrów zatankowanego paliwa:", 30, 130);
               
              gDC.setFont(opisFont);
              gDC.drawString("Spalanie na 100 kilometrów to:", 30, 225);
            }
        }
        JPanel panel = new Panel();
        panel.setBounds(0, 0, 500, 200);
        this.add(panel);
    }

 

 

 

0 głosów
odpowiedź 18 września 2016 przez manjaro Nałogowiec (37,390 p.)
Zainstaluj sobie Netbeans. Cały program zrobisz w 2 minuty. W tym pisanie kodu to dosłownie 1 linijka.

Przepraszam ale naprawdę nie rozumiem po co wymyślać koło od nowa.

Podobne pytania

0 głosów
1 odpowiedź 775 wizyt
0 głosów
0 odpowiedzi 248 wizyt
0 głosów
1 odpowiedź 451 wizyt
pytanie zadane 15 maja 2016 w Java przez hubot Dyskutant (9,090 p.)

93,031 zapytań

141,995 odpowiedzi

321,300 komentarzy

62,379 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...