2017-01-17 4 views
0

Ich möchte eine Anwendung programmieren, mit der Sie Kreise mit einem Mausklick auf die linke Seite eines JFrame zeichnen können, und alle Punkte werden auf die rechte Seite "gespiegelt". Das erste Problem, dem ich begegnete, war, dass, wenn ich versuche, diese Zeichenmechanik in meinem Rahmen zu implementieren, keine Kreise erscheinen.Zeichnen auf einer Seite eines 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); 

    } 
} 

Es funktioniert (auf den gesamten Rahmen), wenn ich container.add(new DrawCircle) verwenden, aber wenn ich Einschränkungen hinzufügen möchten, es funktioniert nicht. Hier

ist der Kreis Klasse:

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

Ein ähnliches Beispiel ist untersucht [hier] (http://stackoverflow.com/q/2244157/230513). – trashgod

+0

Warum haben Sie den 'DrawCircle' Code gelöscht? – Frakcool

Antwort

1

Lassen Sie sich über Ihre Probleme gehen:

Das erste Problem, das ich gestoßen war, dass wenn ich versuche, diesen Einzug Mechaniker in meinem Rahmen zu implementieren, keine Kreise erscheinen. Diese

ist, weil Sie vergessen haben, JPanel#revalidate() zu anrufen und JPanel#repaint(), wenn Sie irgendwo klicken Sie in der DrawCircle Klasse.

So konnten Sie Ihre mousePressed() Methode ändern:

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

Bitte beachte, dass ich mich verändert auch die e.getX() und e.getY() Anrufe, weil sie an den falschen Stellen waren (es sei denn Sie sie auf diese Weise wollen).

Das wird Ihren Kreisen machen erscheinen, aber Ihr DrawCircle wirklich dünn ist (Ich habe die Höhe Ihres JFrame-200 für dieses Bild, sonst wäre es wirklich groß sein):

enter image description here

Der rote Teil ist Ihr DrawCircle Panel.

dies beheben Sie seine getPreferredSize() Methode außer Kraft setzen müssen:

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

Das wird Ihre JPanel machen die Hälfte der Größe zurückzukehren, width und height als Parameter an den Konstruktor übergeben wurden, und Ihre Klasse DrawCircle sollte jetzt wie folgt aussehen:

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) { 
    } 
} 

Und würde die Ausgabe so etwas wie dieses:

enter image description here

Es funktioniert (auf den gesamten Rahmen), wenn ich container.add verwenden (neue DrawCircle)

Das ist, weil standardmäßig BorderLayout Orte standardmäßig die Elemente auf der CENTER Region, und wenn Sie haben nichts anderes im Rest der Orientierungen (NORTH, SOUTH, usw.) es wird den ganzen Raum einnehmen.

Nun wollen wir auch weiterhin mit, wie Ihr Problem zu lösen:

Ich habe auch einige Änderungen an der Application Klasse (die in meinem Fall habe ich zu CustomPaintingInHalfFrame umbenannt):

Diese Veränderungen waren:

  • Erstellen Sie endgültige Konstanten für die Attribute WIDTH und HEIGHT.
  • Entfernen von unnötigen JPanel mit BorderLayout Layout, wie JFrame hat bereits dieses Layout standardmäßig, habe ich einfach unsere DrawClass hinzugefügt.
  • Zeichnung einer Grenze für die DrawCircle Panel (wie Sie nicht wollen, eine Teilung zwischen beiden (links und rechts) Teile Ihrer JFrame wie in Ihrem previous question angegeben können Sie es einfach entfernen (ich empfehle Ihnen, es dort während zu verlassen Sie testen damit Sie wissen, wo linke Platte endet und rechte Tafel beginnt.
  • WIDTH/2 und HEIGHT als Parameter Passing für DrawCircle Konstruktor, so kann es die richtige Dimension zurückzukehren.

so sollte unsere Klasse nun aussehen so:

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); 

    } 
} 

Weitere Tipps

  1. Ich empfehle Ihnen, Ihre DrawCircle-Circle oder so etwas zu benennen. Als convention sollte Klassen Namen Substantive beispiels

  2. Rename gui() Methode createGui() sein, denn als Klassen-Name, sollte Methode Namen Verben

Verwandte Themen