com.tarvon.fractala.util.ColorHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.tarvon.fractala.util.ColorHelper.java

Source

/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2015-2016 saybur
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.tarvon.fractala.util;

import java.awt.EventQueue;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;

import com.google.common.base.Strings;
import com.tarvon.fractala.Fractals;

/**
 * Graphical utility to help select {@link ColorChooser} values.
 * 
 * @author saybur
 *
 */
public class ColorHelper {
    @SuppressWarnings("serial")
    private final class ColorPanel extends JPanel {
        private ColorChooser chooser;

        public ColorPanel() {
            setOpaque(true);
            setPreferredSize(new Dimension(1024, 512));
        }

        @Override
        public void paint(Graphics g) {
            // get draw size
            final Dimension size = this.getSize();
            if (size == null)
                return;
            final int width = size.width;
            final int height = size.height;
            if (width == 0 || height == 0)
                return;

            // alias chooser
            final ColorChooser chooser = this.chooser;
            if (chooser == null) {
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, width, height);
                return;
            }

            // get seed
            final int seed = ((Integer) seedSpinner.getValue()).intValue();

            // draw
            final BufferedImage image = Fractals.createSimplexFractal(seed, 10).call().normalize(0, MAX)
                    .toImage(chooser);
            g.drawImage(image, 0, 0, null);
        }
    }

    private static final int ROWS = 16;
    private static final double MAX = 100.0;
    private static final Color ERROR_COLOR = new Color(255, 200, 200);
    private static final Color GOOD_COLOR = new Color(255, 255, 255);

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ColorHelper window = new ColorHelper();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private final JFrame frame;
    private final JSpinner seedSpinner;
    private final List<JSpinner> spinners;
    private final List<JTextField> fields;
    private final List<JCheckBox> checkboxes;
    private final List<JButton> buttons;
    private final ColorPanel colorPanel;

    private final JDialog colorChooserDialog;
    private final JColorChooser colorChooser;
    private boolean colorChooserOk;

    public ColorHelper() {
        frame = new JFrame("Color Helper");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();

        // make the color panel, and the chooser
        colorPanel = new ColorPanel();
        frame.getContentPane().add(colorPanel, BorderLayout.EAST);
        colorChooser = new JColorChooser();
        colorChooserDialog = JColorChooser.createDialog(frame, "Choose Color", true, colorChooser,
                e -> colorChooserOk = true, null);
        colorChooserOk = false;

        // create GUI elements
        spinners = IntStream.range(0, ROWS).boxed().map(i -> {
            final JSpinner spinner = new JSpinner(new SpinnerNumberModel(0.0, 0.0, MAX, 0.1));
            spinner.setBackground(ERROR_COLOR);
            spinner.addChangeListener(e -> update());
            spinner.setPreferredSize(new Dimension(80, spinner.getPreferredSize().height));
            return spinner;
        }).collect(Collectors.toList());
        fields = IntStream.range(0, ROWS).boxed().map(i -> {
            final JTextField field = new JTextField();
            field.setBackground(ERROR_COLOR);
            field.addActionListener(e -> update());
            field.setPreferredSize(new Dimension(80, field.getPreferredSize().height));
            return field;
        }).collect(Collectors.toList());
        checkboxes = IntStream.range(0, ROWS).boxed().map(i -> {
            final JCheckBox checkbox = new JCheckBox("?");
            checkbox.setSelected(true);
            checkbox.addActionListener(e -> update());
            return checkbox;
        }).collect(Collectors.toList());
        buttons = fields.stream().map(f -> {
            final JButton button = new JButton("...");
            button.setBackground(Color.BLACK);
            button.addActionListener(e -> chooseColor(f));
            return button;
        }).collect(Collectors.toList());
        final List<JPanel> panels = IntStream.range(0, ROWS).boxed().map(i -> {
            final JButton b = buttons.get(i);
            final JCheckBox c = checkboxes.get(i);

            final JPanel panel = new JPanel();
            panel.setLayout(new GridLayout(1, 2));
            panel.add(b);
            panel.add(c);
            return panel;
        }).collect(Collectors.toList());

        // put a few defaults in
        spinners.get(0).setValue(0.0);
        fields.get(0).setText("#000000");
        spinners.get(1).setValue(MAX);
        fields.get(1).setText("#FFFFFF");

        // create table of entry objects
        final JPanel entryPanel = new JPanel();
        entryPanel.setLayout(new GridLayout(ROWS, 3, 2, 2));
        for (int i = 0; i < ROWS; i++) {
            entryPanel.add(spinners.get(i));
            entryPanel.add(fields.get(i));
            entryPanel.add(panels.get(i));
        }
        frame.getContentPane().add(entryPanel);

        // the seed spinner
        seedSpinner = new JSpinner(new SpinnerNumberModel(1000, 1, Integer.MAX_VALUE, 1));
        seedSpinner.addChangeListener(e -> update());
        frame.getContentPane().add(seedSpinner, BorderLayout.NORTH);

        // redrawing button
        final JButton redrawButton = new JButton("Redraw");
        redrawButton.addActionListener(e -> update());
        frame.getContentPane().add(redrawButton, BorderLayout.SOUTH);

        update();
        frame.pack();
    }

    private void chooseColor(JTextField f) {
        // pick existing field color
        Color prev;
        try {
            prev = Color.decode(f.getText());
        } catch (Exception ex) {
            prev = Color.BLACK;
        }

        // let the user pick a color
        colorChooser.setColor(prev);
        colorChooserOk = false;
        colorChooserDialog.setVisible(true);
        Color picked = colorChooser.getColor();

        // then assign
        if (colorChooserOk) {
            String c = Integer.toHexString(picked.getRGB());
            if (c.length() == 7) {
                c = c.substring(1, 7);
            } else if (c.length() > 7) {
                c = c.substring(2, 8);
            } else if (c.length() < 6) {
                c = Strings.padStart(c, 6, '0');
            }
            f.setText("#" + c);

            // update gui post return
            update();
        }
    }

    private void update() {
        final ColorChooser.Builder b = ColorChooser.builder();
        for (int i = 0; i < ROWS; i++) {
            final JCheckBox chbx = checkboxes.get(i);
            final JSpinner spinner = spinners.get(i);
            final JTextField field = fields.get(i);
            final JButton button = buttons.get(i);

            // fetch color or error
            final Color color;
            try {
                color = Color.decode(field.getText());
                field.setBackground(GOOD_COLOR);
                button.setBackground(color);
            } catch (Exception e) {
                field.setBackground(ERROR_COLOR);
                button.setBackground(Color.BLACK);
                continue;
            }

            // now skip if disabled
            if (!chbx.isSelected())
                continue;

            // fetch value or error
            final double value;
            try {
                value = ((Double) spinner.getValue()).doubleValue();
                spinner.setBackground(GOOD_COLOR);
            } catch (Exception e) {
                spinner.setBackground(ERROR_COLOR);
                continue;
            }

            // insert into chooser
            b.add(value, color);
        }

        // assign
        try {
            ColorChooser chooser = b.create();
            colorPanel.chooser = chooser;
        } catch (Exception e) {
            colorPanel.chooser = null;
        }
        colorPanel.repaint();
    }
}