Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

новая папка / лаб 4-5-6 / FractalExplorer

.java
Скачиваний:
7
Добавлен:
26.02.2023
Размер:
10 Кб
Скачать

// import javafx.scene.control.ComboBox;
// import javafx.scene.layout.Border;
import java.awt.geom.Rectangle2D;
// import java.awt.geom.Rectangle2D.Double;
import java.awt.event.*;
// import javax.swing.JFileChooser.*;
import javax.swing.filechooser.*;
import java.awt.image.*;
import java.awt.*;
import javax.swing.*;

public class FractalExplorer {

    /** Элементы, которые надо блокировать методом enableUI **/
    private JComboBox<FractalGenerator> comboBox;
    private JButton button_reset;
    private JButton button_save;

    private int screenSize;
    private JImageDisplay img;
    private FractalGenerator gen;
    private Rectangle2D.Double rectangle;
    private int rowsRemaining;

    FractalExplorer(int size) {
        // сохранение значения размера отображения в переменной screenSize
        screenSize = size;
        // инициализация объектов диапазона и фрактального генератора
        gen = new Mandelbrot();
        rectangle = new Rectangle2D.Double();
        img = new JImageDisplay(screenSize, screenSize);
        //
        gen.getInitialRange(rectangle);

    }

    // создание интерфейса
    public void createAndShowGUI() {
        // создание рамки
        JFrame frame = new JFrame("Fractal");
        // закрытие окна по клику на крестик
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // определение размера окна
        frame.setSize(screenSize, screenSize);
        img.setLayout(new BorderLayout());
        // делаем рамку видимой
        frame.setVisible(true);

        // инициализация панели с кнопкой ресета
        JPanel but_panel = new JPanel();
        // but_panel.setBackground(Color.BLACK);

        // инициализация кнопки ресета
        JButton reset_b = new JButton("reset");
        // определение размера кнопки
        reset_b.setPreferredSize(new Dimension(200, 100));

        ActionListener DisplayReset = new ResetDisplay();
        reset_b.addActionListener(DisplayReset);

        // добавление кнопки на панель
        but_panel.add(reset_b);

        MouseHandler click = new MouseHandler();
        img.addMouseListener(click);

        // добавление панели на рамку и привязка ее к середине снизу рамки
        frame.add(but_panel, BorderLayout.SOUTH);
        frame.add(img, BorderLayout.CENTER);

        JPanel top_panel = new JPanel();
        JLabel lable = new JLabel("Fractal: ");
        top_panel.add(lable);

        FractalGenerator tricorn_frac = new Tricorn();
        FractalGenerator ship_frac = new BurningShip();

        JComboBox<FractalGenerator> comboBox = new JComboBox<>();
        comboBox.addItem(gen);
        comboBox.addItem(tricorn_frac);
        comboBox.addItem(ship_frac);

        ActionListener choose = new ChooseFractal();
        comboBox.addActionListener(choose);

        top_panel.add(comboBox);
        frame.add(top_panel, BorderLayout.NORTH);

        JButton save_b = new JButton("save");
        save_b.setPreferredSize(new Dimension(200, 100));
        ActionListener save = new SavePic();
        save_b.addActionListener(save);

        but_panel.add(save_b);

        frame.pack();
        frame.setResizable(false);

    }

    public void drawFractal() {
        // отключение всех элементов пользовательского интерфейса во время рисования
        enableUI(false);
        // определяем количество строк, которые нужно нарисовать
        rowsRemaining = screenSize;
        for (int x = 0; x < screenSize; x++) {
            FractalWorker drawRow = new FractalWorker(x);
            // запуск фонового потока
            drawRow.execute();
        }
    }

    // отключение/включение элементов пользовательского интерфейса
    private void enableUI(boolean value) {
        comboBox.setEnabled(value);
        button_reset.setEnabled(value);
        button_save.setEnabled(value);
    }

    private class ResetDisplay implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            gen.getInitialRange(rectangle);
            FractalExplorer.this.drawFractal();
        }
    }

    private class SavePic implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            // объект, в который будем сохранять картинку
            JFileChooser chooser = new JFileChooser();
            // указываем фильтр по расширению файла
            FileFilter filter = new FileNameExtensionFilter("PNG Images", "png");
            chooser.setFileFilter(filter);
            chooser.setAcceptAllFileFilterUsed(false);
            // вызываем диалоговое окно сохранения файла
            int userSelection = chooser.showSaveDialog(img);
            // если юзер подтверждает сохранение
            if (userSelection == JFileChooser.APPROVE_OPTION) {
                // узнаем директорию, выбранную пользователем
                java.io.File file = chooser.getSelectedFile();
                try {
                    BufferedImage displayImage = img.getImage();
                    // записываем картинку в указанный файл
                    javax.imageio.ImageIO.write(displayImage, "png", file);
                } catch (Exception exception) {
                    // сообщение об ошибке
                    JOptionPane.showMessageDialog(img, exception.getMessage(), "Cannot Save Image",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        }
    }

    // выбор фрактала через комбобокс
    private class ChooseFractal implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            JComboBox<FractalGenerator> target = (JComboBox<FractalGenerator>) e.getSource();
            gen = (FractalGenerator) target.getSelectedItem();
            gen.getInitialRange(rectangle);
            FractalExplorer.this.drawFractal();
        }
    }

    private class MouseHandler extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            if (rowsRemaining != 0) {
                return;
            }
            int x = e.getX();
            int y = e.getY();
            double xCoord = FractalGenerator.getCoord(rectangle.x, rectangle.x + rectangle.width, screenSize, x);
            double yCoord = FractalGenerator.getCoord(rectangle.y, rectangle.y + rectangle.height, screenSize, y);
            gen.recenterAndZoomRange(rectangle, xCoord, yCoord, 0.5);
            FractalExplorer.this.drawFractal();
        }
    }

    // вычисляет значения цветов строки фрактала
    private class FractalWorker extends SwingWorker<Object, Object> {
        // поле строки
        int yCoordinate;
        // массив с цветами пикселей
        int[] pixColor;

        private FractalWorker(int yTarget) {
            yCoordinate = yTarget;
        }

        // фоновый поток, сохранение каждого значения RGB в соответствующем элементе
        // целочисленного массива
        protected Object doInBackground() {
            pixColor = new int[screenSize];

            double xCoord;
            double yCoord;
            for (int i = 0; i < pixColor.length; i++) {
                xCoord = FractalGenerator.getCoord(rectangle.x, rectangle.x + rectangle.width, screenSize, i);
                yCoord = FractalGenerator.getCoord(rectangle.y, rectangle.y + rectangle.height, screenSize,
                        yCoordinate);
                int iterations_number = gen.numIterations(xCoord, yCoord);

                if (iterations_number == -1) {
                    pixColor[i] = 0;
                } else {
                    float hue = 0.7f + (float) iterations_number / 200f;
                    int rgbColor = Color.HSBtoRGB(hue, 1f, 1f);
                    pixColor[i] = rgbColor;

                }
            }

            return null;
        }

        // перебираем массив строк, рисуем пиксели, находящиеся в нем
        protected void done() {
            for (int i = 0; i < pixColor.length; i++) {
                img.drawPixel(i, yCoordinate, pixColor[i]);
            }

            // указываем область для перерисовки
            img.repaint(0, 0, yCoordinate, screenSize, 1);
            rowsRemaining--;
            if (rowsRemaining == 0) {
                enableUI(true);
            }
        }

    }

    public static void main(String[] args) {
        FractalExplorer explorer = new FractalExplorer(600);
        explorer.createAndShowGUI();
        explorer.drawFractal();
    }

}
Соседние файлы в папке лаб 4-5-6
  • #
    26.02.20231 Кб6BurningShip.class
  • #
    26.02.20232 Кб6BurningShip.java
  • #
    26.02.20233 Кб6FractalExplorer.class
  • #
    26.02.202310 Кб7FractalExplorer.java
  • #
    26.02.2023998 б6FractalExplorer$ChooseFractal.class
  • #
    26.02.20232 Кб6FractalExplorer$FractalWorker.class
  • #
    26.02.20231 Кб6FractalExplorer$MouseHandler.class
  • #
    26.02.2023834 б6FractalExplorer$ResetDisplay.class
  • #
    26.02.20232 Кб6FractalExplorer$SavePic.class