Bölüm 8: Grafikler
Çoktan Seçmeli · Grafik Programlama
Soru 1: main Bittikten Sonra
Bir Swing programının main metodu pencereyi kurup setVisible(true) çağırdıktan sonra bitiyor. Bundan sonra ne olur?
B: GUI programları olay güdümlüdür: main yalnızca arayüzü kurar. Pencere açıldıktan sonra olay iş parçacığı (EDT, arka plan olmayan bir iş parçacığı) olay kuyruğunu bekler; tıklama gibi her olayda ilgili dinleyiciyi çağırır. JVM, bu iş parçacığı çalıştıkça kapanmaz.
Hesap Sorusu · Grafik Programlama
Soru 2: Koordinatlar ve Sınırlayıcı Dikdörtgen
Bir panelde şu çizimler yapılıyor. (a) g.drawOval(30, 20, 80, 40) elipsinin merkezi hangi noktadır, en alttaki pikseli hangi y'dedir? (b) Merkezi (120, 80), yarıçapı 30 olan dolu daireyi çizen fillOval çağrısını yazın. (c) g.drawRect(20, 30, 50, 40) çerçevesinin sağ alt köşe pikseli hangi noktadır?
Cevabı göster
- (a) Elips, sol üst köşesi (30, 20), boyutu 80 × 40 olan dikdörtgene sığar: merkez (30 + 40, 20 + 20) = (70, 40). y aşağı doğru büyüdüğü için en alt nokta y = 20 + 40 = 60'tır (piksel olarak denendi).
- (b)
g.fillOval(120 - 30, 80 - 30, 60, 60), yanifillOval(90, 50, 60, 60): parametreler merkez değil, sınırlayıcı karenin sol üst köşesi ve boyutudur. - (c) (70, 70):
drawRectx..x+en ve y..y+boy arasını çizer (çerçeve en + 1 piksel geniştir). BirBufferedImageüzerinde denendi: (70, 70) boyalı, (71, 70) boş.
Adım Adım Çalıştırma · Giriş Yasak İşareti
Soru 3: İşaret 240 × 180 Panelde
Giriş yasak işaretini çizen paintComponent 240 × 180 piksellik bir panelde çalışıyor (arka plan yeşil). Değişkenler ve üç çizim çağrısının argümanları ne olur?
Zemin arka plan rengiyle (yeşil) boyanır.
Merkez: (240 / 2, 180 / 2) = (120, 90).
min(120, 90) − 5 = 85: kısa kenara göre seçilir.
85 × 0,9 = 76,5; (int) ondalığı atar: 76.
76 × 1,4 = 106,4 → 106; 76 × 0,35 = 26,6 → 26 (yuvarlama değil, kesme).
fillOval(35, 5, 170, 170): beyaz daire; kesikli kare sınırlayıcı dikdörtgendir.
fillOval(44, 14, 152, 152): kırmızı daire beyazın üstüne boyanır, 9 piksellik halka kalır.
bw / 2 = 53, bh / 2 = 13 → fillRect(67, 77, 106, 26). Sonradan çizilen en üstte görünür.
super.paintComponent(g); Point c = new Point(getWidth() / 2, getHeight() / 2); int r = Math.min(getWidth() / 2, getHeight() / 2) - 5; int r2 = (int) (r * 0.9); int bw = (int) (r2 * 1.4); int bh = (int) (r2 * 0.35); g.setColor(Color.WHITE); g.fillOval(c.x - r, c.y - r, 2 * r, 2 * r); g.setColor(Color.RED); g.fillOval(c.x - r2, c.y - r2, r2 * 2, r2 * 2); g.setColor(Color.WHITE); g.fillRect(c.x - bw / 2, c.y - bh / 2, bw, bh);
Çoktan Seçmeli · Pencere ve Panel
Soru 4: Kapatma Düğmesi
JFrame oluşturulup boyutu verildi ve setVisible(true) çağrıldı; setDefaultCloseOperation hiç çağrılmadı. Kullanıcı pencerenin × düğmesine basınca ne olur?
C: Varsayılan davranış HIDE_ON_CLOSE'dur: pencere yalnızca görünmez olur, JVM kapanmaz. Programın kapanması için setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) çağrılır. Kapatmayı tümüyle engellemek DO_NOTHING_ON_CLOSE ile olur.
Çoktan Seçmeli · Pencere ve Panel
Soru 5: İçerik Bölmesine İki Düğme
Pencereye bölge belirtmeden iki düğme ekleniyor. Pencere açılınca ne görünür?
JFrame f = new JFrame("Deneme"); f.add(new JButton("Bir")); f.add(new JButton("İki")); f.setSize(300, 200); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true);
D: JFrame'in içerik bölmesi BorderLayout kullanır; bölge verilmeyen add CENTER'a ekler. Her bölgede tek bileşen yerleşir: son eklenen kazanır. Bir düğmesi kapsayıcıda kalır ama boyutu 0 × 0 olur. Yan yana dizilim FlowLayout'un (JPanel'in varsayılanı) davranışıdır. Aynı yerleşim 300 × 200 bir BorderLayout panelinde denendi: İki (0, 0, 300, 200), Bir 0 × 0.
Çıktı Sorusu · Çizim Araçları
Soru 6: Point Referansı ve Color
Program hangi üç satırı yazdırır?
Point p = new Point(10, 20); Point q = p; q.translate(5, 5); p.setLocation(p.x * 2, p.y); System.out.println(p + " " + (q == p)); System.out.println(q.distance(30, 29)); Color k = new Color(200, 100, 50).darker(); System.out.println(k.getRed() + " " + k.getGreen() + " " + k.getBlue());
Cevabı göster
java.awt.Point[x=30,y=25] true 4.0 140 70 35
Point q = p;yeni nokta oluşturmaz: iki değişken aynı nesneyi gösterir.translate(5, 5)→ (15, 25);setLocation(15 * 2, 25)→ (30, 25).q == ptrue.- (30, 25) ile (30, 29) arası 4.0 (
distancedouble döndürür). darker()her bileşeni 0,7 ile çarpıp tam sayıya keser: 140, 70, 35. Asıl renk değişmez, yeni birColordöner.
Çoktan Seçmeli · Çizim Araçları
Soru 7: Kalın ve İtalik
Font f = new Font("Serif", Font.BOLD | Font.ITALIC, 20); için f.getStyle() ne döndürür?
A: Font.PLAIN = 0, Font.BOLD = 1, Font.ITALIC = 2 bit bayraklarıdır; | (bit düzeyinde VEYA) ikisini birleştirir: 1 | 2 = 3. isBold() ve isItalic() ikisi de true döner; punto ayrı bir parametredir (getSize() = 20).
Adım Adım Çalıştırma · Yerleşim Yöneticileri
Soru 8: BorderLayout Bölgeleri
300 × 200 piksellik panele tercih edilen boyutları verilmiş bileşenler ekleniyor (kutu(en, boy) o boyutu tercih eden bir JPanel döndürür). Her eklemeden sonra bileşenlerin konumu ve boyutu ne olur?
Boş panel: 300 × 200, bölgeler arası boşluk 0.
Kuzey tüm genişliği alır; yüksekliği tercih edilen boydur (30). Tercih edilen en (100) yok sayılır.
Güney en alta, tam genişlikte: y = 200 − 20 = 180.
Batı, kuzey ile güney arasındaki yüksekliği alır: 200 − 30 − 20 = 150; eni tercih edilen 60.
Doğu sağ kenara: x = 300 − 40 = 260.
Bölge verilmedi: CENTER. Tercihi (10 × 10) önemsizdir; kalan alanın tamamını alır: 200 × 150.
NORTH'a ikinci ekleme ilkinin yerini alır. Yeni kuzey 40 piksel yüksek; batı, doğu ve merkez 10 piksel aşağı kayar ve kısalır. Eski kuzey panelde kalır ama yerleşime katılmaz.
JPanel p = new JPanel(new BorderLayout()); p.setSize(300, 200); p.add(kutu(100, 30), BorderLayout.NORTH); p.add(kutu(100, 20), BorderLayout.SOUTH); p.add(kutu(60, 50), BorderLayout.WEST); p.add(kutu(40, 50), BorderLayout.EAST); p.add(kutu(10, 10)); p.add(kutu(80, 40), BorderLayout.NORTH);
Çoktan Seçmeli · Yerleşim Yöneticileri
Soru 9: GridLayout'ta Beşinci Düğme
new GridLayout(2, 3) kullanan 300 × 120 piksellik bir panele sırayla 5 düğme ekleniyor. 5. düğmenin konumu ve boyutu (x, y, en, boy) nedir?
B: GridLayout paneli eşit hücrelere böler: 300 / 3 = 100 en, 120 / 2 = 60 boy. Düğmeler satır satır yerleşir: 1–3 üst satırda, 4 alt satırın ilk, 5 ikinci hücresinde: x = 100, y = 60. Altıncı hücre boş kalır; hücre boyutu bileşen sayısına göre değişmez.
Çoktan Seçmeli · Fare Olayları
Soru 10: Sürükleme Hiç Gelmiyor
Panel üzerinde sürükleyerek çizim yapılmak isteniyor ama mouseDragged hiç çalışmıyor; mousePressed ise çalışıyor. Neden?
MouseAdapter ma = new MouseAdapter() { public void mousePressed(MouseEvent e) { // yeni eğri başlat } public void mouseDragged(MouseEvent e) { // son eğriye nokta ekle, repaint() } }; panel.addMouseListener(ma);
C: MouseAdapter hem MouseListener hem MouseMotionListener metotlarını boş gövdelerle içerir, ama kayıt arayüze göre yapılır: addMouseListener yalnızca basma, bırakma, tıklama, giriş ve çıkış olaylarını iletir. Olay doğrudan panele gönderilerek denendi: yalnız addMouseListener ile mouseDragged 0 kez, panel.addMouseMotionListener(ma) eklenince 1 kez çağrıldı.
Çıktı Sorusu · Çizim Programı
Soru 11: Eğriler ve drawLine Sayısı
Çizim programında (her basış yeni bir eğri başlatır, her sürükleme son eğriye nokta ekler; paintComponent her eğride onceki'yi ilk nokta yapıp her nokta için bir drawLine çağırır) kullanıcı şunları yapıyor: (10, 10)'da basar, (20, 10) ve (30, 20)'ye sürükler, bırakır; (5, 5)'te basar, (6, 6)'ya sürükler, bırakır. Sonra pencere yeniden çiziliyor. egriler.size(), her eğrinin nokta sayısı ve toplam drawLine çağrısı kaçtır?
Cevabı göster
egriler.size()= 2: hermousePressedyeni bir iç liste ekler;mouseReleasedyazılmadığı için hiçbir şey yapmaz.- Eğri 0: (10, 10), (20, 10), (30, 20) → 3 nokta. Eğri 1: (5, 5), (6, 6) → 2 nokta.
drawLine= 3 + 2 = 5: iç döngü ilk noktadan başladığı için ilk çağrı noktayı kendisiyle birleştirir (tek piksel). Görünen çizgi parçası 2 + 1 = 3'tür.
Veri (noktalar) saklandığı için pencere her yeniden çizildiğinde aynı resim oluşur.
Çoktan Seçmeli · Fare Olayları
Soru 12: invokeLater ve invokeAndWait
Bu satırlar main iş parçacığında çalışıyor. Ekrandaki harflerin sırası için hangisi kesindir?
SwingUtilities.invokeLater(
() -> System.out.println("B"));
System.out.println("A");
SwingUtilities.invokeAndWait(
() -> System.out.println("C"));
System.out.println("D");D: invokeLater işi olay kuyruğuna koyup hemen döner; B'nin A'dan önce mi sonra mı yazılacağını zamanlayıcı belirler. Olay kuyruğu sıralıdır: B, C'den önce çalışır. invokeAndWait C bitene kadar bekler, bu yüzden D en sondadır. Pencere gerekmez; denemelerde ABCD görüldü ama bu bir garanti değildir.
Çoktan Seçmeli · Metin Bileşenleri
Soru 13: Lambdada Sayaç
Düğmeye her tıklanışta sayacı artırmak için şu kod yazıldı. Ne olur?
public static void main(String[] args) { int sayac = 0; JButton d = new JButton("Tıkla"); d.addActionListener(e -> sayac++); }
A: Derleyici iletisi: local variables referenced from a lambda expression must be final or effectively final. Lambda yerel değişkenin değerini yakalar, değiştiremez. Çözüm: sayac'ı sınıfın alanı (field) yapmak; alanlar lambda içinden değiştirilebilir.
Çıktı Sorusu · Metin Bileşenleri
Soru 14: JTextArea ve JTextField
Program hangi üç satırı yazdırır?
JTextArea a = new JTextArea("x"); a.append("\ny"); a.append("\n"); System.out.println(a.getLineCount()); a.setText("tek"); a.append(" satır"); System.out.println(a.getText() + " " + a.getLineCount()); JTextField f = new JTextField(10); f.setText(" 42 "); int n = Integer.parseInt(f.getText().trim()); System.out.println(n + 1);
Cevabı göster
3 tek satır 1 43
- Metin
"x\ny\n"oldu: iki satır sonu, üç satır (sonuncusu boş).getLineCount()satır sonu sayısının bir fazlasıdır. setTexteski içeriği siler;appendsona ekler:"tek satır", satır sonu yok → 1.getText()her zamanStringdöndürür; boşluklartrim()ile atılmasaydıparseIntNumberFormatExceptionfırlatırdı. 42 + 1 = 43.
Çıktı Sorusu · Harf Çevirici
Soru 15: Büyük Harf ve Yerel Ayar
Program hangi dört satırı yazdırır?
String s = "Kış İzmir";
Locale tr = new Locale("tr");
System.out.println(s.toUpperCase(tr));
System.out.println(s.toLowerCase(tr));
System.out.println(s.toUpperCase(Locale.ENGLISH));
System.out.println(s);Cevabı göster
KIŞ İZMİR kış izmir KIŞ İZMIR Kış İzmir
- Türkçe kuralları: i → İ, ı → I; İ → i, I → ı.
- İngilizce kuralları: ı → I, i → I, İ değişmeden kalır:
İZMIR. Bu yüzden metin dönüştürücüde yerel ayarı açıkça vermek gerekir. - Dizgiler değiştirilemez:
toUpperCaseyeni bir dizgi döndürür;shâlâ"Kış İzmir"'dir. Düğme dinleyicisinde sonucusetTextile geri yazmak bu yüzden gerekir.
Adım Adım Çalıştırma · Para Üstü Uygulaması
Soru 16: raporuGuncelle: 187 Kuruş
Kullanıcı miktar alanına 187 yazdı. raporuGuncelle rapor alanına hangi satırları yazar?
Alanda 187 yazıyor; metin tam sayıya çevrilir.
setText raporu sıfırdan başlatır.
187 / 50 = 3 adet (tam sayı bölmesi).
Kalan: 187 % 50 = 37.
37 / 25 = 1 adet (tam sayı bölmesi).
Kalan: 37 % 25 = 12.
12 / 10 = 1 adet (tam sayı bölmesi).
Kalan: 12 % 10 = 2.
2 / 5 = 0 adet (tam sayı bölmesi).
Kalan: 2 % 5 = 2.
2 / 1 = 2 adet (tam sayı bölmesi).
Kalan: 2 % 1 = 0. Döngü biter: 3 + 1 + 1 + 0 + 2 = 7 madeni para.
void raporuGuncelle() {
try {
int miktar = Integer.parseInt(
metin.getText(0, metin.getLength()));
int[] dizi = {50, 25, 10, 5, 1};
rapor.setText(miktar + " kuruş yapmak için kullanılacaklar:\n");
for (int x : dizi) {
rapor.append(miktar / x + " " + x + " kuruş\n");
miktar %= x;
}
} catch (NumberFormatException e) {
rapor.setText("Tam sayı değil veya aralık dışında");
} catch (Exception e) {
rapor.setText(e.toString());
}
}Kod Yazma · Grafik Programlama
Soru 17: Hedef Tahtası
JPanel'den türeyen bir sınıfın paintComponent metodunu yazın: panelin ortasında, kısa kenara göre ölçeklenen (kenarda 10 piksel pay), içten dışa kırmızı-beyaz sırayla 4 halkalı bir hedef çizsin. 220 × 150 panelde hangi dört fillOval çağrısı yapılır?
Cevabı göster
@Override public void paintComponent(Graphics g) { super.paintComponent(g); int cx = getWidth() / 2, cy = getHeight() / 2; int r = Math.min(cx, cy) - 10; for (int i = 0; i < 4; i++) { int ri = r - i * r / 4; // büyükten küçüğe g.setColor(i % 2 == 0 ? Color.RED : Color.WHITE); g.fillOval(cx - ri, cy - ri, 2 * ri, 2 * ri); } }
220 × 150: cx = 110, cy = 75, r = 65. i * r / 4 soldan sağa hesaplanır (önce çarpma): ri = 65, 49, 33, 17 → fillOval(45, 10, 130, 130), (61, 26, 98, 98), (77, 42, 66, 66), (93, 58, 34, 34). Büyük daire önce çizilmelidir; küçükten büyüğe çizilseydi en son çizilen büyük daire hepsini örterdi.
Hata Bulma · Çizim Programı
Soru 18: Üç Hata
Panel derleniyor ama eğriler görünmüyor, eski çizim artıkları kalıyor ve ilk sürüklemede istisna fırlıyor. Üç hatayı bulun.
class Cizim extends JPanel { List<List<Point>> egriler = new ArrayList<>(); MouseAdapter m = new MouseAdapter() { public void mousePressed(MouseEvent e) { egriler.add(new ArrayList<>()); } public void mouseDragged(MouseEvent e) { egriler.get(egriler.size()).add(e.getPoint()); repaint(); } }; Cizim() { addMouseListener(m); addMouseMotionListener(m); } public void paintcomponent(Graphics g) { for (List<Point> eg : egriler) for (int i = 1; i < eg.size(); i++) g.drawLine(eg.get(i - 1).x, eg.get(i - 1).y, eg.get(i).x, eg.get(i).y); } }
Cevabı göster
paintcomponent(küçük c) yeni bir metottur, Swing onu çağırmaz;@Overridebunu derlemede yakalardı.super.paintComponent(g)yok: zemin temizlenmez, artıklar kalır.- Son öğe
size() - 1'dedir;get(size())IndexOutOfBoundsExceptionfırlatır.