2015-10-07 2 views
0

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

private static void createAndShowGui() { 
    SimpleDraw mainPanel = new SimpleDraw(); 
    MenuBar.createMenuBar(); 
    JLabel label = new JLabel(); 
    label.setText("Drawing prototype 0.0.1"); 
    // label.setHorizontalTextPosition(JLabel.NORTH); 
    label.setFont(new Font("Serif", Font.BOLD, 20)); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().add(mainPanel); 
    frame.pack(); 
    frame.setLocationByPlatform(true); 
    frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.PAGE_AXIS)); 
    frame.setVisible(true); 
    frame.setJMenuBar(MenuBar.getMenuBar()); 
    frame.setBackground(Color.WHITE); 
    frame.add(label); 

Блок кода выше настраивает JFrame (окно)

@Override 
    public void mouseDragged(MouseEvent e) 
    { 
    // These console outputs are just so that I know what is happening 
     System.out.println("Event: MOUSE_DRAG"); 
     System.out.println(e.getX()); 
     System.out.println(e.getY()); 
     System.out.println(e.getComponent()); 
     System.out.println(e.getWhen()); 
     System.out.println(e.getButton()); 
     MOUSE_X = e.getX() - 5; //-5 so that the cursor represents the center of the square, not the top left corner. 
     MOUSE_Y = e.getY() - 5; //^ 
     rect = new Rectangle(MOUSE_X, MOUSE_Y, 10, 10); //This doesn't ever come into action. 
     repaint(); 

    } 

Код выше довольно многое просто устанавливает переменные MOUSE_X и MOUSE_Y и repaint(); метод

@Override 
    protected void paintComponent(Graphics g) { 

    Graphics2D g2 = (Graphics2D) g; 
    if (rect != null) { 

     if (!colorChoice.equals("Default")) 
     { 
      g2.setColor(Color.BLACK); 
     } 

     switch(colorChoice) { 

     case "GRAY": 
      g2.setColor(Color.GRAY); 
      break; 
     case "CYAN": 
      g2.setColor(Color.CYAN); 
      break; 
     case "BLUE": 
      g2.setColor(Color.BLUE); 
      break; 
     case "RED": 
      g2.setColor(Color.RED); 
      break; 
     case "PINK": 
      g2.setColor(Color.PINK); 
      break; 
     case "YELLOW": 
      g2.setColor(Color.YELLOW); 
      break; 
     case "GREEN": 
      g2.setColor(Color.GREEN); 
      break; 
     case "PURPLE": 
      g2.setColor(Color.MAGENTA); 
      break; 
     case "RESET": 
      g2.setColor(Color.WHITE); 
     case "WHITE": 
      g2.setColor(Color.WHITE); 

     } 





     g2.fillRect(MOUSE_X, MOUSE_Y, 15, 15); 

     if (colorChoice.equals("RESET")) 
     resetColorOnCursor(); 

     } 
    } 

    public static void clearBoard() 
    { 
    tempColor = colorChoice; 
    setColorChoice("RESET"); 
    frame.repaint(); 




    } 


    public static void resetColorOnCursor() 
    { 
    setColorChoice(tempColor); 
    } 

Это то, что я случайно встретил. То, что я пытался сделать, когда я это обнаружил, в основном заключалось в том, что квадрат следует за вашим курсором всякий раз, когда вы перемещаете мышь. Но я забыл ввести код paintComponent(g);, который превращает эту программу в ту вещь, которую я изначально планировал. Нижние части этого - это, по сути, то, как я очистил доску. Я на 100% уверен, что это не правильный способ очистить/сбросить фрейм, как это, но я не мог найти другого пути. Если у кого-то есть какие-либо советы или более эффективные методы для этого, я бы очень благодарен. Благодаря! : D

+0

Нет, вы должны называть 'super.paintComponent', прежде чем рисовать текущее состояние компонента. В противном случае вы могли бы получить всевозможные беспорядки, появляющиеся на вашем компоненте, например, другие призрачные образы вашего компонента, например – MadProgrammer

+0

Чтобы «покоиться» в представлении, оставьте значения, которые определяют, как и что окрашивают, до вызова 'repaint' – MadProgrammer

+0

Вызов super.paintComponent(); делает подвижный квадрат. Это то, чего я НЕ хочу. Я бы не стал более привлекательным. Вызов super.paintComponent(); Вернет эту программу обратно в скучное приложение «подвижный квадрат» –

ответ

6

Вы используете текущий подход, в основном, нарушая требования цепочки красок, не вызывая super.paintComponent. Метод paintComponent выполняет набор операций, которые вы не берете на себя, и которые могут привести к очень странным артефактам краски, которые трудно реплицировать последовательно.

Graphics - общий ресурс, поэтому контекст Graphics, который использовался для рисования какого-либо другого элемента управления, будет таким же, который используется для рисования вашего компонента, если только вы не «очищаете» контекст перед рукой, контекст останется (вот почему вы, по-видимому, сейчас работаете в коде).

Вместо этого, вы должны использовать MouseListener, чтобы определить точку привязки, которая представляет собой точку, в которой мышь была нажата, а затем использовать MouseMotionListener, чтобы определить степень выделенной области, к примеру ...

Paint Selection

import java.awt.AlphaComposite; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class SelectExample { 

    public static void main(String[] args) { 
     new SelectExample(); 
    } 

    public SelectExample() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Rectangle selection; 

     public TestPane() { 
      MouseAdapter ma = new MouseAdapter() { 

       private Point clickPoint; 

       @Override 
       public void mousePressed(MouseEvent e) { 
        clickPoint = e.getPoint(); 
        selection = null; 
       } 

       @Override 
       public void mouseDragged(MouseEvent e) { 
        Point dragPoint = e.getPoint(); 
        int x = Math.min(clickPoint.x, dragPoint.x); 
        int y = Math.min(clickPoint.y, dragPoint.y); 

        int width = Math.max(clickPoint.x, dragPoint.x) - x; 
        int height = Math.max(clickPoint.y, dragPoint.y) - y; 

        if (selection == null) { 
         selection = new Rectangle(x, y, width, height); 
        } else { 
         selection.setBounds(x, y, width, height); 
        } 
        repaint(); 
       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 
        selection = null; 
        repaint(); 
       } 

      }; 

      addMouseListener(ma); 
      addMouseMotionListener(ma); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (selection != null) { 
       g.setColor(UIManager.getColor("List.selectionBackground")); 
       Graphics2D g2d = (Graphics2D) g.create(); 
       g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); 
       g2d.fill(selection); 
       g2d.dispose(); 
       g2d = (Graphics2D) g.create(); 
       g2d.draw(selection); 
       g2d.dispose(); 
      } 
     } 

    } 

} 

Просто, чтобы выделить этот вопрос вы будете столкнуться, если вы будете продолжать нарушать требования методы paintComponent, это то, что происходит, когда я не называю super.paintComponent

Violated

я просто добавил два JButton «S к JFrame (поэтому не даже непосредственно на панель). paintComponent выполняет ряд важных заданий, которые вы пренебрегли выполнением, что вызовет больше проблем и проблем.

Свободный пример формы линии ...

Свободная форма линии на самом деле иллюзия, это серия (маленьких) линий, нарисованных между серией точек, причина этого заключается в том, потому что MouseListener не будет сообщите каждую позицию мыши, в которой он перемещается, в зависимости от скорости перемещения мыши, вы можете получить много обратных вызовов или несколько.

Таким образом, вместо того, чтобы рисовать просто рисовать точки, мы храним точки в List и рисовать линии между ними, к примеру ...

FreeForm

import java.awt.AlphaComposite; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class FreeFormLines { 

    public static void main(String[] args) { 
     new FreeFormLines(); 
    } 

    public FreeFormLines() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private List<List<Point>> points; 

     public TestPane() { 
      points = new ArrayList<>(25); 
      MouseAdapter ma = new MouseAdapter() { 

       private List<Point> currentPath; 

       @Override 
       public void mousePressed(MouseEvent e) { 
        currentPath = new ArrayList<>(25); 
        currentPath.add(e.getPoint()); 

        points.add(currentPath); 
       } 

       @Override 
       public void mouseDragged(MouseEvent e) { 
        Point dragPoint = e.getPoint(); 
        currentPath.add(dragPoint); 
        repaint(); 
       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 
        currentPath = null; 
       } 

      }; 

      addMouseListener(ma); 
      addMouseMotionListener(ma); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      for (List<Point> path : points) { 
       Point from = null; 
       for (Point p : path) { 
        if (from != null) { 
         g2d.drawLine(from.x, from.y, p.x, p.y); 
        } 
        from = p; 
       } 
      } 
      g2d.dispose(); 
     } 

    } 

} 
+0

. Очевидно, что вы более опытные, чем я, но здесь, очевидно, также возникает ошибка связи. Программа, которую я пытаюсь создать, в основном представляет собой программное обеспечение для рисования. EX: Перетащите мышь и создайте строку, а не поле. –

+0

Итак, вместо создания 'Rectangle', создайте' Line2D', как показано [здесь] (http://stackoverflow.com/questions/32979814/how-can-i-set-the-stroke-color-at- runtime-in-java/32981345 # 32981345) (и добавьте их в какой-то «Список», чтобы вы могли повторно рисовать их, когда вам нужно) – MadProgrammer

+0

Хорошо, я понимаю, что вы говорите, но используя ваш метод, как бы вы создаете линии свободной формы? (кривые) –