Veränderungen am JPanel vom JDialog aus

Hallo

hatte vor ein paar Tagen schonmal ein ähnlich gelagertes Problem, dieses konnte glücklicherweise durch einen Tipp gelöst werden. Hoffe das funktioniert hier auch so. Warscheinlich seh ich wieder nur den Wald vor lauter Bäumen nicht.:oops:

Problemschilderung:
Habe ein JFrame:
Java:
package gui;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class TestFrame extends JFrame {

  private static final long serialVersionUID = 1L;
  private JPanel contentPane;
  private TestPane tp = new TestPane();

  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        try {
          TestFrame frame = new TestFrame();
          frame.setVisible(true);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  public TestFrame() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);
    
    init();
    
  }
  
  private void init() {
    JButton btnNewButton = new JButton("New button");
    btnNewButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        //contentPane.remove(1);
        //tp.doSmth("test");
        new TestDialog();
        contentPane.updateUI();
      }
    });
    contentPane.add(btnNewButton, BorderLayout.SOUTH);
    
    contentPane.add(tp, BorderLayout.CENTER,1);
  }

}

In diesem befindet sich ein Button, mit dem das JDialog geöffnet wird, und ein JPanel als eigene Klasse:

Java:
package gui;

import javax.swing.JPanel;
import javax.swing.JTextPane;

public class TestPane extends JPanel {

  private static final long serialVersionUID = 1L;

  public TestPane() {
    initA();
  }
  
  private void initA() {
    JTextPane txtPaneA = new JTextPane();
    txtPaneA.setText("bla bla bla");
    add(txtPaneA);
  }
  
  private void initB() {
    //removeAll();
    JTextPane txtPaneB = new JTextPane();
    txtPaneB.setText("test test test test");
    add(txtPaneB);
    updateUI();
  }
  
  public void doSmth(String str) {
    switch (str) {
      case "test" : 
        initB();
        System.out.println("initB() test");
        break;
        
      default:
        break;
    }
  }
}

Der Button öffnet folgendes JDialog:

Java:
package gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class TestDialog extends JDialog{

  private static final long serialVersionUID = 1L;
  
  private final JPanel contentPanel = new JPanel();
  private TestPane tp = new TestPane();

  public TestDialog() {
    init();
  }
  
  private void init() {
    setBounds(100, 100, 450, 300);
    getContentPane().setLayout(new BorderLayout());
    contentPanel.setLayout(new FlowLayout());
    contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
    setLocationRelativeTo(null);
    setVisible(true);
    setModal(false);
    getContentPane().add(contentPanel, BorderLayout.CENTER);
    
    JPanel buttonPane = new JPanel();
    buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
    getContentPane().add(buttonPane, BorderLayout.SOUTH);
    
    JButton okButton = new JButton("OK");
    okButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        tp.doSmth("test");
      }
    });
    
    okButton.setActionCommand("OK");
    buttonPane.add(okButton);
    getRootPane().setDefaultButton(okButton);

    JButton cancelButton = new JButton("Cancel");
    cancelButton.setActionCommand("Cancel");
    buttonPane.add(cancelButton);
  }
}

Mit dem OK Button möchte ich nun einfach ein zweites JTextPane neben das andere setzen. Es funktioniert, wenn ich diese Aktion auf den Button im JFrame setze. Aber warum aus dem JDialog heraus nicht? Die Syso-Anweisung ruft er aber auf, nur das Textfeld wird nicht dargstellt.

Habe gelesen, dass der JDialog das JFrame pausiert und somit keine Veränderungen zulässt. Abhilfe soll ein eigener Thread schaffen oder das setzen der Modalität auf false. Nun false war es sowieso und mit dem Thread hat es nicht geklappt (ist nicht im Minimalbeispiel enthalten).
 

renwal

Aktives Mitglied
Wenn ich das richtig verstehe, dann erzeugst du zwei Objekte vom Typ
Code:
TestPane
, nämlich einmal in deinem JFrame und einmal in dem JDialog. Diese Objekte sind voneinander scheinbar völlig unabhängig, sie werden beide mit
Code:
new
generiert. Das eine, das du in dem JFrame erzeugst, fügst du diesem auch hinzu. Alles gut.
Das andere in dem JDialog dagegen bleibt "in der Luft hängen". Es wird nirgendwo hinzugefügt, in diesem Objekt rufst du aber
Code:
doSmth("test")
auf. Da dieses zweite Panel nirgendwo hinzugefügt ist, wird logischerweise auch nirgendwo etwas angezeigt.

Jetzt sagst du, wenn du die Aktion auf den anderen Button legst, dann geht es. Kein Wunder, da greifst du dann ja auch auf das TestPane-Objekt in dem JFrame zu ;).

Wichtig ist, dass beide Objekte außer, dass sie Instanzen der gleichen Klasse sind, nichts miteinander zu tun haben. Du müsstest theoretisch vom JDialog aus auf das JFrame zugreifen, oder einfach das Panel im JDialog diesem auch mal hinzufügen.
Bei der ersten Variante hast du das neue Textfeld danach im JFrame, bei der zweitem im JDialog.
 
Wenn ich das richtig verstehe, dann erzeugst du zwei Objekte vom Typ
Code:
TestPane
, nämlich einmal in deinem JFrame und einmal in dem JDialog.
korrekt

Das andere in dem JDialog dagegen bleibt "in der Luft hängen". Es wird nirgendwo hinzugefügt, in diesem Objekt rufst du aber
Code:
doSmth("test")
auf. Da dieses zweite Panel nirgendwo hinzugefügt ist, wird logischerweise auch nirgendwo etwas angezeigt.
Das soll es auch gar nicht. Es gibt nur ein Panel, ein Frame und ein Dialog. Das Frame beinhaltet das Panel und das Dialog soll Veränderungen auf dem Panel, welches auf dem Frame liegt, bewirken.

Zumindest habe ich schonmal das Problem verstanden, denke ich.
Es gibt für das TestDialog ein völlig anderes TestPanel als für das TestFrame, da ich mit dem new, ein von dem mit new erzeugten Objekts im Testframe, verschiedenes Objekt erzeuge.

Jetzt sagst du, wenn du die Aktion auf den anderen Button legst, dann geht es. Kein Wunder, da greifst du dann ja auch auf das TestPane-Objekt in dem JFrame zu ;).
Das war mir auch bewusst :p

Du müsstest theoretisch vom JDialog aus auf das JFrame zugreifen, oder einfach das Panel im JDialog diesem auch mal hinzufügen. Bei der ersten Variante hast du das neue Textfeld danach im JFrame, bei der zweitem im JDialog.
Gedacht ist eben, dass das Textfeld im Panel erscheint. Wie und wo ist erst mal egal weil es geht mir nur darum, dass es funktioniert. Die hier gestellte Situation ist sowieso nur eine Simulation, entspricht aber dem, was ich im erweitertem Sinne vorhabe.

Ich habe es nun so gelöst, dass ich im Testframe folgendes verändere:
Alt:
Code:
 private TestPane tp = new TestPane();[/c]
Neu: [code] public static TestPane tp = new TestPane();[/c]

im TestDialog entfällt diese Zeile dann komplett aber ich greife auf das TestPane über das TestFrame zu mit:
Alt: [code]tp.doSmth("test");
Neu:
Code:
TestFrame.tp.doSmth("test");

Ist das so sauber? Ich habe aber das Gefühl, dass ich so anderweitig auf Probleme stoßen werde, da ja nun das TestPane static ist? Könnte man das static auch umgehen? Bisher tat ich das, durch das Anlegen von Objekten. :oops:
 

renwal

Aktives Mitglied
Das klingt auf jeden Fall besser, aber sauber ist das nicht. Wie du schon richtig vermutet hast, liegt es an dem static-Modifier. Für dein Projekt wird das wohl funktionieren, aber du solltest das bei "richtigen" Projekten nie machen. Durch das static kannst du auf das Objekt zugreifen, ohne es über eine Klasseninstanz anzusprechen. Das würde z.B. kompliziert werden, wenn du mehrere dieser Frames hast.
Ich habe eine andere Lösung dafür benutzt, ob die allerdings so viel besser ist, weiß ich auch nicht. Der JDialog bekommt einfach einen Zeiger auf die eigene Klasse des JFrames über seinen Konstruktor.

Deinen Dialog erzeugst du dann mit
Java:
new TestDialog(this)
.

Deine TestFrame-Klasse muss dann wie folgt beginnen:
Java:
 public class TestDialog extends JDialog{
private static final long serialVersionUID = 1L ;
private final JPanel contentPanel = new JPanel () ;
private TestPane tp = new TestPane() ;

private TestFrame frame;

public TestDialog(TestFrame frame) {
this.frame = frame;
init() ;
} 

public doSmthOnTestPane(String s)
{
tp.doSmth(s);
}
[...]

Die
Code:
doSmthOnTestPane(String s)
-Methode kannst du benutzen, dann rufst du im TestDialog einfach diese Methode auf, dann musst du
Code:
tp
nicht einmal public machen. So verhinderst du gleich Modifikationen von außen, auch das hilft dir bei größeren Projekten.

PS: Sorry für die schlechte Formatierung, geht auf dem Handy nicht besser.
 
Hast du das mal getestet?
Ich habe deinen Code mal ein wenig modifiziert:

das in TestDialog:
Java:
[...]
  private final JPanel contentPanel = new JPanel();
  private TestFrame frame;
  
  public TestDialog(TestFrame frame) {
    this.frame = frame;
    init();
  }
[...]

das in TestFrame:
Java:
[...]
public TestPane tp = new TestPane();
[...]
      public void actionPerformed(ActionEvent e) {
        openDialog();
        contentPane.updateUI();
      }
[...]
  private void openDialog() {
    new TestDialog(this);
  }
[...]

So bekomme ich zwar das static weg aber das public nicht.
Die Idee find ich aber erstmal so klasse, dass ich sie direkt mal in mein Projekt implementierte und gleich ein paar Schönheitsfehler beseitigen konnte. Danke dir dafür. :)
Gui's sind nicht meine stärke... :oops:

Wenn ich jetzt noch eine Lösung dafür finde, dass ich nicht alle Panels auf public setzen muss, bin ich ganz zufrieden.
 

renwal

Aktives Mitglied
Ahhh! Stop! Ich habe gerade einen Fehler in meinem Post gefunden! Die zweite Klasse ist natürlich Mist, ich ich hab da irgendeine Mischung aus TestDialog und TestFrame gemacht! Da ich den Beitrag nicht mehr ändern kann, hier der RICHTIGE Code.

TestFrame:
Java:
public class TestFrame extends JFrame {
 
  private static final long serialVersionUID = 1L;
  private JPanel contentPane;
  private TestPane tp = new TestPane();

  public doSmthOnTestPane(String s)
  {
    tp.doSmth(s);
  }
[...]

TestDialog:
Java:
public class TestDialog extends JDialog{
private static final long serialVersionUID = 1L ;
private final JPanel contentPanel = new JPanel () ;
private TestPane tp = new TestPane() ;
 
private TestFrame frame;
 
public TestDialog(TestFrame frame) {
  this.frame = frame;
  init() ;
}

Sorry dafür!
 
Zuletzt bearbeitet:
Und genau so habe ich es auch inzwischen. ;) Mir kahm die im Garten, dass ich doch die doSmthOn... Methode innerhalb des Frames auf das Pane zugreifen lassen kann und somit alle Objekte private setzen darf. Gerade getestet und es klappt wunderbar. Tja man muss mit den Leuten reden wenn man eine gute Idee haben möchte.

Ich bin aber trotzdem mal so frech und verbessere dich, für den Fall das weitere deinen Code nutzen:
Java:
  public void doSmthOnTestPane(String s)
  {
    tp.doSmth(s);
  }
Kann ja sein, dass andere Leser das nicht sehen und sich dann beim ausführen wundern wieso der compiler meckert.

Danke dir noch einmal.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D JPanel soll auf Veränderungen reagieren! Java Basics - Anfänger-Themen 6
P Veränderungen einer ObservableList Java Basics - Anfänger-Themen 10
N Veränderungen dauerhaft speichern Java Basics - Anfänger-Themen 3
C Source Veränderungen-Erlaubt? Java Basics - Anfänger-Themen 27
N Veränderungen in JTextArea erkennen Java Basics - Anfänger-Themen 5
richis-fragen Optisch JPanel BorderLayout vertikaler Rand dicker als horizontaler Rand Java Basics - Anfänger-Themen 4
N Klassen Hintergrundfarbe in JPanel ändert sich nicht Java Basics - Anfänger-Themen 3
J JSON mit einem JPanel Java Basics - Anfänger-Themen 3
J Ein mit UI-Designer erstelltes JPanel einblenden Java Basics - Anfänger-Themen 0
J Eine theoretische Frage zur Praxis - JPanel oder Canvas Java Basics - Anfänger-Themen 5
J Beim Start des Programms zB. eine Linie in JPanel ausgeben Java Basics - Anfänger-Themen 4
C mehrere JPanel in ein JFrame bringen Java Basics - Anfänger-Themen 9
M HILFE JPanel - Graphics Java Basics - Anfänger-Themen 1
B Scrollbares Fenster (JScrollPane) mit JPanel scrollt nicht Java Basics - Anfänger-Themen 3
Zeppi JPanel responsive Grid Java Basics - Anfänger-Themen 0
J JPanel in JScrollPanel Java Basics - Anfänger-Themen 4
Elyt JPanel als HintergrundBild Java Basics - Anfänger-Themen 7
W 2 JPanel in einem JFrame Java Basics - Anfänger-Themen 4
B Wie kann man an ein JPanel eine Scrollbar anheften? Java Basics - Anfänger-Themen 8
O Swing JPanel Java Basics - Anfänger-Themen 4
CptK Klassen JPanel nach Ablauf der Spielzeit neuladen Java Basics - Anfänger-Themen 2
S JPanel wird nicht angezeigt Java Basics - Anfänger-Themen 1
D Animation JPanel Java Basics - Anfänger-Themen 1
M JLabels "verrutschen" beim übergeben von JPanel Java Basics - Anfänger-Themen 2
D Auf angeklicktes JPanel zugreifen Java Basics - Anfänger-Themen 5
D JPanel mehrere Formen zeichnen Java Basics - Anfänger-Themen 5
D JPanel passt die Größe nicht an Java Basics - Anfänger-Themen 22
Y Webinhalt JPanel Java Basics - Anfänger-Themen 6
D Erste Schritte JPanel verschiebt Fenster via setVisible Java Basics - Anfänger-Themen 5
Dechasa Interface JFrame mit mehreren Übereinander liegenden JPanel Java Basics - Anfänger-Themen 5
S JPanel variablenabhängig erstellen Java Basics - Anfänger-Themen 13
J Methoden Dinge auf einem JPanel paltzieren Java Basics - Anfänger-Themen 1
Z JPanel wird zweimal hinterinander gezeichnet.. Wieso? Java Basics - Anfänger-Themen 4
F JFrame resize verschiebt JPanel Java Basics - Anfänger-Themen 3
A altes JPanel entfernen und neues öffnen Java Basics - Anfänger-Themen 5
I A0-Format in jpanel anzeigen Java Basics - Anfänger-Themen 1
R NullPointerException wegen JPanel oder doch nicht ? Java Basics - Anfänger-Themen 7
J Probleme mit eigenem JPanel (IDE Eclipse) Java Basics - Anfänger-Themen 4
S JPanel wird versetzt auf JFrame gelegt Java Basics - Anfänger-Themen 2
V jab ich eclipse verrückt gemacht :D ? array Jpanel, Jlabel Grafik Fehler / Frage Java Basics - Anfänger-Themen 5
R Focus auf JPanel im Thread Java Basics - Anfänger-Themen 9
I Problem mit JPanel Java Basics - Anfänger-Themen 0
B JPanel ändert die Hintergrundfarbe nicht Java Basics - Anfänger-Themen 2
F Threads funktionieren auf JPanel nicht Java Basics - Anfänger-Themen 1
C JPanel in MessageDialog Java Basics - Anfänger-Themen 1
B JPanel/JFrame in ein Applet umwandeln (Webfähig) Java Basics - Anfänger-Themen 7
S Inhalt von JPanel erst nach Resize sichtbar Java Basics - Anfänger-Themen 2
M Listener einerm JPanel hinzufuegen Java Basics - Anfänger-Themen 3
gamebreiti Methoden JPanel nach clearAll() und add neu zeichnen Java Basics - Anfänger-Themen 1
S vom JPanel aus durch Mouselistener Internet aufrufen Java Basics - Anfänger-Themen 6
Z JPanel bleibt leer Java Basics - Anfänger-Themen 2
E Bild per Verzeichnis/JFileChooser auf JPanel laden Java Basics - Anfänger-Themen 13
Q JPanel Java Basics - Anfänger-Themen 2
K Erste Schritte jpanel in einer klasse auslagern Java Basics - Anfänger-Themen 3
I Anfängerfrage JPanel repaint() Java Basics - Anfänger-Themen 6
N String auf JPanel bewegen Java Basics - Anfänger-Themen 6
K Erste Schritte Jframe Im Jpanel Java Basics - Anfänger-Themen 4
S Layout mit JPanel in JScrollPanel funktioniert nicht Java Basics - Anfänger-Themen 3
S JPanel drucken -> PrinterException Java Basics - Anfänger-Themen 2
B JPanel -JTable Java Basics - Anfänger-Themen 2
H JPanel Hintergrund transparent setzen? Java Basics - Anfänger-Themen 10
A Input/Output Hashmap in einem JPanel via JList anzeigen Java Basics - Anfänger-Themen 8
L zoomen aus jpanel Java Basics - Anfänger-Themen 7
P Bekomme in meinen JPanel nur eine JComponente angezeigt Java Basics - Anfänger-Themen 7
A Methoden repaint() zeichnet JPanel falsch Java Basics - Anfänger-Themen 3
R JFrame über einen JPanel Java Basics - Anfänger-Themen 5
F JPanel zu klein Java Basics - Anfänger-Themen 5
D GUI - Objekte in JPanel nach oben schieben Java Basics - Anfänger-Themen 2
S JPanel wird nicht eingefügt Java Basics - Anfänger-Themen 3
P Netbeans Platform - JLabel und JPanel setLocation Problem Java Basics - Anfänger-Themen 2
Kenan89 JPanel mit JTable Java Basics - Anfänger-Themen 9
I JPanel in JPanel Java Basics - Anfänger-Themen 2
A Zugriff auf Komponente innerhalb einer JPanel Java Basics - Anfänger-Themen 8
J Auf einem JPanel ein JFrame platzieren Java Basics - Anfänger-Themen 10
S JPanel anzeige Java Basics - Anfänger-Themen 2
propra Wie mache ich einem JPanel mein bereits instanziertes Model bekannt Java Basics - Anfänger-Themen 9
T Zugreifen auf JPanel Java Basics - Anfänger-Themen 4
K JPanel auslagern Java Basics - Anfänger-Themen 9
J Paint Methode von JPanel aufrufen Java Basics - Anfänger-Themen 15
T Tastendruck simulieren in JPanel Java Basics - Anfänger-Themen 3
P JPanel in JTable einfügen Java Basics - Anfänger-Themen 23
E Erste Schritte Objekte werden in JPanel angedockt und maximiert Java Basics - Anfänger-Themen 7
M Componenten auf JPanel anzeigen Java Basics - Anfänger-Themen 2
F JPanel als JPG - weisse Fläche Java Basics - Anfänger-Themen 9
L Image laden und auf jPanel ausgeben Java Basics - Anfänger-Themen 7
M JLabel auf JPanel positionieren Java Basics - Anfänger-Themen 8
M Verständnisfrage zu JPanel Java Basics - Anfänger-Themen 3
M MouseListener funkioniert auf JPanel nicht Java Basics - Anfänger-Themen 8
D JPanel + ein JLabel Java Basics - Anfänger-Themen 8
B JPanel-Oberfläche speichern Java Basics - Anfänger-Themen 9
X JTable in JPanel in JTabbedPane mouseevent von jtable kommt nicht durch Java Basics - Anfänger-Themen 3
P GUI, JPanel Java Basics - Anfänger-Themen 7
H JPanel in andere Klasse übergeben Java Basics - Anfänger-Themen 7
D Grösse eines JPanel hinsichtlich LayoutManager festlegen Java Basics - Anfänger-Themen 4
B JPanel über anderem JPanel Java Basics - Anfänger-Themen 6
F zeichnen in JPanel Java Basics - Anfänger-Themen 7
F Unterschied JPanel und JFrame Java Basics - Anfänger-Themen 5
U JPanel dynamisch gestalten Java Basics - Anfänger-Themen 7
H Zeichnen in JPanel Java Basics - Anfänger-Themen 8
K Auf JPanel Zeichnen Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben