haarig Geschrieben 9. Mai 2007 Teilen Geschrieben 9. Mai 2007 Hallo Java-Freunde, ich habe hier eine Java Aufgabe zu bewältigen, die eigentlich auch ziemlich fertig ist. Ein Problem habe ich aber noch. Erst mal zur Beschreibung. Ich soll ein Programm schreiben, was sich bewegende Objekte in einem Fenster darstellt. Dabei soll man einige Optionen mit JComboBoxes einstellen können. So weit so gut. Das einzige was mich noch stört ist, dass die ausgefahrenen JComboBoxes von den sich bewegenden Objekten übermalt werden. Kann man das verhindern? Schauts euch einfach mal an. import javax.swing.*; import java.awt.*; import java.awt.event.*; public class FunnyObject extends JFrame implements ActionListener, Runnable{ Thread t = new Thread(this); Node geoObjects; String[] objects = { "oval", "rectangle"}; String[] arts = { "line", "fill"}; String[] colors = { "black", "blue", "cyan", "dark grey", "grey", "light gray", "green", "magenta", "orange", "pink", "red", "white", "yellow" }; Color[] allColors = { Color.black, Color.blue, Color.cyan, Color.darkGray, Color.gray, Color.lightGray, Color.green, Color.magenta, Color.orange, Color.pink, Color.red, Color.white, Color.yellow }; JComboBox cObject = new JComboBox(objects); JComboBox cArt = new JComboBox(arts); JComboBox cColor = new JComboBox(colors); JButton bCreate = new JButton("New Object"); JPanel objArea = new JPanel(); JPanel operations = new JPanel(); FunnyObject(String s){ super(s); getContentPane().setLayout(new FlowLayout()); operations.setLayout(new FlowLayout()); operations.add(cObject); operations.add(cArt); operations.add(cColor); operations.add(bCreate); cObject.setPreferredSize(new Dimension(115,25)); cArt.setPreferredSize(new Dimension(115,25)); cColor.setPreferredSize(new Dimension(115,25)); getContentPane().add(operations); getContentPane().add(objArea); bCreate.addActionListener(this); bCreate.setActionCommand("new"); objArea.setBackground(Color.WHITE); objArea.setPreferredSize(new Dimension(450,450)); setLocation(100, 100); setSize(500, 550); this.setResizable(false); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); t.start(); } public void run(){ while(true){ for(Node a=geoObjects; a!=null; a=a.next){ (a.data).moveMe(); } this.draw(); try{Thread.sleep(10);} catch(InterruptedException ex){} } } public void actionPerformed(ActionEvent e) { addObject(); } public void addObject(){ Drawable newObject = createObject(); if(geoObjects==null) geoObjects = new Node(null, createObject()); else{ Node a=geoObjects; for(; a.next!=null; a=a.next); a.next = new Node(null, createObject()); } } void draw(){ for(Node a=geoObjects; a!=null; a=a.next){ a.data.zeichneMich(); } } Drawable createObject(){ boolean fill = cArt.getSelectedIndex()==0?false:true; if(cObject.getSelectedItem().equals("oval")){ Point a = new Point((int)(Math.random()*objArea.getWidth()*0.8+20),(int)(Math.random()*objArea.getHeight()*0.8+20)); return new Circle(a, 20, fill, allColors[cColor.getSelectedIndex()], objArea); } if(cObject.getSelectedItem().equals("rectangle")){ Point a = new Point((int)(Math.random()*objArea.getWidth()*0.8+25),(int)(Math.random()*objArea.getHeight()*0.8+25)); Point b = new Point(a.x+25, a.y+25); return new Rectangle(a, b, fill, allColors[cColor.getSelectedIndex()], objArea); } else return null; } public static void main(String[] args){ new FunnyObject("Funny Objects"); } } class Rectangle implements Drawable { private Point links_oben, rechts_unten; Color color; boolean fill; Graphics g; int dirR; int dirL; JPanel mp; Rectangle(Point a, Point b, boolean fill, Color color, JPanel mp) { links_oben = new Point(Math.min(a.x, b.x), Math.min(a.y, b.y)); rechts_unten = new Point(Math.max(a.x, b.x), Math.max(a.y, b.y)); this.fill = fill; this.color = color; this.mp = mp; this.g = mp.getGraphics(); dirR=1; dirL=1; } public void zeichneMich() { g.setColor(color); if (fill) { g.fillRect(links_oben.x, links_oben.y, rechts_unten.x-links_oben.x, rechts_unten.y-links_oben.y); g.setColor(Color.black); g.drawRect(links_oben.x, links_oben.y, rechts_unten.x-links_oben.x, rechts_unten.y-links_oben.y); } else{ g.drawRect(links_oben.x, links_oben.y, rechts_unten.x-links_oben.x, rechts_unten.y-links_oben.y); } } boolean isOut(){ if( rechts_unten.y>mp.getHeight() || rechts_unten.x>mp.getWidth() || links_oben.x<0 || links_oben.y<0) return true; else return false; } public void moveMe(){ g.setColor(Color.white); g.fillRect(links_oben.x-1, links_oben.y-1,rechts_unten.x-links_oben.x+2,rechts_unten.y-links_oben.y+2 ); links_oben.translate(dirR*1,dirL*1); rechts_unten.translate(dirR*1, dirL*1); if(isOut()){ dirR = dirR* (-1); dirL = dirL* (-1); } } } class Circle implements Drawable { private Point upperLeft; private int radius; private boolean fill; private Color color; Graphics g; int dirR; int dirL; JPanel mp; Circle(Point upperLeft, int radius, boolean fill, Color color, JPanel mp) { this.upperLeft = upperLeft; this.radius = radius; this.fill = fill; this.color = color; this.mp = mp; this.g = mp.getGraphics(); dirR=1; dirL=1; } public void zeichneMich() { g.setColor(color); if(fill){ g.fillOval(upperLeft.x, upperLeft.y, radius*2, radius*2); } else{ g.drawOval(upperLeft.x, upperLeft.y, radius*2, radius*2); } } public void moveMe(){ g.setColor(Color.white); g.fillOval(upperLeft.x-1, upperLeft.y-1, radius*2+3, radius*2+3); upperLeft.translate(dirR*1,dirL*1); if(isOut()){ dirR = dirR* (-1); dirL = dirL* (-1); } } boolean isOut(){ if( (upperLeft.y+radius*2)>mp.getHeight() || (upperLeft.x+radius*2)>mp.getWidth() || upperLeft.x<0 || upperLeft.y<0) return true; else return false; } } interface Drawable{ void zeichneMich(); void moveMe(); // Ok, das gehört hier nicht wirklich rein, aber es passt halt grad } class Node { // Node wird zum Speichern der Objekte benutzt Node next; Drawable data; Node(Node next, Drawable data) { this.next = next; this.data = data; } } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bigredeyes Geschrieben 10. Mai 2007 Teilen Geschrieben 10. Mai 2007 erster verbesserungsvorschlag: hole dir beim zeichnen die "graphics" jedes mal neu. @override paint(Graphics g){ //funktion zum malen aufrufen for(Node a=geoObjects; a!=null; a=a.next){ a.data.zeichneMich(g); } } wenn du jetzt ein repaint() auslöst, kommt die aktuelle graphics in die paint-methode. dann lass sich die objekte zeichnen. mit aktuller graphic. ändert das was am verhalten? bigredeyes Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
haarig Geschrieben 10. Mai 2007 Autor Teilen Geschrieben 10. Mai 2007 Ja, danke. Anscheinend wurde die getGraphics() gar nicht so gemocht. Wenn man paint() überschreibt gibt es keine Probleme. Komisch :confused: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
bigredeyes Geschrieben 11. Mai 2007 Teilen Geschrieben 11. Mai 2007 Ja, danke. Anscheinend wurde die getGraphics() gar nicht so gemocht. Komisch :confused: man "merkt" sich den GC nicht. das ist nicht "komisch", sonder sinnig! du sagts deinem frame repaint() und er stößt bei allen die paint-methode an und gibt den richtigen (!) GC mit. jetzt durfte auch das phänomen weg sein, dass man mit anderen fenstern im deinem java fenster "radieren" kann bzw, nach minimize der inhalt wieder richtig dargestellt wird. lektüre (habs selber aber noch nicht angeschaut, nur link in der api gefunden): Painting in AWT and Swing bigredeyes Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.