Форум программистов, компьютерный форум, киберфорум
Java: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.74/47: Рейтинг темы: голосов - 47, средняя оценка - 4.74
0 / 0 / 1
Регистрация: 11.12.2014
Сообщений: 14

Создать фрейм с областью для рисования «пером»

05.09.2015, 09:24. Показов 8752. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Задача эта конечно не новая, но всё-таки попрошу помочь разобраться. Вопрос полностью звучит так: "Создать фрейм с областью для рисования «пером». Создать меню для выбора цвета и толщины линии".

Я в качестве основы воспользовался материалом из двух статей:

1) http://eax.me/java-swing/ - здесь я взял основу формы для рисования.
2) - здесь основы реализации алгоритма.

Получился следующий код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.NumberFormat;
 
public class MySimplePaint extends JFrame {
 
    private int previousX, previousY;
    private  Object brushFormWidth = (int)6;
    private Color brushColor = Color.BLACK;
    private JPanel topPanel = new JPanel();
 
    public MySimplePaint (){
 
        addMouseListener(new MouseCoordinateReader());
        addMouseMotionListener(new PaintClass());
    }
 
    Image img = new ImageIcon("1.png").getImage();
 
    public void createGUI() {
 
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension screenSize = kit.getScreenSize();
        int screenW = screenSize.width;
        int screenH = screenSize.height;
 
        topPanel.setLayout(new BorderLayout());
        topPanel.setBackground(Color.WHITE);
 
        JButton selectColor = new JButton("Select Brush Color");
        JButton selectBrushWidth = new JButton("Select Brush Width");
 
        NumberFormat integerNumber;
        integerNumber = NumberFormat.getIntegerInstance();
        integerNumber.setMaximumIntegerDigits(2);
        integerNumber.setMinimumIntegerDigits(1);
 
        JFormattedTextField setBrushWidthValueFild = new JFormattedTextField(integerNumber);
 
        selectColor.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
 
                brushColor = JColorChooser.showDialog(((Component) e.getSource()).getParent(), "The color selection panel", brushColor);
            }
        });
 
        selectBrushWidth.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
 
                brushFormWidth = setBrushWidthValueFild.getValue();
 
            }
        });
 
        JPanel txtPannel = new JPanel();
        txtPannel.setLayout(new BorderLayout());
        txtPannel.add(Box.createHorizontalStrut(5));
        txtPannel.add(setBrushWidthValueFild);
 
        JPanel btnPannel = new JPanel();
        btnPannel.setLayout(new BoxLayout(btnPannel, BoxLayout.LINE_AXIS));
        btnPannel.add(selectColor);
        btnPannel.add(Box.createHorizontalStrut(5));
        btnPannel.add(selectBrushWidth);
 
        JPanel bottomPanel = new JPanel();
        bottomPanel.add(btnPannel);
 
        JPanel paintPanel = new JPanel();
        paintPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        paintPanel.setLayout(new BorderLayout());
        paintPanel.add(topPanel, BorderLayout.CENTER);
        paintPanel.add(txtPannel, BorderLayout.NORTH);
        paintPanel.add(bottomPanel, BorderLayout.SOUTH);
 
        JFrame mainFrame = new JFrame("My Simple Paint");
        mainFrame.setMinimumSize(new Dimension(screenW / 2, screenH / 2));
        mainFrame.setLocationByPlatform(true);
        mainFrame.setIconImage(img);
        mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        mainFrame.add(paintPanel);
        mainFrame.pack();
        mainFrame.setVisible(true);
 
        addMouseListener(new MouseCoordinateReader());
        addMouseMotionListener(new PaintClass());
 
    }
 
    private int getBrushWidthValue (Object aObject) {
 
        return (int) aObject;
    }
 
    public class MouseCoordinateReader extends MouseAdapter {
 
        public void setPreviousCoordinates(int _PrevX, int _PrevY) {
 
            previousX = _PrevX;
            previousY = _PrevY;
 
        }
 
        public void mousePressed(MouseEvent ev) {
 
            setPreviousCoordinates(ev.getX(), ev.getY());
 
        }
 
    }
    public class PaintClass extends MouseMotionAdapter {
 
        public void mouseDragged(MouseEvent ev) {
 
            MouseCoordinateReader mcr = new MouseCoordinateReader();
 
            Graphics2D  g = (Graphics2D )topPanel.getGraphics();
            BasicStroke brushForm = new BasicStroke(getBrushWidthValue(brushFormWidth), BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL);
 
            g.setStroke(brushForm);
            g.setColor(brushColor);
            g.drawLine(previousX, previousY, ev.getX(), ev.getY());
            mcr.setPreviousCoordinates(ev.getX(), ev.getY());
 
        }
    }
 
}
Только к сожалению не могу понять, почему перо не рисует, хотя как мне кажется код должен работать. В одной из предыдущих версий этой программки, созданной при помощи редактора форм IDEA 14 рисовать получалось, но структура программы была другой.

В методе main создаётся экземпляр класса и запускается метод: MySimplePaint msp = new MySimplePaint(); msp.createGUI().

Подскажите, почему не работает addMouseListener(new MouseCoordinateReader()); addMouseMotionListener(new PaintClass()); и насколько корректна реализация brushFormWidth = setBrushWidthValueFild.getValue() при нажатии на кнопку. Заранее спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.09.2015, 09:24
Ответы с готовыми решениями:

Написать приложения для рисования эллипсов с закрашенной внутренней областью
Написать приложения для рисования эллипсов с закрашенной внутренней областью.

Как создать приложение с областью для окон?
Область внутри который могут создаваться окна, как в visual studio например

Создать приложение для рисования окружности
Создать приложение для изображения окружности. Радиус задается в строке редактирования. Создать обработчик события, который предоставит...

2
0 / 0 / 1
Регистрация: 11.12.2014
Сообщений: 14
06.09.2015, 14:14  [ТС]
Перетрёс код, кое как заработало. На данный момент вариант такой:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class Main {
 
    public static void main(String[] args) {
 
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
 
                Image img = new ImageIcon("1.png").getImage();
                mySimplePaint msp = new mySimplePaint();
 
                Toolkit kit = Toolkit.getDefaultToolkit();
                Dimension screenSize = kit.getScreenSize();
                int screenW = screenSize.width;
                int screenH = screenSize.height;
 
                msp.setMinimumSize(new Dimension(screenW / 2, screenH / 2));
                msp.setTitle("My Simple Paint");
                msp.setLocationByPlatform(true);
                msp.pack();
                msp.setVisible(true);
                msp.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                msp.setIconImage(img);
 
            }
        });
 
    }
 
   public static class mySimplePaint extends JFrame {
 
       private int previousX, previousY;
 
       private  int brushFormWidth = 1;
       private Color brushColor = Color.BLACK;
 
       private JPanel paintPanel = new JPanel();
       private JPanel btnPanel = new JPanel();
 
       private JButton selectBrushColorButton = new JButton("Select Color");
       private JButton selectBrushWidthButton = new JButton("Select Brush Width");
 
       private JTextField setBrushWidthValueFild = new JTextField();
 
       public mySimplePaint() {
 
           Container c = getContentPane();
           c.add(paintPanel, BorderLayout.CENTER);
           c.add(btnPanel, BorderLayout.SOUTH);
 
           setBrushWidthValueFild.setColumns(10);
           setBrushWidthValueFild.setHorizontalAlignment(JTextField.CENTER);
 
           paintPanel.setLayout(new BorderLayout());
           paintPanel.setBackground(Color.WHITE);
 
           btnPanel.add(selectBrushColorButton);
           btnPanel.add(selectBrushWidthButton);
           btnPanel.add(setBrushWidthValueFild);
 
           selectBrushColorButton.addActionListener(new colorButtonActionListener());
           selectBrushWidthButton.addActionListener(new widthButtonActionListener());
 
           addMouseListener(new MouseCoordinateReader());
           addMouseMotionListener(new PaintClass());
 
       }
 
       private class colorButtonActionListener implements ActionListener {
 
           public void actionPerformed(ActionEvent e) {
 
               brushColor = JColorChooser.showDialog(((Component) e.getSource()).getParent(), "Select brush color panel", brushColor);
 
           }
 
       }
 
       private class widthButtonActionListener implements ActionListener {
 
           public void actionPerformed(ActionEvent e) {
 
               String str =  setBrushWidthValueFild.getText();
               boolean b = str.matches("\\d+");
 
               if (b && str.length()<=2) {
 
                   brushFormWidth = Integer.parseInt(setBrushWidthValueFild.getText());
 
               } else JOptionPane.showMessageDialog(null, "Не увлекайтесь размером кисти и не вводите буквенные символы! Значение более 99 не рекомедуется.", "Ошибочное значение", JOptionPane.ERROR_MESSAGE);
 
           }
 
       }
 
       private class MouseCoordinateReader extends MouseAdapter {
 
           public void mousePressed(MouseEvent ev) {
 
               setPreviousCoordinates(ev.getX(), ev.getY());
 
           }
 
       }
 
       private class PaintClass extends MouseMotionAdapter {
 
           public void mouseDragged(MouseEvent ev) {
 
               Graphics2D g = (Graphics2D)getGraphics();
               BasicStroke brushForm = new BasicStroke(brushFormWidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL);
 
               g.setStroke(brushForm);
               g.setColor(brushColor);
               g.drawLine(previousX, previousY, ev.getX(), ev.getY());
               setPreviousCoordinates(ev.getX(), ev.getY());
 
           }
 
       }
 
       public void setPreviousCoordinates(int aPrevX, int aPrevY) {
 
           previousX = aPrevX;
           previousY = aPrevY;
 
       }
   }
 
}
Но есть два момента, которые хотелось бы поправить:

1) В части
Java
1
Graphics2D g = (Graphics2D)getGraphics();
получается, что кисть рисует по всей области, в т.ч. по кнопкам и текстовому полю. Если изменить код на
Java
1
Graphics2D g = (Graphics2D)paintPanel.getGraphics();
, то рисует где надо, только линия рисуется под указателем мыши, а не вслед за его кончиком. Не знаю, как это исправить.

2) Хотелось бы в JTextPane добавить сообщение-подсказку, что в это поле вводить, так чтобы при появлении указателя в поле ввода текст исчезал.
0
0 / 0 / 0
Регистрация: 14.04.2016
Сообщений: 1
27.02.2019, 18:19
Evge_n, Сейчас данная программа у вас есть, можете мне отправить?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.02.2019, 18:19
Помогаю со студенческими работами здесь

Создать поток для рисования в picturebox
Как создать поток для рисования в picturebox, ведь там нужно 2 аргумента?

Создать фрейм с двумя полями для ввода текста и одной кнопкой сохранения значения полей в переменные
Нужно создать фрейм с двумя полями для ввода текста и одной кнопкой при нажатии которой он сохраняет текст первого поля в перемнную А, а...

Как и где создать процедуру с глобальной областью видимости
Здравствуйте. Я хотел спросить, можно ли создать подпрограмму(процедуру или что то на подобии), что б вызывать с любой формы. У меня в...

В чате есть фрейм с юзерами, как по клику вставить имя юзера в другой фрейм?
Это делается для приватных сообщений, ну типа такого(окно чата): Stas =&gt; : вобщим кодить еще много чего Stas =&gt;...

Работа с пером в режиме слой фигура
Ребят фотошоп изучаю не давно вот прохожу урок И у меня сразу же возникли трудности Используя Pen Tool (Перо) (P) в режиме shape...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru