diff --git a/problem-set/ResizableGrid.java b/problem-set/ResizableGrid.java new file mode 100644 index 0000000..1d33c48 --- /dev/null +++ b/problem-set/ResizableGrid.java @@ -0,0 +1,54 @@ +/* + * File: ResizableGrid.java + * ---------------------------- + * მთელ ფორმაზე ბადის დახატვა, ისე რომ ფორმის ზომის ცვლილებაზე ბადის უჯრის ზომაც + * პროპორციულად იზრდებოდეს. + * + * დეტალური ამოხსნა იხილეთ ResizableGrid.md ფაილში. + */ + +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; + +import acm.graphics.GRect; +import acm.program.GraphicsProgram; + +public class GraphicsProgramSample extends GraphicsProgram implements ComponentListener { + + // Size of the board + private final int BOARD_WIDTH = 10; + private final int BOARD_HEIGHT = 10; + + public void run() { + addComponentListener(this); + } + + public void componentResized(ComponentEvent e) { + drawBoard(getWidth(), getHeight()); + } + + // This method draw board with (width, height) size + private void drawBoard(int width, int height) { + removeAll(); + int cellWidth = width / BOARD_WIDTH; // Width of each cell + int cellHeight = height / BOARD_HEIGHT; // Height of each cell + for (int k = 0; k < BOARD_WIDTH; k++) { + for (int i = 0; i < BOARD_HEIGHT; i++) { + // Coordinates of the (k,i) cell will be (k * cellWidth, i * cellHeight) + GRect cell = new GRect(k * cellWidth, i * cellHeight, cellWidth, cellHeight); + add(cell); + } + } + } + + public void componentHidden(ComponentEvent e) { + } + + public void componentMoved(ComponentEvent e) { + } + + public void componentShown(ComponentEvent e) { + } + +} + diff --git a/problem-set/ResizableGrid.md b/problem-set/ResizableGrid.md new file mode 100644 index 0000000..9457575 --- /dev/null +++ b/problem-set/ResizableGrid.md @@ -0,0 +1,54 @@ +# ResizableGrid + +## პრობლემა: + +მთელ ფორმაზე ბადის დახატვა, ისე რომ ფორმის ზომის ცვლილებაზე ბადის უჯრის ზომაც +პროპორციულად იზრდებოდეს. + +## პრობლემის გადაჭრის გზა: + +გავაკეთოთ **drawBoard(int width, int height)** მეთოდი, რომელსაც **width** და **height** გადაეცემა და **(0,0)** წერტილიდან ამ სიგრძისა და სიგანის ბადეს დახატავს. შემდეგ ჩვენს კანვასზე დავამატოთ **ComponentListener**-ები და როდესაც ფანჯრის ზომა შეიცვლება, **drawBoard()**-ს გამოვიძახებთ და მას გადავცემთ ფანჯრის ახალ **getWidth()**-ს და **getHeight()**-ს. + +## პრობლემის გადაჭრის გზის კოდად გარდაქმნა: + +1. თავდაპირველად შევქმანთ ორი **final int** ტიპის ცვლადი **BOARD_WIDTH** და **BOARD_HEIGHT**, რომელშიც ბადის სიგანესა და სიგრძეში უჯრების რაოდენობა გვეწერება. თუ ბადის ზომის შეცვლა დაგვჭირდება, მარტივად მხოლოდ **BOARD_WIDTH**-ს და **BOARD_HEIGHT**-ს შევცვლით. + +2. გავაკეთოთ **drawBoard(int width, int height)** მეთოდი, რომელშიც **width** და **height** ზომის ბადეს დავხატავთ. პირველ რიგში გავიგოთ ბადეში თითოეული უჯრის განზომილებები, **cellWidth** და **cellHeight**. უჯრის სიგანე იქნება **width / BOARD_WIDTH** და სიმაღლე **height / BOARD_HEIGHT**. + +3. ბადის დასახატად თითოეული უჯრა დავხატოთ როგორც **GRect**. სულ მოგვიწევს **BOARD_WIDTH** რაოდენობის უჯრის დახატვა თითოეულ სტრიქონში, სტრიქონების რაოდენობა იქნება **BOARD_HEIGHT**. ყველა უჯრის დასახატად დაგვჭირდება ორი for ციკლი შემდეგნაირად: +```java + for (int k = 0; k < BOARD_WIDTH; k++) { + for (int i = 0; i < BOARD_HEIGHT; i++) { + + } + } +``` + +4. გავაკეთოთ **GRect** ცვლადი. მისი ზომები უკვე გამოვთვალეთ **(cellWidth, cellHeight)**, კოორდინატები კი იქნება **(k * cellWidth, i * cellHeight)**. დავამატოთ **GRect** ეკრანზე **add()** მეთოდით. + +5. მთავარი ნაწილი ამოცანაში ბადის ზომის შეცვლაა ფანჯრის ზომის ცვლილებასთან ერთად. ამისათვის, პირველ რიგში ჩვენმა კლასმა უნდა დააიმპლემენტიროს **ComponentListener** ინტერფეისი და ჩვენს კანვასზე დავამატოთ **componentListener**, რასაც **addComponentListener(this)**-ის საშუალებით გავაკეთებთ. რადგან ჩვენმა კლასმა **ComponentListener** ინტერფეისი დააიმპლემენტირა, უნდა ჩამოვწეროთ **ComponentListener** ინტერფეისში აღწერილი ყველა მეთოდი(მიუხედავად იმისა, გამოვიყენებთ მათ თუ არა): +```java + public void componentResized(ComponentEvent e) { + } + + public void componentHidden(ComponentEvent e) { + } + + public void componentMoved(ComponentEvent e) { + } + + public void componentShown(ComponentEvent e) { + } +``` + +6. როდესაც ფანჯრის ზომა შეიცვლება, **componentResized(ComponentEvent e)** მეთოდი ავტომატურად გამოიძახება, ამიტომ ამ მეთოდში **drawBoard(getWidth(), getHeight())** გამოვიძახოთ, რომ კანვაზე ბადე დავხაზოთ ფანჯრის ახალი ზომების მიხედვით. + +7. **drawBoard()**-ის ყოველი ახალი გამოძახებისას ეკრანზე დახატული ყველა ელემენტი უნდა წავშალოთ **removeAll()** მეთოდით, თორემ ბადეები ერთმანეთს გადაეხატება. + +## შესაძლო ხარვეზები: + +1. თუ **ComponentListener** ინტერფეისის ყველა მეთოდს არ ჩამოვწერთ ჩვენს კლასში, კომპილაციის შეცდომა იქნება და კოდი არ გაეშვება. + +2. **addComponentListener(this)**-ის დაწერა თუ დაგვავიწყდება, ფანჯრის ზომის ცვლილებაზე **listener**-ები არ დაემატება, შესაბამისად არც **componentResized()** მეთოდი გამოიძახება. + +3. როდესაც ორმაგი ციკლი დავწერეთ უჯრების დასახატად, **k**-სა და **i**-ს ინდექსები **0** დან დავიწყეთ, რადგან ამ ორ ცვლადს **(k, i)** უჯრის კოორდინატების დასათვლელად ვიყენებთ. **1**-დან რომ დაგვეწყო **(k * cellWidth, i * cellHeight)**-ის ნაცვლად **((k - 1) * cellWidth, (i - 1) * cellHeight)**-ის დაწერა მოგვიწევდა.