Thread + getters und setters

Vehementis

Mitglied
Ich hab noch nicht so viel Java erfahrung hab erst vor paar wochen angefangen mich damit zu beschäftigen

ich hab mich nun mal nachdem ich den Programmcode immer in Herachien ablaufen lassen hab mal an Threads gewagt...

ich will einen Thread machen der dauerhaft neben dem GUI im hintergrund läuft und mir eine variable durch System.out.println alle 0,5s ausgibt
wenn ich beim GUI einen Button klicke soll sich diese Variable in eine zahl zwischen 1 und 50 ändern

nur gibt mir der Thread die ganze zeit aus dass I1 = 0 ist obwohl ich es ja durch den setter ändere
und bei "I1 wurde auf ... geändert" gibt es mir auch das richtige aus
woran liegt das?
kann ich einen Thread keine aktuellen variablen abfragen lassen?

hier mein Code:
JavaTestApp.java
Java:
package javatestapp;

public class JavaTestApp {


    public static void main(String[] args) {
            new GUI().setVisible(true);
            ThreadTest tt = new ThreadTest();
            Thread t1 = new Thread(tt);
            t1.start();
        }
    }

GUI.java
Java:
package javatestapp;
public class GUI extends javax.swing.JFrame {

    private ThreadTest TT = new ThreadTest();
    /**
     * Creates new form GUI
     */
    public GUI() {
        initComponents();
    }

    /**
     * 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() {

        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("Zufall");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 73, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButton1)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        TT.setI1((int) (Math.random()*50));
        System.out.println("I1 auf " + TT.getI1() + " geändert");
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * [url=http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html]How to Set the Look and Feel (The Java™ Tutorials > Creating a GUI With JFC/Swing > Modifying the Look and Feel)[/url]
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new GUI().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    // End of variables declaration
}

ThreadTest.java
Java:
package javatestapp;


public class ThreadTest implements Runnable 
{
    private int I1 = 0;
    
    public void run()
    {
        while (true)
        {
            System.out.println("I1 = " + getI1());
            try
            {
                Thread.sleep(500);
            }
            catch (Exception e) {System.out.println(e);}
        }
    }
    
    public int getI1() 
    {
        return I1;
    }

    public void setI1(int I1) 
    {
        this.I1 = I1;
    }
}
 
Du erstellst zwei Threads, einmal JavaTestApp und einmal in GUI. Den in JavaTestApp startest du auch, den in GUI nicht. Du veänderst in GUI aber die Werte des Threads der nicht gestartet ist, der Wert im gestarteten Thread bleibt konstant.
 
meinst du das
[JAVA=4]
private ThreadTest TT = new ThreadTest();
[/code]
in GUI ?
ich dachte das wäre nur dafür um an den setter über TT.setI1() heran zu kommen

naja gut und wie muss ich das machen damit es so funktioniert wie ich das will und er die geänderte variable zurück gibt?
ich hab schon ein bisschen rumprobiert aber wenn ich den Thread statt aus dem JavaTestApp aus GUI versuch zu starten meckert er immer rum wegen dem static oder er staret den Thread einfach nicht

ich weiß auch nicht was ich an GUI.java alles ändern kann da es von NetBeans automatisch erstellt wurde
 
Ganz einfach ginge das zum Beispiel so:

Java:
public GUI() {
        initComponents();
        TT.start();
    }

Aber du solltest dich denke ich noch ein bisschen mit den Basics beschäftigen bevor du mit Threads rumhantierst.
 
danke hat so funktioniert =)

naja man wächst mit seine Herausforderungen xD

naja es ist so das ich mir vor 2 wochen mal nen einfaches Tick Tack Toe erstellt hatte

das hatte ich dann letztes we zum Multiplayer umgebaut über TCP...
es funktioniert auch bis auf die tatsache das es zwischendurch wärend dem warten auf den 2. spieler ständig freezed und man seine eigene eingabe nicht sieht
deswegen wollte ich versuchen das in nem extra thread laufen zu lassen um dem entgegen zu wirken
 
das mit dem Thread starten klappt jetzt alles super
jetzt muss ich für mein TickTackToe allerdings aus dem Thread auf das GUI zugreifen um um textfeldinhalte abzufragen und zu setzen
auch hierfür hab ich mir in GUI nen getter und einen setter erstellt
die frage ist nur wie komme ich da ran ohne einen neuen Thread zu starten?
ich hab mir überlegt das TT.start() eventuell in ein "if" zu setzen und mit nem boolean festzulegen ob schon ein thread läuft oder nicht das funktioniert aber nicht ganz weil wenn ich in GUI ein boolean definiere wird sobald ich new GUI() mache ja wieder ein neuer boolean erstellt
 
wie oft erstellt man schon neue GUIs?
ohne alles gelesen zu haben der allgemeinen Schritt neu angewandt: wenn du auch über mehrere GUIs etwas gemeinsames verwalten willst, dann brauchst du eben eine weitere Klasse Controller oder so, von der es nur ein Objekt gibt welches an alle GUI-Objekte übergeben wird, dort steht dann drin ob es schon einen Thread gibt usw.,

eine statische Variable ist immer der einfache Weg für einzelne Dinge
 
naja ich will ja eigentlich kein neues GUI ich will einfach auf eine funktion in meinem GUI zugreifen

das heißt
wenn ich jetzt z.B.
eine JavaTestApp.java habe in der ich das GUI aufrufe... aslo
Java:
public class JavaTestApp 
{
    public static void main(String[] args) 
    {
        new GUI().setVisible(true);
    }
}

von meinem GUI aus wird dann der Thread gestartet
[JAVA=21]
public GUI()
{
initComponents();
thread.start();
}
[/code]

Dieser Thread fürt eine while schleife die unter bestimmten umständen das ausführt:
[JAVA=46]
try
{
System.out.println("Sie sind Client, verbinde");
int port = Integer.parseInt(?????.getTF1());
String IP = ?????.getTF2();
socket = new Socket(IP, port);
System.out.println("Server verbunden");
} catch (Exception e)
{
System.out.println(e);
}
[/code]
so mein Problem sind nun die "?????"

hier will ich auf folgendes in GUI.java zugreifen:
[JAVA=8]
public String getTF1()
{
return jTextField1.getText();
}
public String getTF2()
{
return jTextField2.getText();
}
public void setTP(String text)
{
jTextPane1.setText(text);
}
[/code]


normalerweiße mache ich das ja so:
Java:
private GUI gui = new GUI();
und dann würde das obere so aussehen:
Java:
                        try
                        {
                            System.out.println("Sie sind Client, verbinde");
                            int port = Integer.parseInt(gui.getTF1());
                            String IP = gui.getTF2();
                            socket = new Socket(IP, port);
                            System.out.println("Server verbunden");
                        } catch (Exception e)
                        {
                            System.out.println(e);
                        }

hierbei wird allerdings dann ein neuer thread gestartet was ich ja nicht will
ich will einfach nur das return von getTF1 und getTF2
 
new GUI() würde dir dabei überhaupt nicht helfen, selbst wenn du kontrollieren könntest dass dort kein zweiter Thread
(bzw. in Endloskreis noch weitere Threads + GUIs) gestartet wird,
zwei GUIs wäre für sich schon schlecht,

du musst einfach nur dem Thread relativ am Anfang, z.B. per Konstruktor, die GUI übergeben, eine simple Aufgabe
 
also irgendwie mögen mich die Konstruktoren nicht oder die Tutorials mit denen ich versuche zu lernen beschreiben es nicht so wie ich es brauch...

egal hab das jetzt etwas anders geregelt aber es scheint zu laufen

ich hab in meiner OnlineTickTackToe.java (main class) folgendes
Java:
    public static void main(String[] args) 
    {
        OnlineTickTackToeGUI otttg = new OnlineTickTackToeGUI();
        OnlineTickTackToeClass otttc = new OnlineTickTackToeClass();
        otttg.setottt(otttc, otttg);
        otttg.setVisible(true);
    }

in meinem OnlineTickTackToeGUI.java folgendes
Java:
    private OnlineTickTackToeClass otttc;
    private OnlineTickTackToeGUI otttg;
    private Thread thread;
Java:
    public void setottt(OnlineTickTackToeClass otttc, OnlineTickTackToeGUI otttg)
    {
        this.otttg = otttg;
        this.otttc = otttc;
        otttc.setotttg(otttg);
        thread = new Thread(otttc);
        thread.start();
    }

und in meiner OnlineTickTackToeClass.java folgendes
Java:
    private OnlineTickTackToeGUI otttg;
Java:
    public void setotttg(OnlineTickTackToeGUI otttg)
    {
        this.otttg = otttg;
    }

so müsste das doch gehen oder sieht da jemand Probleme?
 
da scheinst du ja nun reichlich Konstruktoren, setter und quasi init-Methoden (mehr als nur ein einfacher setter) im Einsatz zu haben, die großen 3 vereint,

der Sinn von OnlineTickTackToeClass bleibt nur per Code sicherlich für alle unsichtbar,
falls du das nur machst damit, wie aktuell das Thema ist, der Thread die GUI kennt, dürfte es auch ohne gehen,

statt im Konstruktoraufruf
thread = new Thread(otttc);
das neue OnlineTickTackToeClass zu übergeben machte die GUI zum Konstruktor-Parameter, das muss offensichtlich genauso funktionieren,
oder arbeite ohne Konstruktor mit einem setter, genau den Code den du in OnlineTickTackToeClass drin hast:
Java:
  private OnlineTickTackToeGUI otttg;

    public void setotttg(OnlineTickTackToeGUI otttg)
    {
        this.otttg = otttg;
    }
 
ich hätte ja meinen code mal gepostet aber er ist zu lang dafür sagt es mir...
naja ich hab mein Online Tick Tack Toe jetzt zum laufen bekommen 😀
muss nurnoch mal testen ob es auch auf verschiedenen Computern läuft
also zur zeit über 127.0.0.1 geht es aber ka was die firewall und virenscanner noch anstellt xD

EDIT:
also ich habs mal übers internet versucht und es geht nicht...
welchen port sollte ich den am besten nehmen oder muss der TCP Port erst in beiden routern freigegeben werden?
 
Zuletzt bearbeitet:

Zurück
Oben