Swing JLabels entfernen und neue einfügen

C

CMGbR

Gast
Hallo zusammen,

ich arbeite gerade für mein Studium an der grafischen Oberfläche für Schiffe-Versenken.

Genauer gesagt an den Schiffen selbst. Ich habe dafür einen neue Klasse Ship geschrieben, die von JPanel erbt.
Man übergibt dem Konstuktor die Größe des Schiffs (Anzahl der Felder), Variation (es gibt 3 verschiedene grafikvariationen), Feldgröße und Richtung (true = vertikal)...

Den Code für die Ship-Klasse habe ich der Übersicht halber ganz unten angehängt.

Der Konstruktor initialisiert nur die Variablen, setzt die Hintergrundfarbe und ruft dann buildShipGraphics() auf, welche dann die Größe und das Layout festlegt und dann addTile aufruft.
AddTile holt sich die Grafiken für die Schiffe und fügt die JLabels mit den entsprechenden Icons ein. Jedes Schiff besteht aus einem Anfangsstück, beliebig vielen Mittelstücken und einem Endstück.

Ich kann in meinem Frame problemlos ein neues Schiff anlegen:

Java:
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        newship = new ship(10,1,30,true);
        newship.setLocation(0,0);
        add(newship);
        newship.setVisible(true);
        pack();
    }

Das funktioniert sowohl vertikal als auch horizontal und in jeder Größe.
Dann habe ich eine weitere Methode zum Schiff hinzugefügt: rotateShip();
rotateShip soll alle Tiles (also die Labels) löschen, den Wert von direction ändern und dann wieder buildShipGraphics() aufrufen.

Das funktioniert aber nicht! Sobald ich die Methode rotate() aufrufe verschwindet das ganze Schiff vom Bildschirm. Es taucht auch nicht wieder auf wenn ich zurückrotiere.

Ich hab schon an allen möglichen Stellen Kombinationen aus
invalidate() & validate()
revalidate()
repaint()
updateUI()
usw. versucht.

Das Hilft alles nichts...

Kann mir jemand helfen?

Vielen Dank im Voraus und viele Grüße
Kornelius

Java:
public class ship extends JPanel {

    int variation, length, fieldsize;
    boolean direction;
    /** Creates new form BeanForm */
    public ship(int length, int variation, int fieldsize, boolean direction) {
        super();
        this.length=length;
        this.variation=variation;
        this.fieldsize=fieldsize;
        this.direction=direction;
        

        this.setBackground(new Color(255,255,255,0));
        buildShipGraphics();

    }

    public void buildShipGraphics() //Setzt die Größe des Schiffs (vertikal oder horizontal) und fügt die Labels ein
    {
        int i;
        if(direction)
        {
            this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

            setSize(fieldsize,fieldsize*length);
            setPreferredSize( new Dimension(fieldsize, fieldsize*length) );
            addTile(0,true,0,0,fieldsize);
            for(i=1;i<length-1;i++)
            {
               addTile(1,true,0,fieldsize*i,fieldsize);
            }
            addTile(2,true,0,fieldsize*(i+1),fieldsize);
        }
        else
        {
            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
            setSize(fieldsize*length,fieldsize);
            setPreferredSize( new Dimension(fieldsize*length, fieldsize) );
            addTile(0,false,0,0,fieldsize);
            for(i=1;i<length-1;i++)
            {
               addTile(1,false,fieldsize*i,0,fieldsize);
            }
            addTile(2,false,fieldsize*(i+1),0,fieldsize);

        }
    }

    //posX und posY werden seit dem BoxLayout nicht mehr verwendet:
    private void addTile(int type, boolean vertical, int posX, int posY, int size) 
    {
        String dir = (vertical ? "v" : "h");
        ImageIcon icon = new ImageIcon(getClass().getResource("images/ship_"+Integer.toString(this.variation)+"_" + dir + "_"+Integer.toString(type)+".png").getPath() );
        JLabel temp = new JLabel(scaleTileIcon(icon,fieldsize));
        //temp.setLocation(posX,posY);
        temp.setSize(size,size);
        temp.setPreferredSize(new Dimension(size,size));
        //temp.setIconTextGap(0);
        temp.setBackground(new Color(255,255,255,0));
        this.add(temp);
        temp.setVisible(true);
        temp.validate();
    }

    private ImageIcon scaleTileIcon(ImageIcon icon, int size)
    {
        BufferedImage bi = new BufferedImage(size,size, BufferedImage.TYPE_INT_ARGB);
        bi.getGraphics().drawImage(icon.getImage(), 0, 0, size, size, null);
        return new ImageIcon(bi);
    }

    public void rotateShip()
    {
        this.removeAll();
        direction=(direction?false:true);
        //this.removeAll();
        
        System.out.println(direction);
        //direction=false;
        buildShipGraphics();
        this.validate();
    }
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        setName("ship"); // NOI18N
        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));
    }// </editor-fold>


    // Variables declaration - do not modify
    // End of variables declaration

}
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
ich empfehle
validate();
repaint();
am JFrame aufzurufen, siehe Beispiel unten,
nur innerhalb des JPanels funktioniert es bei mir diesmal nicht, doppelte Anzeige

deine diversen setSize/PreferredSize-Aufrufe habe ich rausgenommen, für meine Text-Label zu klein,
setVisible(true) + validate() auf die JLabel kannst du dir komplett sparen,
Klassen groß schreiben!

Java:
public class TestGUI extends JFrame {
    public TestGUI() {
        ship p = new ship(10, 10, 10, true);
        add(p);
        setSize(950, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        while (true) {
            try{ Thread.sleep(2000);  }  catch (Exception e) {}
            p.rotateShip(); // alle 2 sec rotieren
            validate();
            repaint();
        }
    }

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


class ship
    extends JPanel
{

    int variation, length, fieldsize;
    boolean direction;

    public ship(int length, int variation, int fieldsize, boolean direction)
    {
        this.length = length;
        this.variation = variation;
        this.fieldsize = fieldsize;
        this.direction = direction;
        this.setBackground(new Color(255, 255, 255, 0));
        buildShipGraphics();
    }

    public void buildShipGraphics()
    {
        int i;
        if (direction)
        {
            this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

//            setSize(fieldsize, fieldsize * length);
//            setPreferredSize(new Dimension(fieldsize, fieldsize * length));
            addTile(0, true, 0, 0, fieldsize);
            for (i = 1; i < length - 1; i++)
            {
                addTile(1, true, 0, fieldsize * i, fieldsize);
            }
            addTile(2, true, 0, fieldsize * (i + 1), fieldsize);
        }
        else
        {
            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
//            setSize(fieldsize * length, fieldsize);
//            setPreferredSize(new Dimension(fieldsize * length, fieldsize));
            addTile(0, false, 0, 0, fieldsize);
            for (i = 1; i < length - 1; i++)
            {
                addTile(1, false, fieldsize * i, 0, fieldsize);
            }
            addTile(2, false, fieldsize * (i + 1), 0, fieldsize);

        }
    }

    // posX und posY werden seit dem BoxLayout nicht mehr verwendet:
    private void addTile(int type, boolean vertical, int posX, int posY, int size)
    {
        String dir = (vertical ? "v" : "h");
        JLabel temp = new JLabel("<boot> ");
        // temp.setLocation(posX,posY);
//        temp.setSize(size, size);
//        temp.setPreferredSize(new Dimension(size, size));
        // temp.setIconTextGap(0);
        temp.setBackground(new Color(255, 255, 255, 0));
        add(temp);
    }

    public void rotateShip()
    {
        removeAll();
        direction = (direction ? false : true);
        System.out.println(direction);
        buildShipGraphics();       
    }

    private void initComponents()
    {
        setName("ship");
        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.Y_AXIS));
    }
}
 
C

cmgbr

Gast
Hi,

erstmal vielen Dank für deine schnelle Antwort!

Ich habe es mal so versucht und validate() und repaint() nur im JFrame aufgerufen.
Leider funktioniert es aber immernoch nicht.

Sobald rotateShip() aufgerufen wird verschwindet das Schiff vom Bildschirm...
 
S

SlaterB

Gast
merke: wenn ich ein vollständiges Programm poste, das ohne Fehler läuft, dann bringt es nichts über Fehler in deinem unbekannten Programm mit unbekannter Umsetzung bei dir zu philosophieren,

ich habe deine Vorlage so gut es geht kopiert, mehr ist nicht machbar, du musst schon ein vollständiges Programm mit JFrame und main-Methode posten,
am besten wie bei mir testweise ohne Grafiken und mit mit Text, es sei denn dadurch verschwindet der Fehler, was dann immerhin ein guter Hinweis ist
 

CroniD

Aktives Mitglied
Ich habe mal den Code von cmgbr und den von SlaterB ausprobiert. Beide funktionieren soweit, aber SlaterBs Variante, dass man das JFrame revalidieren sollte ist nicht ganz richtig und auch inperformant. Das Panel zu validieren reicht völlig. Daher könnte ich mir folgendes vorstellen woran es liegen könnte dass du nichts siehst:
1. Der Pfad zu den Images stimmt nicht,
2. die png Dateien sind komplett transparent oder
3. der EDT wird irgendwo blockiert, bevor er zu dem repaint kommt.

Wenn du deinen kompletten Source Code in einer Zip in einem Forum Post von dir anhängen könntest, dann schau ich gerne mal rüber. :)
 
S

SlaterB

Gast
meinen Quellcode kann ja jeder ausprobieren und dann die beiden Befehle von Zeile von Zeile 12 + 13 etwa ans Ende von rotateShip() verschieben

bei mir siehts dann so aus, woran es liegt will ich aber nicht beschwören
 

Anhänge

  • Bildschirmfoto2.png
    Bildschirmfoto2.png
    8,2 KB · Aufrufe: 32

CroniD

Aktives Mitglied
Vorweg: Sry, SlaterB. Ich lag in der Tat falsch. :(

Eigentlich sollte er schon die komplette Fläche des Ships neu zeichnen. Hmm ...

Oh man, ich bin auch bissle döschig. ^^ Setze beim Ship mal setOpaque(false). :) Swing denkt, dass das Ship das zeichnen des Hintergrundes dem Container (in diesem Falle dem JFrame) überlassen soll. Bis man auf sowas kommt. ^^
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P Swing Mehrere JLabels mit ImageIcon in JPanel lesen AWT, Swing, JavaFX & SWT 1
VPChief Icons in 2 Jlabels Director nebeneinander anzeigen AWT, Swing, JavaFX & SWT 26
kilopack15 JLabels im Array erzeugen AWT, Swing, JavaFX & SWT 2
E Swing Miserable Performance beim Ändern der Hintergrundfarbe von JLabels AWT, Swing, JavaFX & SWT 3
A Swing JLabels in einer ForEach Schleife an den JPanel anheften (UNO Netzwerkspiel) AWT, Swing, JavaFX & SWT 1
B Swing HTML in JLabels AWT, Swing, JavaFX & SWT 6
D Event Handling Aus einer anderen Klasse heraus einen Text des JLabels ändern. AWT, Swing, JavaFX & SWT 12
C Swing BufferedImage zeichnen und JLabels setzen. AWT, Swing, JavaFX & SWT 17
J Swing Frage zur Vorgehensweise (JTable?, JLabels?) AWT, Swing, JavaFX & SWT 8
I Jlabels Addieren AWT, Swing, JavaFX & SWT 3
X Swing ListDialog von Oracle mit JLabels AWT, Swing, JavaFX & SWT 2
T Swing Drag and Drop - JLabels tauschen statt überschreiben AWT, Swing, JavaFX & SWT 11
M Position eines JLabels mit getX() auslesen AWT, Swing, JavaFX & SWT 2
M Position eines JLabels speichern? AWT, Swing, JavaFX & SWT 3
S Swing Größe von JLabels verändern sich in einem Panel unterschiedlich AWT, Swing, JavaFX & SWT 6
N Meine JLabels werden nicht angezeigt AWT, Swing, JavaFX & SWT 6
L Name des JLabels auslesen bei Mouseclick AWT, Swing, JavaFX & SWT 2
S Textfelder JLabels AWT, Swing, JavaFX & SWT 3
J JLabels repainten AWT, Swing, JavaFX & SWT 4
D Swing JLabels in einer Schleife aktualisieren AWT, Swing, JavaFX & SWT 2
Balbes Swing Mehrere JLabels vereinen AWT, Swing, JavaFX & SWT 2
M In Jlist auf Änderungen von mehreren JLabels reagieren AWT, Swing, JavaFX & SWT 3
bugmenot Dynamisch erzeugte jLabels werden nicht angezeigt. AWT, Swing, JavaFX & SWT 5
S Probleme beim Neuzeichnen eines JLabels AWT, Swing, JavaFX & SWT 6
B Problem bei Textänderung eines JLabels AWT, Swing, JavaFX & SWT 5
J JLabels usw. dynamisch anlegen AWT, Swing, JavaFX & SWT 8
B Erneuern der Informationen in der GUI und JTable und JLabels AWT, Swing, JavaFX & SWT 2
B zwei JLabels überlappen lassen AWT, Swing, JavaFX & SWT 5
I JScrollPane, wenn JLabels x Pixel erreichen AWT, Swing, JavaFX & SWT 3
K dynamische jlabels AWT, Swing, JavaFX & SWT 21
F Farbiger Text in JLabels AWT, Swing, JavaFX & SWT 9
L Hinzufügen eines JLabels AWT, Swing, JavaFX & SWT 4
U Bilder, JLabels, JButtons voreinander AWT, Swing, JavaFX & SWT 7
loadbrain 3 JLabels untereinander ohne Abstand AWT, Swing, JavaFX & SWT 4
J jlabels überlappen / vorder-hintergrund AWT, Swing, JavaFX & SWT 2
X Focusproblem beim Refresh eines jLabels AWT, Swing, JavaFX & SWT 4
B Update von JLabels AWT, Swing, JavaFX & SWT 2
J GridBagLayout JLabels links ausrichten + vertikaler Freiraum AWT, Swing, JavaFX & SWT 4
G JLabels mehrmals erstellen AWT, Swing, JavaFX & SWT 7
G der sinn von labels/jlabels ? AWT, Swing, JavaFX & SWT 3
V Probleme mit JLabels AWT, Swing, JavaFX & SWT 4
D Font eines JLabels verändern, JLabel mit LookAndFeel-Format AWT, Swing, JavaFX & SWT 2
J Farbverlauf als Hintergrund eines JLabels AWT, Swing, JavaFX & SWT 4
L Größe eines JLabels an enthaltenen Text anpassen AWT, Swing, JavaFX & SWT 2
B Problem mit JLabels und deren Inhalt AWT, Swing, JavaFX & SWT 2
T Größe und Position eines JLabels ermitteln AWT, Swing, JavaFX & SWT 3
P JLabels übereinander legen AWT, Swing, JavaFX & SWT 8
H Swing Wie Fokus von JTextField entfernen? AWT, Swing, JavaFX & SWT 9
TheWhiteShadow JavaFX ListView Problem beim Entfernen von Elementen AWT, Swing, JavaFX & SWT 1
J JavaFX - Included FXML - Entfernen feststellen AWT, Swing, JavaFX & SWT 2
Monokuma Canvas Form entfernen AWT, Swing, JavaFX & SWT 2
R AWT Listeners entfernen AWT, Swing, JavaFX & SWT 0
kodela angezeigtes Image entfernen AWT, Swing, JavaFX & SWT 1
N JavaFX Group: Gezieltes entfernen eines Objects (Rectangle) AWT, Swing, JavaFX & SWT 0
xYurisha Aus einer Gui Buttons, Label und ProgessBars entfernen AWT, Swing, JavaFX & SWT 4
K Swing Entfernen von Panel funktioniert nicht AWT, Swing, JavaFX & SWT 5
B Swing mehrfache Tabelleneinträge entfernen AWT, Swing, JavaFX & SWT 5
M Default-WindowListener JFrame entfernen (Stichwort: iconified) AWT, Swing, JavaFX & SWT 4
M JavaFX TableView & CSS, Rand um Tabellenkopf entfernen AWT, Swing, JavaFX & SWT 3
C SWT MenuBar & MenuItems Fokus wenn F10 unterdrücken/entfernen AWT, Swing, JavaFX & SWT 9
T Swing Tabelle mit Button - Anzeigefehler nach Zeile entfernen AWT, Swing, JavaFX & SWT 1
I Spielsteine zeichnen und entfernen AWT, Swing, JavaFX & SWT 3
wolfgang63 JavaFX Elemente einer Group entfernen AWT, Swing, JavaFX & SWT 1
C Geloest: JTextfield: Titel automatisch entfernen, sobald Text eingegeben wird AWT, Swing, JavaFX & SWT 1
S Die Rücktaste und Entfernen in einer Textarea blockieren AWT, Swing, JavaFX & SWT 3
C JavaFX Entfernen vom "java" Menüeintrag in der Systemmenüleiste in Mac OsX in Verbindung mit JavaFX AWT, Swing, JavaFX & SWT 1
S SWT [TextBox] Bestimmtes Zeichen entfernen unterbinden AWT, Swing, JavaFX & SWT 3
M Element aus JList eines JFileChooser entfernen AWT, Swing, JavaFX & SWT 3
B Buttons entfernen / hinzufügen AWT, Swing, JavaFX & SWT 5
B Fokus markierung entfernen AWT, Swing, JavaFX & SWT 2
M Makierung bei JRadioButton entfernen AWT, Swing, JavaFX & SWT 5
C AWT Fokus von Component entfernen, wenn kein anderes vorhanden AWT, Swing, JavaFX & SWT 4
C SWT CTabFolder / CTabItem Markierung des angewählten Tabs entfernen AWT, Swing, JavaFX & SWT 10
S ImageIcon von Label entfernen AWT, Swing, JavaFX & SWT 9
R Komponente wieder entfernen AWT, Swing, JavaFX & SWT 13
B Komponente "sauber" entfernen(JToolBar) AWT, Swing, JavaFX & SWT 4
R JPanel von JScrollPane entfernen und hinzufügen AWT, Swing, JavaFX & SWT 3
G Swing JTree - Verbindungslinien entfernen AWT, Swing, JavaFX & SWT 4
AyKay SWT (alle) Listener bzw. ModifyEventListener entfernen AWT, Swing, JavaFX & SWT 2
Z Swing Bild aus Panel entfernen AWT, Swing, JavaFX & SWT 12
G Swing MigLayout: Lücken zwischen Elementen entfernen AWT, Swing, JavaFX & SWT 2
Z Swing Buttons wieder entfernen vom Bildschirm AWT, Swing, JavaFX & SWT 5
E Swing Den Button Vergrössern/Verkleinern entfernen AWT, Swing, JavaFX & SWT 4
A Komponenten zur Laufzeit entfernen AWT, Swing, JavaFX & SWT 3
multiholle Button bei Klick entfernen AWT, Swing, JavaFX & SWT 3
A Swing JList Einträge entfernen AWT, Swing, JavaFX & SWT 6
M Swing Rahmen innerhalb des JButton entfernen AWT, Swing, JavaFX & SWT 2
H JFrame Rahmen entfernen AWT, Swing, JavaFX & SWT 1
H JList: Selection-Border entfernen AWT, Swing, JavaFX & SWT 2
T Dynamisches hinzufügen und entfernen von Bildern AWT, Swing, JavaFX & SWT 3
C Swing Schließen, Maximieren, Minimieren entfernen AWT, Swing, JavaFX & SWT 6
S Swing JInternalFrame: Titelleiste entfernen AWT, Swing, JavaFX & SWT 5
L GUI Komponenten zur Laufzeit entfernen AWT, Swing, JavaFX & SWT 4
K SWT und Tree, wie kann ich TreeItem aus einem Tree entfernen? AWT, Swing, JavaFX & SWT 12
byte JTabbedPane - Insets entfernen AWT, Swing, JavaFX & SWT 7
T JTree - alle Nodes entfernen AWT, Swing, JavaFX & SWT 8
T Abbrechen-Icon entfernen AWT, Swing, JavaFX & SWT 4
S JLabel entfernen AWT, Swing, JavaFX & SWT 9
M Redundanzen in JTable entfernen? AWT, Swing, JavaFX & SWT 9
T JCheckBox deselektieren (Haken wieder entfernen) - wie? AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben