@Ezekiel4
Охотник на пиратов и сборщик монолитов

Подходит ли библиотека swing, чтобы воспроизвести MS Paint (win7)?

Здравстуйте! На данный момент реализована только круглая кисть и возможность настройки её размера, цвета и прозрачности, а также функция очистки холста. Инструменты в одном окне JFrame, холст в другом.
Я хочу, чтобы всё было как в пеинте - в одном окне и выглядело так же. Пока единственный способ, как я могу это сделать - попиксельно отрисовать весь экран. Но не уверен, что это хороший подход.
Также у меня ещё есть проблема: чем быстрее я веду мышкой по холсту, тем сильнее получаемая линия разрывается. Это можно как-то решить?
PS. Я не привязан конкретно к swing, просто к другим ui фреймворкам я ещё даже не прикасался. Но если есть вариант лучше, я воспользуюсь им.

Иллюстрация
6070417aaf354039071523.png


Paint.java
package paint;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;

import javax.swing.*;
import javax.swing.event.*;

public class Paint {

	private JFrame frame1, frame2;
	private JPanel panel1;
	private JSlider sl_red, sl_green, sl_blue, sl_size, sl_transparency;
	private JButton btn_clear;
	private Color color;

	private PaintData paintdata;

	private PaintPanel panel2;
	private PaintActionListener actionListener;
	private PaintChangeListener listener;
	private PaintMouseListener mouseListener;
	private PaintMouseMotionListener mouseMotionListener;

	public Paint() {
		initBrushesPanel();
		setBrushesAttributes();

		initDrawingPanel();
		setDrawingAttributes();
	}

	public void initBrushesPanel() {
		frame1 = new JFrame();
		panel1 = new JPanel();

		listener = new PaintChangeListener();
		actionListener = new PaintActionListener();

		sl_red = new JSlider(0, 255);
		sl_green = new JSlider(0, 255);
		sl_blue = new JSlider(0, 255);
		sl_size = new JSlider(0, 100);
		sl_transparency = new JSlider(0, 100);

		btn_clear = new JButton("Clear");
	}

	private void initSlider(JSlider js, ChangeListener cl, String title, int ticksSparcing, int val) {
		js.addChangeListener(cl);
		js.setBorder(BorderFactory.createTitledBorder(title));
		js.setMajorTickSpacing(ticksSparcing);
		js.setValue(val);
		js.setPaintTicks(true);
		js.setPaintLabels(true);
		panel1.add(js);
	}

	public void setBrushesAttributes() {
		initSlider(sl_red, listener, "Red", 50, 0);
		initSlider(sl_green, listener, "Green", 50, 0);
		initSlider(sl_blue, listener, "Blue", 50, 0);

		initSlider(sl_size, listener, "Size", 25, 5);
		initSlider(sl_transparency, listener, "Transparency", 25, 100);

		btn_clear.addActionListener(actionListener);
		panel1.add(btn_clear);

		frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame1.setSize(220, 600);
		frame1.setResizable(false);
		frame1.add(panel1);
		frame1.setVisible(true);
	}

	public void initDrawingPanel() {
		mouseListener = new PaintMouseListener();
		mouseMotionListener = new PaintMouseMotionListener();

		paintdata = new PaintData();

		frame2 = new JFrame();
		panel2 = new PaintPanel();
	}

	public void setDrawingAttributes() {
		panel2.addMouseListener(mouseListener);
		panel2.addMouseMotionListener(mouseMotionListener);

		frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame2.setLocation(285, 0);
		frame2.setSize(800, 600);
		frame2.setResizable(false);
		frame2.add(panel2);
		frame2.setVisible(true);
	}

	private class PaintActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == btn_clear) {
				paintdata.reset();
				panel2.repaint();
			}
		}
	}

	private class PaintMouseListener implements MouseListener {
		@Override
		public void mouseClicked(MouseEvent e) {
			if (e.getSource() == panel2) {
				int drawX = e.getX() - sl_size.getValue() / 2;
				int drawY = e.getY() - sl_size.getValue() / 2;

				Shape shape = new Ellipse2D.Double(drawX, drawY, sl_size.getValue(), sl_size.getValue());
				paintdata.add(shape, color, sl_transparency.getValue() / 100f);
				panel2.repaint();
			}
		}

		@Override
		public void mousePressed(MouseEvent e) {
		}

		@Override
		public void mouseReleased(MouseEvent e) {
		}

		@Override
		public void mouseEntered(MouseEvent e) {
		}

		@Override
		public void mouseExited(MouseEvent e) {
		}
	}

	private class PaintMouseMotionListener implements MouseMotionListener {
		@Override
		public void mouseDragged(MouseEvent e) {
			if (e.getSource() == panel2) {
				int drawX = e.getX() - sl_size.getValue() / 2;
				int drawY = e.getY() - sl_size.getValue() / 2;

				Shape shape = new Ellipse2D.Double(drawX, drawY, sl_size.getValue(), sl_size.getValue());
				paintdata.add(shape, color, sl_transparency.getValue() / 100f);
				panel2.repaint();
			}
		}

		@Override
		public void mouseMoved(MouseEvent e) {
		}

	}

	private class PaintChangeListener implements ChangeListener {
		@Override
		public void stateChanged(ChangeEvent e) {
			if (e.getSource() == sl_red || e.getSource() == sl_green || e.getSource() == sl_blue) {
				color = new Color(sl_red.getValue(), sl_green.getValue(), sl_blue.getValue());
				panel1.setBackground(color);
			}
		}
	}

	private class PaintPanel extends JPanel {
		public void paintComponent(Graphics gr) {
			Graphics2D g = (Graphics2D) gr;

			g.setColor(Color.WHITE);
			g.fillRect(0, 0, 800, 600);

			for (int i = 0; i < paintdata.size(); i++) {
				g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, paintdata.getTransparency(i)));
				g.setColor(paintdata.getColor(i));
				g.fill(paintdata.getShape(i));
			}
		}
	}
	
	public static void main(String[] args) {
		new Paint();
	}
}


PaintData.java
package paint;

import java.awt.*;
import java.util.ArrayList;

public class PaintData {

	private ArrayList<Shape> shapes;
	private ArrayList<Color> colors;
	private ArrayList<Float> transp;

	public PaintData() {
		shapes = new ArrayList<Shape>();
		colors = new ArrayList<Color>();
		transp = new ArrayList<Float>();
	}

	public void add(Shape shape, Color color, Float transparency) {
		shapes.add(shape);
		colors.add(color);
		transp.add(transparency);
	}

	public Shape getShape(int index) {
		return shapes.get(index);
	}

	public Color getColor(int index) {
		return colors.get(index);
	}

	public Float getTransparency(int index) {
		return transp.get(index);
	}

	public void reset() {
		shapes.clear();
		colors.clear();
		transp.clear();
	}
	
	public int size() {
		return shapes.size();
	}
}
  • Вопрос задан
  • 59 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽
19 апр. 2024, в 03:52
1000 руб./за проект
19 апр. 2024, в 03:01
1000 руб./за проект
18 апр. 2024, в 21:56
2000 руб./за проект