Форум программистов, компьютерный форум, киберфорум
Java: GUI, графика
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/83: Рейтинг темы: голосов - 83, средняя оценка - 4.54
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30

Не могу понять, как работать с графикой

22.01.2012, 14:24. Показов 17713. Ответов 53
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть примитивная программа. Создаётся Frame, в нём создаётся Panel, далее в методе paintComponent рисуется линия. Как теперь человеческими способами переписать программу так, чтобы то, что требуется нарисовать, рисовалось, к примеру, в функции main, потому что принятие решений о том, что рисовать, должно делаться НЕ внутри paintComponent. Как идеальный пример хотелось бы увидеть программу, которая нарисует одну линию, а через 5 секунд нарисует вторую линию

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
import java.awt.*;
import javax.swing.*;
 
public class Main {
  public static void main (String[] args)
  {
    MyFrame frame = new MyFrame ();
    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    frame.setVisible (true);
  }
}
 
class MyFrame extends JFrame
{
  public MyFrame()
  {
    this.setBounds (0, 0, 200, 200);
    
    MyPanel panel = new MyPanel();
    this.add (panel);
  }
}
 
class MyPanel extends JPanel
{
  public void paintComponent (Graphics g)
  {
    super.paintComponent (g);   
    g.drawLine (10, 10, 180, 180);  
  }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.01.2012, 14:24
Ответы с готовыми решениями:

Не могу понять как работать с событиями
Здравствуйте. Подскажите пожалуйста такую вещь: У меня при нажатии на кнопку выбора файла , появляется лэйбл на форме и после выбора файла...

TStyleManager, не могу понять как работать с ним
Ребята! Помогите! Хочу сделать программу покрасивее, но я не могу понять как работать с ним. Класс создаю. Пишет ошибку: Undeclared...

Не могу понять, как должна работать модель
Не могу понять алгоритм работы модели, кто может, подскажите как данная модель должна функционировать. Что это за терминалы, где...

53
_
2364 / 1243 / 78
Регистрация: 28.10.2009
Сообщений: 4,331
22.01.2012, 15:12
что-то типа того - рисуем новую линию через 3 секунды
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
import java.awt.*;
import javax.swing.*;
import java.lang.Thread;
 
public class Main {
  public static void main (String[] args) throws InterruptedException
  {
    MyFrame frame = new MyFrame ();
    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    frame.setVisible (true);
    Thread.sleep(3000);
    lineDraw(frame, 100,10);    
  }
  public static void lineDraw(MyFrame frame, int x, int y) 
  {
    frame.Line_Draw(x, y);
  }
}
 
class MyFrame extends JFrame
{
    MyPanel panel;
  public MyFrame()
  {
    this.setBounds (0, 0, 200, 200);  
  }
  public void paint(Graphics g)
        {
            g.drawLine(10, 10, 130, 140);           
        }
 
  public void Line_Draw(int x, int y)
  {
    Graphics g = getGraphics();
    
    g.drawLine(x, y, 130, 140);
    repaint();
  }
}
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
22.01.2012, 15:28  [ТС]
1. Зачем в методе MyFrame.paint оставлено рисование линии? И почему если это место закомментировать, то при запуске программы окно не прорисовывается?
2. В моём примере (взято из книги), рисование происходит на панели. В твоём, если я правильно понимаю, прямо на фрейме. Какая между этими вещами разница?

Добавлено через 5 минут
Если перефразировать мой изначальный вопрос, то звучать он будет примерно так. В моём тестовом примере по сути дела рисуется СТАТИЧЕСКАЯ КАРТИНКА. А мне хотелось бы уметь это делать динамически. Например, как реализовать передвигающийся кружок (квадрат, треугольник, не суть) мне непонятно. А точнее, непонятно, как это безе черезжо..ностей сделать
0
_
2364 / 1243 / 78
Регистрация: 28.10.2009
Сообщений: 4,331
22.01.2012, 16:22
ну что-то типа того
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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.Thread;
 
public class Main {
  public static void main (String[] args) throws InterruptedException
  {
    final MyFrame frame = new MyFrame ();
    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    frame.setVisible (true);
          Timer timer = new Timer( 1000, new ActionListener()
          {
              public void actionPerformed(ActionEvent e)
              {
                    frame.panel.x=frame.panel.x+10;
                    frame.repaint();
              }
          } );
          timer.start();
  }
}
 
class MyFrame extends JFrame
{
    MyPanel panel;
  public MyFrame()
  {
    setSize(200,200);
    panel= new MyPanel();
    add(panel);
  }
 
}
class MyPanel extends JPanel
{
    int x =10;
    int y = 10;
  public void paintComponent(Graphics g)
  {
    g.drawLine(x, y, 130, 140);
  } 
  }
Ну вместо лини можно задать кружок, квадрат и т.д.
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
22.01.2012, 17:16  [ТС]
Ну это и есть черезж...е решение. Чтобы добавить ещё один рисующийся объект, надо опять в несколько классов чего-то добавлять. Неужто нет "классических" способов без того, чтобы низкий уровень (панель для отображения) НЕ знал о том, что надо рисовать? Потому что это не его дело. Его дело - рисовать, а "наверху" должны решать, что рисовать. Т.е. нужно нарисовать круг - "наверху" нарисовали круг, без того, чтобы что-то добавлять в класс "внизу"
0
636 / 528 / 165
Регистрация: 01.04.2010
Сообщений: 1,843
23.01.2012, 07:02
Цитата Сообщение от Evg Посмотреть сообщение
Неужто нет "классических" способов без того, чтобы низкий уровень (панель для отображения) НЕ знал о том, что надо рисовать?
А как можно нарисовать что-то, не зная что именно?

В самом простом варианте, можно поступить следующим образом:
1. Создаешь свой интерфейс
Java
1
2
3
interface Drawable {
    void draw(Graphics2D g);
}
2. Создаешь своего наследника от JComponent:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MyComponent extends JComponent {
 
    private List<Drawable> drawables = new ArrayList<Drawable>();
 
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        for (Drawable d : drawables) {
            d.draw(g2d);
        }
    }
 
    public void addDrawable(Drawable d) {
        drawables.add(d);
        repaint();
    }
}
3. Создаешь конкретные имплементации Drawable.
4. PROFIT!
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
23.01.2012, 11:32  [ТС]
Цитата Сообщение от aleksandy Посмотреть сообщение
А как можно нарисовать что-то, не зная что именно?
Элементарно. Во всяком случая, я себе представлял, что реализовано что-то типа следующего. "Наверху" срашивают у "низа" что-то типа "дай мне графический контекст для рисования". На нём "наверху" отображают всё, что надо, а потом отдают "вниз" приказ типа "мы закончили рисовать, отображай на экран". Схематически что-то типа того:

Java
1
2
3
4
5
6
7
8
// Внутри метода main
...
Graphics g = JFrame.getGraphics(); // интерфейс обозвал условно
g.drawLine(...);
g.drawBox(...);
...
g.repaint();
...
При таком раскладе мы "наверху" рисуем то, что нам надо, не занимаясь извращениями в виде дополнительных классов и надстроек "внизу". "Внизу" вообще ничего не должны знать о том, какие данные имеются в нашей программе. "Внизу" должны только делать то, что требуют "сверху", не занимаясь хранением дополнительных данных и знаний о том, что же надо рисовать. Наподобие того, что есть в Borland'е: см. Краткое руководство по работе с классом TCanvas для начинающих раздел 1.1. Метод ButtonClick - это обработчик событий, хотя на его месте можно вполне себе поставить main-поток исполнения задачи, НЕ ЗАВОДЯ НИКАКИХ ДОПОЛНИТЕЛЬНЫХ КЛАССОВ. Неужто в java нельзя сделать вот так по простому?

Добавлено через 47 секунд
Цитата Сообщение от aleksandy Посмотреть сообщение
В самом простом варианте, можно поступить следующим образом:
Можешь написать итоговую программу целиком? Потому что я в java только пытаюсь разобраться. И уже на первом шаге начинаю ощущать дикое разочарование
0
636 / 528 / 165
Регистрация: 01.04.2010
Сообщений: 1,843
23.01.2012, 13:42
Цитата Сообщение от Evg Посмотреть сообщение
"Внизу" должны только делать то, что требуют "сверху", не занимаясь хранением дополнительных данных и знаний о том, что же надо рисовать.
А что насчет перерисовки при растягивании, перемещении и пр.? Где-то инфа о том, что необходимо рисовать все равно должна храниться. Понажимай на "manual draw", а потом измени размер окна.

Интерфейс описан выше.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Oval implements Drawable {
 
    private int x, y, w, h;
 
    public Oval(int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }
 
    @Override
    public void draw(Graphics2D g) {
        g.drawOval(this.x, this.y, this.w, this.h);
    }
 
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Line implements Drawable {
 
    private int x1, y1, x2, y2;
 
    public Line(int x1, int y1, int x2, int y2) {
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
    }
 
    @Override
    public void draw(Graphics2D g) {
        g.drawLine(this.x1, this.y1, this.x2, this.y2);
    }
 
}
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
public class Drawer extends JComponent {
 
    private List<Drawable> drawables = new ArrayList<Drawable>();
 
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        for (Drawable d : this.drawables) {
            d.draw(g2d);
        }
    }
 
    public void addDrawable(Drawable d) {
        this.drawables.add(d);
        repaint();
    }
 
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
 
            @Override
            public void run() {
                JFrame f = new DrawerFrame("drawer");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationRelativeTo(null);
                f.setSize(300, 200);
                f.setVisible(true);
            }
 
        });
    }
 
    static class DrawerFrame extends JFrame {
 
        Drawer drawer = new Drawer();
 
        public DrawerFrame(String title) {
            super(title);
            createGUI();
        }
 
        private void createGUI() {
            setLayout(new BorderLayout());
            add(this.drawer, BorderLayout.CENTER);
            add(createRightPanel(), BorderLayout.EAST);
        }
 
        private JPanel createRightPanel() {
            JPanel result = new JPanel();
            result.setLayout(new BoxLayout(result, BoxLayout.Y_AXIS));
            final Random rnd = new Random();
            final JComboBox combo = new JComboBox(new Object[] {"line", "oval"});
            result.add(combo);
            result.add(new JButton(new AbstractAction("add drawable") {
 
                @Override
                public void actionPerformed(ActionEvent e) {
                    int maxWidth = DrawerFrame.this.drawer.getWidth();
                    int maxHeight = DrawerFrame.this.drawer.getHeight();
                    switch (combo.getSelectedIndex()) {
                        case 0 :
                            DrawerFrame.this.drawer.addDrawable(new Line(rnd.nextInt(maxWidth), rnd.nextInt(maxHeight), rnd.nextInt(maxWidth), rnd.nextInt(maxHeight)));
                            break;
                        case 1 :
                            DrawerFrame.this.drawer.addDrawable(new Oval(rnd.nextInt(maxWidth), rnd.nextInt(maxHeight), rnd.nextInt(maxWidth), rnd.nextInt(maxHeight)));
                            break;
                        default :
                            throw new IllegalStateException("unknow drawable");
                    }
                }
 
            }));
            result.add(new JButton(new AbstractAction("manual draw") {
 
                @Override
                public void actionPerformed(ActionEvent e) {
                    Graphics2D g2d = (Graphics2D) DrawerFrame.this.drawer.getGraphics();
                    int maxWidth = DrawerFrame.this.drawer.getWidth();
                    int maxHeight = DrawerFrame.this.drawer.getHeight();
                    g2d.fill3DRect(rnd.nextInt(maxWidth), rnd.nextInt(maxHeight), rnd.nextInt(maxWidth), rnd.nextInt(maxHeight), false);
                }
            }));
            result.add(Box.createVerticalGlue());
            return result;
        }
    }
}
1
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
23.01.2012, 14:29
Evg, посмотрите программку из этого поста Движение фигуры
и вот еще небольшой пример рисования
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
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public class MainForm {
   private int[] color = { 0xffff0000, 0xffc00000, 0xff802000, 0xff404000, 0xff208000, 0xff00c000,
         0xff00ff00, 0xff00c000, 0xff8020, 0xff004040, 0xff002080, 0xff0000c0, 0xff0000ff,
         0xff0000c0, 0xff200080, 0xff400040, 0xff800020, 0xffc00000 };
 
   private int current = 0;
 
   public MainForm() {
      JFrame mainForm = new JFrame("Main Form");
      mainForm.setSize(400, 400);
      mainForm.setMinimumSize(new Dimension(649, 600));
      mainForm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      mainForm.setVisible(true);
 
      final JPanel imagePanel = new JPanel();
      imagePanel.setVisible(true);
 
      imagePanel.addMouseMotionListener(new MouseMotionListener() {
         private Point last = null;
 
         @Override
         public void mouseMoved(MouseEvent event) {
            Graphics g = imagePanel.getGraphics();
            g.setColor(new Color(color[current]));
            if (last != null) {
               g.drawLine(event.getX(), event.getY(), last.x, last.y);
            } else {
               g.drawLine(event.getX(), event.getY(), event.getX(), event.getY());
               last = new Point();
            }
            last.setLocation(event.getX(), event.getY());
         }
 
         @Override
         public void mouseDragged(MouseEvent arg0) {
 
         }
      });
      imagePanel.addMouseListener(new MouseListener() {
 
         @Override
         public void mouseReleased(MouseEvent arg0) {
         }
 
         @Override
         public void mousePressed(MouseEvent arg0) {
 
         }
 
         @Override
         public void mouseExited(MouseEvent arg0) {
 
         }
 
         @Override
         public void mouseEntered(MouseEvent arg0) {
 
         }
 
         @Override
         public void mouseClicked(MouseEvent arg0) {
            ++current;
            if (current == color.length)
               current = 0;
         }
      });
      mainForm.getContentPane().add(imagePanel);
   }
 
   public static void main(String[] args) {
      new MainForm();
   }
 
}
0
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
23.01.2012, 14:59
Цитата Сообщение от Evg Посмотреть сообщение
Неужто нет "классических" способов без того, чтобы низкий уровень (панель для отображения) НЕ знал о том, что надо рисовать? Потому что это не его дело. Его дело - рисовать, а "наверху" должны решать, что рисовать. Т.е. нужно нарисовать круг - "наверху" нарисовали круг, без того, чтобы что-то добавлять в класс "внизу"
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
23.01.2012, 17:02  [ТС]
Цитата Сообщение от aleksandy Посмотреть сообщение
А что насчет перерисовки при растягивании, перемещении и пр.? Где-то инфа о том, что необходимо рисовать все равно должна храниться
Вот borland'овская библиотека VCL реализована таким образом, что по умолчанию пользователю кроме как что-то нарисовать один раз, больше ничегоне нужно. При всех растягиваниях, переключениях окна и т.п. вся перерисовка делается автоматически. Ни разу не работал в MSVC или Qt, но более, чем уверен, что там сделано ровно так же

Цитата Сообщение от M128K145 Посмотреть сообщение
Вот посмотрите и переделайте под свои нужды, кое как, но работает
В обоих случаях то же самое. Вся прорисовка происходит "внизу". Т.е. класс, отвечающий за панельку (которая должна быть не более, чем бумажкой для рисования), должен содержать в себе информацию о том, что и как рисовать. Может я хочу слишком многого, но с точки зрения нормального проектирования программы такая модель работы, на мой взгляд, является полным убожеством

Добавлено через 1 минуту
При этом, насколько я понимаю, в языке нет понятия типа "указатель на метод", чтобы хотя бы через hook рисовать
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
23.01.2012, 21:08
Цитата Сообщение от Evg Посмотреть сообщение
В обоих случаях то же самое. Вся прорисовка происходит "внизу". Т.е. класс, отвечающий за панельку (которая должна быть не более, чем бумажкой для рисования), должен содержать в себе информацию о том, что и как рисовать. Может я хочу слишком многого, но с точки зрения нормального проектирования программы такая модель работы, на мой взгляд, является полным убожеством
ну так ООП же, взял унаследовался и переопределил или расширил возможности, подрисовал сам поверху, чем ниже тем больше функционала, что тут убогого?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
24.01.2012, 01:18  [ТС]
Цитата Сообщение от mutagen Посмотреть сообщение
ну так ООП же, взял унаследовался и переопределил или расширил возможности, подрисовал сам поверху, чем ниже тем больше функционала, что тут убогого?
Тогда ещё раз повторю постановку задачи (ну и немного изменю). Возьми мой оригинальный пример и перепиши его так, чтобы на экране отобразилось 10 произвольных линий с интервалом в 1 секунду. То, что интервал между прорисовками 1 секунда - это чистая условность (там могло бы быть по нажатию кнопки, по движению мыши и т.п.), лишь бы картинка была не статическая, а динамическая (т.е. менялась во времени). Желательно написать готовый пример, а не просто "отнаследуй тут, напиши там". И желательно простой и аккуратный (потому что через ж...у я и сам смогу)
0
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
24.01.2012, 02:33
Цитата Сообщение от Evg Посмотреть сообщение
Тогда ещё раз повторю постановку задачи (ну и немного изменю). Возьми мой оригинальный пример и перепиши его так, чтобы на экране отобразилось 10 произвольных линий с интервалом в 1 секунду. То, что интервал между прорисовками 1 секунда - это чистая условность (там могло бы быть по нажатию кнопки, по движению мыши и т.п.), лишь бы картинка была не статическая, а динамическая (т.е. менялась во времени).
код из девятого поста именно это и делает и соответствует требованиям - я просто рисую линии мышью на панели.
В C# применяется такой же подход.
0
636 / 528 / 165
Регистрация: 01.04.2010
Сообщений: 1,843
24.01.2012, 08:18
Evg,
если тебе так не нравятся общепринятые в языке практики, то зачем вообще использовать этот язык?

Цитата Сообщение от Evg Посмотреть сообщение
Вот borland'овская библиотека VCL реализована таким образом, что по умолчанию пользователю кроме как что-то нарисовать один раз, больше ничегоне нужно.
Значит сохранение инфы реализовано внутри VLC-библиотеки. Чудес не бывает.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
24.01.2012, 14:02  [ТС]
Цитата Сообщение от M128K145 Посмотреть сообщение
код из девятого поста именно это и делает и соответствует требованиям - я просто рисую линии мышью на панели.
Я что-то сначала только ссылку смотрел и твой код забыл посмотреть. Сейчас посмотрел. Я просил нарисовать 10 линий с интервалом в 1 секунду, но не просил рисовать точки, отображающие текущую позицию мыши. Если несложно, напиши код, который я хотел видеть.

Цитата Сообщение от aleksandy Посмотреть сообщение
Evg,
если тебе так не нравятся общепринятые в языке практики, то зачем вообще использовать этот язык?
Я его не использую. Я просто подумал, что для расширения кругозора надо бы научиться хотя бы что-то и как-то сделать на java. Пока читал книгу раздел про графику, мне это жутко не понравилось, как там реализовано. Книга книгой, но решил потыкаться сам. Не получилось. Попросил на форуме. Мои худшие опасения пока подтверждаются.

Цитата Сообщение от aleksandy Посмотреть сообщение
Значит сохранение инфы реализовано внутри VLC-библиотеки. Чудес не бывает.
Естественно, что всё необходимое реализовано в VCL. Т.е. разработчики VCL очень серьёзно потрудились для того, чтобы модель работы с графикой привести в нормальный человеческий вид, удобный для использования. А вот разработчики java (а точнее, разработчики Swing'а), судя по всему, переложили геморрой на плечи пользователя. На форум я полез из-за того, что вполне может оказаться так, что в книге пишут не всё, а по технической документации понять что-либо слишком сложно. И надеялся, что всё-таки есть какая-то нормальная модель работы с графикой, которая бы не противоречила принципам ООП
0
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
24.01.2012, 15:11
Цитата Сообщение от Evg Посмотреть сообщение
но не просил рисовать точки, отображающие текущую позицию мыши
на самом деле там рисуются линии, соединяющие точки
Цитата Сообщение от M128K145 Посмотреть сообщение
Java
1
g.drawLine(event.getX(), event.getY(), last.x, last.y);
Вот отрисовка по таймеру:
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
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
 
public class MainForm {
 
   public MainForm() {
      JFrame mainForm = new JFrame("Main Form");
      mainForm.setSize(400, 400);
      mainForm.setMinimumSize(new Dimension(649, 600));
      mainForm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      mainForm.setVisible(true);
 
      final JPanel imagePanel = new JPanel();
      imagePanel.setVisible(true);
      final Random random = new Random();
 
      final Timer timer = new Timer(1000, new ActionListener() {
         private int count = 0;
 
         @Override
         public void actionPerformed(ActionEvent event) {
            int x1 = random.nextInt(imagePanel.getWidth());
            int y1 = random.nextInt(imagePanel.getHeight());
            int x2 = random.nextInt(imagePanel.getWidth());
            int y2 = random.nextInt(imagePanel.getHeight());
            imagePanel.getGraphics().drawLine(x1, y1, x2, y2);
            ++count;
            if (count == 10) {
               count = 0;
               ((Timer) event.getSource()).stop();
            }
         }
 
      });
 
      imagePanel.addMouseListener(new MouseListener() {
 
         @Override
         public void mouseReleased(MouseEvent arg0) {
         }
 
         @Override
         public void mousePressed(MouseEvent arg0) {
 
         }
 
         @Override
         public void mouseExited(MouseEvent arg0) {
 
         }
 
         @Override
         public void mouseEntered(MouseEvent arg0) {
 
         }
 
         @Override
         public void mouseClicked(MouseEvent arg0) {
            timer.start();
         }
      });
      mainForm.getContentPane().add(imagePanel);
   }
 
   public static void main(String[] args) {
      new MainForm();
   }
 
}
Таймер запускается по клику мыши
1
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
24.01.2012, 15:13
ну вот я накидал как вы просили, только по клику

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
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Random;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public class TenLines {
    private Random rnd = new Random();
 
    public TenLines() {
        JFrame mainForm = new JFrame("Main Form");
        mainForm.setSize(400, 400);
        mainForm.setMinimumSize(new Dimension(649, 600));
        mainForm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainForm.setVisible(true);
 
        final MyVcl imagePanel = new MyVcl();
        imagePanel.setVisible(true);
        Line lines[] = { new Line(rnd.nextInt(300), rnd.nextInt(300), rnd.nextInt(300), rnd.nextInt(300)) };
        for (Line line : lines) {
            imagePanel.drawVcl(line);
        }
        imagePanel.addMouseListener(new MouseListener() {
 
            @Override
            public void mouseReleased(MouseEvent arg0) {
 
            }
 
            @Override
            public void mousePressed(MouseEvent arg0) {
 
            }
 
            @Override
            public void mouseExited(MouseEvent arg0) {
 
            }
 
            @Override
            public void mouseEntered(MouseEvent arg0) {
 
            }
 
            @Override
            public void mouseClicked(MouseEvent arg0) {
                imagePanel.drawVcl(new Line(rnd.nextInt(300), rnd.nextInt(300), rnd.nextInt(300), rnd.nextInt(300)));
                imagePanel.repaint();
            }
        });
        mainForm.getContentPane().add(imagePanel);
 
    }
 
    static class MyVcl extends JPanel {
        private ArrayList<Line> lines = new ArrayList<Line>();
 
        public void drawVcl(Line l) {
            lines.add(l);
        }
 
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            for (Line l : lines) {
                l.paint(g);
            }
        }
    }
 
    static class Line {
        public final int x1;
        public final int x2;
        public final int y1;
        public final int y2;
 
        public Line(int x1, int y1, int x2, int y2) {
            this.x1 = x1;
            this.x2 = x2;
            this.y1 = y1;
            this.y2 = y2;
        }
 
        public void paint(Graphics g) {
            g.drawLine(this.x1, this.y1, this.x2, this.y2);
        }
    }
 
    public static void main(String[] args) {
        new TenLines();
    }
 
}
И заметьте тут чистый ООП и если продолжить наворачивать, то можно всю возможную графику законтейнерить и добавить удобства как в VCL
Цитата Сообщение от Evg Посмотреть сообщение
разработчики VCL очень серьёзно потрудились для того, чтобы модель работы с графикой привести в нормальный человеческий вид, удобный для использования.
В том что они серьёзно потрудились я ничуть не сомневаюсь
2
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
24.01.2012, 15:45  [ТС]
У меня под линуксом оба теста не запускаются (а точнее, там ничего не рисуется). Наверное java какой-нибудь устаревшей версии (что само по себе интересно, потому что никаких сообщений об этом я не видел).

Но у обеих программ я вижу один и тот же дефект. Решая конкретную задачу оба втора всё свалили в одну большую кучу. Собственно, я насчёт этого пока ничего не просил, так что возьмём это за рабочую версию.

А теперь попробуйте растащить код программы на два класса. Первый класс - рассчётный. Т.е. он занимается исключительно обработкой данных и вычислением координат линий, требуемых к прорисовке. Второй класс - класс окна, который представляет собой холст для рисования и не более того. Первый класс посчитал данные и попросил второй класс нарисовать. И для наглядности лучше эти два класса растащить в разные файлы

Т.е. что-то типа того

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
public Main
{
  static void main (...)
  {
     MyFrame = new MyFrame(); // создали окошко
 
     // То, что здесь как sleep'ы - это условность. Допустим мы считываем данные с файла,
     // с устройства, с полей ввода - неважно. Важно лишь то, что данные для каждой
     // отдельной линии требуются в разное время
 
     // ----- Итерация 1
     
     // Посчитали координаты линии
     x1 = 10; y1 = 10; x2 = 100; y2 = 100;
     // попросили MyFrame нарисовать линию с координатами (x1, y1) - (x2, y2);
     ....
     // ожидаем получения следующей порции данных
     sleep (1);
 
     // ----- Итерация 2
 
     // Посчитали координаты линии
     x1 = 20; y1 = 10; x2 = 110; y2 = 100;
     // попросили MyFrame нарисовать линию с координатами (x1, y1) - (x2, y2);
     ....
     // ожидаем получения следующей порции данных
     sleep (1);
 
     // ----- Итерация 3
 
     ...
     // ну и так далее
  }
};
Java
1
2
3
4
class MyFrame
{
   ...
}
Как будет выглядеть взаимодействие между классами при таком построении архитектуры программы? И как будут вообще выглядеть эти классы?
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
24.01.2012, 16:05
Цитата Сообщение от Evg Посмотреть сообщение
У меня под линуксом оба теста не запускаются (а точнее, там ничего не рисуется). Наверное java какой-нибудь устаревшей версии (что само по себе интересно, потому что никаких сообщений об этом я не видел).
у меня тоже линукс и OpenJDK такчто ищите пули у себя.
Цитата Сообщение от Evg Посмотреть сообщение
А теперь попробуйте растащить код программы на два класса.
А вы не заметили у меня аж 3 класса и MyVcl какраз и является холстом для линий и помнит сколько вы их нарисовали??? И в чём проблема наследовать за ними и наращивать контейнеры для всех придуманных вами фигур?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.01.2012, 16:05
Помогаю со студенческими работами здесь

Не могу понять как работать с данным массивом
Добрый день форумчане! Имеется массив ...

длинная арифметика, не могу понять как с ней работать
необходимо написать программу которая могла бы найти остаток от деления, но проблема в том что числа могут быть до 10 в 100 степени. как...

Не могу понять как в Visual Studio (C#) работать с "ресурсами"
Начал программировать на C#, установил Visual Studio и встретил там такую графу как &quot;ресурсы&quot;.И у меня возник вопрос как с ними...

Перестал работать код. Не могу понять в чём причина!
Получил сайт в распоряжение, а на сайте ошибка в РНР. При чём изначально работало всё, но в один момент повисло и работать отказывается. Не...

Програма не хочет работать. не могу понять что не так (
В панели интерфейса предусмотреть возможность выбора одной из трех функций sin(x), x^2, exp(x) unit laba2; interface uses...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru