2017-01-17 2 views
0

Я хочу запрограммировать приложение, которое позволяет нарисовать круги с помощью мыши, щелкнув левой стороной от JFrame, и все точки получаются «зеркальными» с правой стороны. Первая проблема, с которой я столкнулся, заключалась в том, что когда я пытаюсь реализовать этот механизм рисования в моем кадре, никаких кругов не появляется.Нарисуйте одну сторону JPanel

public class Application{ 
    int x,y; 
    private JPanel container; 

    public static void main(String[] args) 
    { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     new Application().gui(); 
     } 
    }); 
    } 

    public void gui() 
    { 
    int height = 250; 
    int width = 700; 
    JFrame jframe = new JFrame(); 
    container = new JPanel(); 
    container.setLayout(new BorderLayout()); 

    container.add(new DrawCircle(), BorderLayout.WEST); 
    container.setVisible(true); 
    jframe.add(container); 
    //jframe.add(new DrawCircle()); 

    jframe.setSize(500,700); 
    jframe.setVisible(true); 
    jframe.setTitle("Title"); 
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    jframe.setResizable(false); 

    } 
} 

Он работает (по всему кадру), когда я использую container.add(new DrawCircle), но если я хочу, чтобы добавить ограничения, это не делает.

Вот класс круг:

public class DrawCircle extends JPanel implements MouseListener 
{ 
    ArrayList<Point> p = new ArrayList<Point>(); 

    public DrawCircle() 
    { 
    addMouseListener(this); 
    } 

    public void paintComponent(Graphics g) 
    { 
    super.paintComponent(g); 
    for(Point point : p) 
    { 
     g.fillOval(point.x,point.y,30,30);  
    } 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
    // TODO Auto-generated method stub 
    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
    // TODO Auto-generated method stub 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
    p.add(new Point(e.getY(), e.getX())); 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
    } 

    @Override 
    public void mouseMoved(MouseEvent arg0) { 
    } 
} 
+1

Связанный примером является [здесь] (http://stackoverflow.com/q/2244157/230513). – trashgod

+0

Почему вы удалили код DrawCircle? – Frakcool

ответ

1

Поедем через ваши проблемы:

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

Это потому, что вы забыли позвонить JPanel#revalidate() и JPanel#repaint() всякий раз, когда вы щелкаете где-нибудь в DrawCircle классе.

Таким образом, вы можете изменить свой mousePressed() метод к:

@Override 
public void mousePressed(MouseEvent e) { 
    p.add(new Point(e.getX(), e.getY())); 
    revalidate(); 
    repaint(); 
} 

Обратите внимание, что я также изменил e.getX() и e.getY() звонки, потому что они были на неправильных местах (если вы не хотите их таким образом).

Это сделает ваши круги появляются, но, ваш DrawCircle действительно тонкий (я изменил высоту вашего JFrame 200 для этого изображения, в противном случае было бы очень высокий):

enter image description here

Красная часть - ваша панель DrawCircle.

Чтобы это исправить, необходимо переопределить его getPreferredSize() метод:

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

Это сделает вашу JPanel вернуть половину размера, width и height были переданы в качестве параметров в конструкторе, и ваш класс DrawCircle теперь должен выглядеть следующим образом:

class DrawCircle extends JPanel implements MouseListener { 
    ArrayList<Point> p = new ArrayList<Point>(); 

    int width = 0; 
    int height = 0; 

    public DrawCircle(int width, int height) { 
     this.width = width; 
     this.height = height; 
     addMouseListener(this); 
    } 

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

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     for (Point point : p) { 
      g.fillOval(point.x, point.y, 30, 30); 
     } 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     p.add(new Point(e.getX(), e.getY())); 
     revalidate(); 
     repaint(); 
    } 

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

И выход будет что-то вроде этого:

enter image description here

Он работает (по всему кадру), когда я использую container.add (новый DrawCircle)

Это потому, что по умолчанию BorderLayout места по умолчанию элементы на CENTER области, и если у вас нет ничего другого в остальных направлениях (NORTH, SOUTH и т. д.), это займет все пространство.

Теперь давайте продолжим с тем, как решить вашу проблему:

Я также сделал некоторые изменения в Application класса (в моем случае я переименовал в CustomPaintingInHalfFrame):

Эти изменения были:

  • Создать окончательные константы для атрибутов WIDTH и HEIGHT.
  • Удаление ненужного JPanel с BorderLayout макет, так как JFrame уже имеет этот макет по умолчанию, я просто добавил наш DrawClass к нему.
  • Рисование границы для панели DrawCircle (так как вы не хотите разделять между левой и правой частями вашего JFrame, как указано в вашем previous question, вы можете просто удалить его (я рекомендую вам оставить его там, пока вы проверяете, так что вы знаете, где левая панель заканчивается и начинается правая панель.
  • Передача WIDTH/2 и HEIGHT в качестве параметров для DrawCircle конструктора, так что он может вернуть правильный Dimension.

Итак, наш класс должен выглядеть например:

public class CustomPaintingInHalfFrame { 
    int x, y; 
    public static final int WIDTH = 500; 
    public static final int HEIGHT = 200; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new CustomPaintingInHalfFrame().gui(); 
      } 
     }); 
    } 

    @SuppressWarnings("serial") 
    public void gui() { 
     JFrame jframe = new JFrame("Title"); 

     DrawCircle dc = new DrawCircle(WIDTH/2, HEIGHT); 

     dc.setBorder(BorderFactory.createLineBorder(Color.RED)); 

     jframe.add(dc, BorderLayout.WEST); 

     jframe.setSize(WIDTH, HEIGHT); 
     jframe.setVisible(true); 
     jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jframe.setResizable(false); 

    } 
} 

Дополнительные советы

  1. Я рекомендую вам переименовать ваш DrawCircle в Circle или что-то в этом роде. В качестве convention, классов имен должны быть существительных

  2. Переименовать gui() метод createGui(), например, потому что, как имена классов, метод имена должны быть глаголов

Смежные вопросы