tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
13
ZUGRIFFE
471
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    TobyNick TobyNick ist offline Mitglied
    Registriert seit
    Apr 2009
    Beiträge
    15
    Hallo,
    ich habe ein Problem. Und zwar habe ich einen JButton in einem JPanel (panel1) mit NullLayout eingebunden. Jetzt geschieht etwas in dem Programm und dann soll der Button dort gelöscht werden (panel1.remove()) und in ein anderes JPanel (panel2) mit FlowLayout eingebunden werden (panel2.add()). Komischerweise wird der Button in panel2 an genau den gleichen Koordinaten eingebunden wie beim NullLayout und das FlowLayout wird irgendwie nicht benutzt. Woran kann das liegen? Wenn ich nach dem adden revalidate() oder doLayout() ausführe verschwindet der Button einfach ganz.

    Danke schon mal!
     

  2. #2
    SE Tutorials.de Gastzugang
    Das liegt daran das du für das NullLayout die Methode JComponent.setBounds() aufgerufen hast. Du musst erst die Bounds löschen bevor das FlowLayout greifen kann.
     

  3. #3
    TobyNick TobyNick ist offline Mitglied
    Registriert seit
    Apr 2009
    Beiträge
    15
    Ok stimmt, ich habe den Button mit setSize() und setLocation() verändert. Aber wie lösche ich die Bounds jetzt zurück? setBounds(0,0,0,0) funktioniert nicht.
     

  4. #4
    SE Tutorials.de Gastzugang
    1) Doppel-Posts , im Sinne von : gleicher Inhalt , sind hier unerwünscht.
    2) Warum machst du es dir so umständlich und fügst erst eine Component auf ein NullLayout hinzu wo du auf setBounds() angewiesen bist und willst diese dann später auf ein Panel verschieben welches ein LayoutManager besitzt und dir da die Bounds in die Query kommen. Einfacher wäre es doch wenn du das ganze entweder komplett auf einem Panel machen würdest *hier natürlich vorzugsweise das mit dem LayoutManager* oder du nimmst eine zweite Component.

    Wie man über setBounds() gemachte absolute Positions- und Größenangaben wieder "löscht" weis ich nicht ... ich bin nur davon ausgegangen das es möglich sein müsste.
     

  5. #5
    TobyNick TobyNick ist offline Mitglied
    Registriert seit
    Apr 2009
    Beiträge
    15
    Nun ja. Ich habe in dem Programm Würfel als Buttons (damit man sie anklicken kann) auf dem ersten Panel zufällig angeordnet. Jetzt kann man Würfel auswählen. Wenn man sie auswählt, sollen sie in dem einen Panel gelöscht werden und in ein anderes Panel eingefügt werden, allerdings sollen die in dem Panel geordnet sein.
    So als ob die Würfel in so einem Bereich gewürfelt worden sind (durcheinander / zufällige Anordnung) und man sich dann die Würfel rauspickt und sie vor sich legt, aber das macht man ja ordentlich / in einer Reihe...deswegen FlowLayout.
     

  6. #6
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist offline Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Hi,
    warum machst du es dann nicht so, da ein Würfel ein Objekt ist, dass du dieses Objekt einfach von dem einen Panel löst und in ein anderes setzt? Diese Würfel-Objekte werden dann (wie du es auch schon gemacht hast) über ein JPanel angezeigt. Und wenn du auf einen Würfel geklickt hast, dann wird das JPanel von dem Würfel-Objekt gelöscht und du zeigst das Würfel-Objekt auf der anderen Seite in einem neuen JPanel an.

    Gruß

    Fabio
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

  7. #7
    TobyNick TobyNick ist offline Mitglied
    Registriert seit
    Apr 2009
    Beiträge
    15
    Ich weiß nicht ob ich dich richtig verstehe, aber so mache ich das doch eigentlich. Ich lösche den Würfel von dem einen Panel mit NullLayout: panel1.remove(wuerfel); und füge es ins andere Panel mit FlowLayout ein: panel2.add(wuerfel);
    Oder wie meinst du das? Entschuldige, falls ich dich falsch verstanden habe.
     

  8. #8
    SE Tutorials.de Gastzugang
    Normalerweise sollte wenn du eine Component in einen Container mit LayoutManager addest von diesem die setBounds() Methode aufgerufen werden welche die von dir vorher gemacht Bounds überschreibt. Ich habe es zwar noch nicht getestet ... aber laut dem OOP-Konzept von Java und den Zusammenhängen in GUI-Strukturen sollte es eigentlich so sein. Aus irgend einem Grund wird jetzt aber genau das bei dir nicht getan.
    Es wäre interessant zu sehen WIE du den "Würfel" von Panel1 auf Panel2 überträgst *bitte den kompletten relevanten Code*. Vielleicht findet man darin ja einen Fehler. So ohne Source fällt mir jetzt auch keine Lösung mehr ein.
     

  9. #9
    TobyNick TobyNick ist offline Mitglied
    Registriert seit
    Apr 2009
    Beiträge
    15
    Ok dann poste ich mal den Code

    Code :
    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
    
    //Im ActionListener der Würfel-Buttons
     
    //...
     
    public void actionPerformed(ActionEvent e) {
            Wuerfel ausgewaehlt = (Wuerfel) e.getSource();
            
            panel1.entferneWuerfel(ausgewaehlt); //panel1 ist ein Objekt einer Klasse die von JPanel erbt, dass heißt es ist auch direkt das Panel, aus dem entfernt werden soll
            player.addWuerfel(ausgewaehlt); // player ist Spieler-Objekt
        }
     
     
    //Die Klasse von panel1, wo die Wuerfel anfangs drin sind (mit NullLayout)
     
    public class Wuerfelpott extends JPanel {
     
    ArrayList<Wuerfel> wuerfel;
     
    //...
     
    public void entferneWuerfel(Wuerfel w) {
            wuerfel.remove(w);
            this.remove(w);
            this.repaint();
        }
     
    }
     
    public class Spieler {
     
    ArrayList<Wuerfel> wuerfel;
    Ablage ablage; // Ablage erbt von JPanel und hat das FlowLayout, ablage ist halt das 2. Panel
     
    public void addWuerfel(Wuerfel w) {
            wuerfel.add(w);     
            ablage.add(w);
        }
    }

    Also alles nichts besonderes
     

  10. #10
    SE Tutorials.de Gastzugang
    Ja ... nicht besonderst gut vor allem. Mir fallen da selbst in diesem Stück Code einige Fehler auf.

    1) Nach dem der Würfel vom Würfelpott entfernt wurde reicht ein einfaches
    Code java:
    1
    
    this.repaint();
    nicht. Ersetze es mal durch
    Code java:
    1
    2
    
    this.validate();
    this.update(this.getGraphics());

    2) Analog gilt es natürlich auch für das Hinzufügen einer Component in ein Layout. Wenn du ein Layout veränderst MUSS IMMER validate() aufgerufen werden. also müsste die ganze Methode so aussehen
    Code java:
    1
    2
    3
    4
    5
    6
    7
    
    public void addWuerfel(Wuerfel w)
    {
        wuefel.add(w);
        ablage.add(w);
        ablage.validate();
        ablage.update(ablage.getGraphics());
    }

    Ich hoffe das hilft dir bei deinem Problem.

    Der Grund : Component.setBounds() wird erst durch das validate() aufgerufen , aber ein simples add() reicht nicht.
     

  11. #11
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist offline Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Hi TobyNick,
    nein, du hast mich damals ein wenig falsch verstanden. Ich habe dir hier mal einen kleinen Beispiel-Code geschrieben, um dir das mal ein bischen besser veranschaulichen zu können.

    Die Klasse Pott fügst du zu deinem JFrame hinzu. Das Pott-Objekt übernimmt die Anzeige der einzelnen Würfel. D.h. der aktuelle Spieler wird über die Methode setActualPlayer(Player) gesetzt und danach wird die Methode update() aufgerufen. Die Methode update() wird immer dann aufgerufen, wenn der Spieler z.B. neu gewürfelt hat oder bei sonstigen Änderungen.
    Code 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
    
        public class Pott extends JPanel
        {
            private Player player;
            private final List<JPanel> pottPanels;
            
            /**
             * 
             */
            public Pott() {
                this.pottPanels = new LinkedList<JPanel>();
                
                // Je nachdem, wieviele JPanels du zum Würfelzeichnen brauchst
                // ...
                JPanel panel1 = new JPanel();
                pottPanels.add(panel1);
                add(panel1);
                JPanel panel2 = new JPanel();
                pottPanels.add(panel2);
                add(panel2);
                JPanel panel3 = new JPanel();
                pottPanels.add(panel3);
                add(panel3);
                JPanel panel4 = new JPanel();
                pottPanels.add(panel4);
                add(panel4);
                JPanel panel5 = new JPanel();
                pottPanels.add(panel5);
                add(panel5);
                // Den Panels müsstest du auch noch einen MouseListener für ein Click-Event mit übergeben.
                // Oder du nimmst statt JPanel's einfach JButton's.
            }
            
            public void setActualPlayer(Player player) {
                this.player = player;
            }
            
            public void update() {
                List<Cube> notSelectedCubes = player.getNotSelectedCubes();
                
                for (int i = 0; i < pottPanels.size(); i++) {
                    JPanel panel = pottPanels.get(i);
                    
                    if(i < notSelectedCubes.size()) {
                        Cube cube = notSelectedCubes.get(i);
                        cube.draw((Graphics2D) panel.getGraphics());
                    } else {
                        panel.validate();
                        panel.update(panel.getGraphics());
                    }
                }
            }
        }

    Die Klasse Player enthält jetzt unsere Würfelobjekte. Da nur der Spieler (nach OOP) weiß welche Würfel er "selektiert" hat und welche nicht, werden diese beiden Methoden - getNotSelectedCubes() und getSelectedCubes() - dem Player-Objekt hinzugefügt. Zudem bekommt das Player-Objekt noch die Methode dice() zum würfeln. Wird diese Methode aufgerufen, werden alle Würfel (welche nicht selektiert sind) gewürfelt.
    Code 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
    
        public class Player
        {
            private final List<Cube> cubes;
            
            public Player() {
                this.cubes = new ArrayList<Cube>();
                cubes.add(new Cube());
                cubes.add(new Cube());
                cubes.add(new Cube());
                cubes.add(new Cube());
                cubes.add(new Cube());
                // Je nachdem, wieviele Würfel du haben willst
                // ...
            }
            
            public void dice() {
                for (int i = 0; i < cubes.size(); i++) {
                    Cube cube = cubes.get(i);
                    if(!cube.isSelected()) {
                        cube.dice();
                    }
                }
            }
            
            public List<Cube> getNotSelectedCubes() {
                List<Cube> selectedCubes = new ArrayList<Cube>();
                for (int i = 0; i < cubes.size(); i++) {
                    Cube cube = cubes.get(i);
                    if(!cube.isSelected()) {
                        selectedCubes.add(cube);
                    }
                }
                return selectedCubes;
            }
            
            public List<Cube> getSelectedCubes() {
                List<Cube> selectedCubes = new ArrayList<Cube>();
                for (int i = 0; i < cubes.size(); i++) {
                    Cube cube = cubes.get(i);
                    if(cube.isSelected()) {
                        selectedCubes.add(cube);
                    }
                }
                return selectedCubes;
            }
        }

    Die Klasse Cube ist nun also unser Würfel-Objekt. Von diesem Objekt können wir nun erfragen, ob es selektiert wurde und welche Nummer es gerade zeigt. Zudem (fürs zeichnen) können wir noch die x-/y-Koordinaten einsehen und ändern.
    Code 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
    
        public class Cube
        {
            private int shownValue;
            private boolean selected;
            private int x = 0;
            private int y = 0;
            
            public void dice() {
                this.shownValue = (int) (Math.random()*6+1);
            }
            
            public int getShownValue() {
                return shownValue;
            }
            
            public void setSelected(boolean isSelected) {
                this.selected = isSelected;
            }
            
            public boolean isSelected() {
                return selected;
            }
     
            public void setX(int x) {
                this.x = x;
            }
     
            public int getX() {
                return x;
            }
     
            public void setY(int y) {
                this.y = y;
            }
     
            public int getY() {
                return y;
            }
            
            public void draw(Graphics2D g) {
                g.drawRect(x, y, 40, 40);
                g.drawString(String.valueOf(shownValue), x+19, y+18); // Oder durch selber gezeichnete Punkte ersezten
            }
        }

    Ich hoffe ich konnte dir meinen Gedankengang ein wenig veranschaulichen mit diesen Codeausschnitten. Bitte bedenke, dass ich diesen Code vorher nicht ausprobiert habe und ich daher nicht garantieren kann, dass er zu 100% einsatzbereit/lauffähig (sprich: Fehler können vorhanden sein) ist.
    Du wirst wahrscheinlich nichts desto drotz die ein oder anderen Änderungen vornehmen müssen. Diese Arbeit wird dir wohl nicht erspart bleiben.

    Falls du noch Fragen haben solltest, nur zu.

    Gruß

    Fabio
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

  12. #12
    TobyNick TobyNick ist offline Mitglied
    Registriert seit
    Apr 2009
    Beiträge
    15
    @Spikee: Danke erstmal. Ich wusste nicht, dass repaint() nicht ausreicht. aber wofür gibt es dann repaint()? auf jeden fall, wenn ich validate benutzte oder auch revalidate, dann werden die würfel gar nicht mehr angezeigt. nicht mal mehr an den falschen koordinaten. einfach weg.
    ich verstehe es einfach nicht. hmm...ich kann verstehen wenn ihr das thema schon satt habt
     

  13. #13
    TobyNick TobyNick ist offline Mitglied
    Registriert seit
    Apr 2009
    Beiträge
    15
    @Fabio: Danke für die Mühe, aber ich verstehe noch nicht, wie mir das bei meinem Problem helfen soll. Es geht hier ums NullLayout und FlowLayout und darum, wie die Komponenten angezeigt werden, wenn sie von einem Panel mit dem einen Layout in ein anderes Panel mit dem anderen Layout verschoben werden.
    Du hast dir sehr viel Mühe gemacht um zu zeigen, wie man die Würfel verwaltet, aber das ist kein Problem. Das habe ich alles und das funktioniert.
     

  14. #14
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist offline Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Ich wollte dir damit nur zeigen, dass du die Würfel auch von den JPanel's trennen kannst. Dadurch würdest du dir das verschieben von Komponenten durch die verschiedenen Layouts sparen.
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

Ähnliche Themen

  1. JPanel im FlowLayout: zeigt JScrollPane nicht an
    Von Sacrent im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 0
    Letzter Beitrag: 28.05.10, 14:26
  2. Layout im JPanel
    Von Jellysheep im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 5
    Letzter Beitrag: 29.12.09, 18:01
  3. Höhe ist null bei JPanel im GridBagLayout
    Von cubeless im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 2
    Letzter Beitrag: 22.06.08, 17:41
  4. JPanel verschieben
    Von ChMaster im Forum Swing, Java2D/3D, SWT, JFace
    Antworten: 3
    Letzter Beitrag: 26.04.08, 12:41
  5. Antworten: 7
    Letzter Beitrag: 16.05.07, 17:03