non-static variable cannot be refferenced from a static context

0
 public static void main(String[] args){
        final plikerShort okno=new plikerShort();  //tworzy okno programu.
        
        okno.bZapisz.addActionListener(new ActionListener(){ //button2
            @Override
            public void actionPerformed(ActionEvent arg0) {
                Object e=arg0.getSource();
                //File plik;
                
                if (e==okno.bZapisz){
                    File plik=new File("test.txt");
                    if (plik.exists()){
                        okno.txtArea.setText(plik.getName());
                    }
                    else okno.txtArea.setText("brak pliku");
                    } 
                }
        });
		
        okno.bWczytajDaneXML.addActionListener(new ActionListener(){  //button Wyswietl
            @Override
            public void actionPerformed(ActionEvent arg0) {
                Object e=arg0.getSource();
                //File plik;
                
                if (e==okno.bWczytajDaneXML){
                    okno.txtArea.setText("tu ma być ścieżka do pliku wybranego wyżej");
                    okno.txtArea.append(plik.getAbsolutePath());
                }}
        });
        
    } 

Witam, powyżej jest kawałek kodu, cała funkcja main w zasadzie.

Wiem,że wątków dla tego tematu jest tu i w internecie multum, ale nie znalazłem odpowiedzi na nurtujące mnie pytanie.
Jeśli wg. powyższego kodu wcisnę pierwszy button, to program utworzy mi nową zmienną typu File ( statyczną ),
i inaczej tego nie potrafię zrobić dopóki chcę utworzyć zmienną poprzez zdarzenie ( np. wciśnięcie przycisku ).
natomiast ja chcę tą zmienną wykorzystać przy innym zdarzeniu ( np. przy wciśnięciu drugiego przycisku )
I mam problem żeby to zrealizować. Co bym nie kombinował to dostaję komunikat jak w temacie.

Za wskazówki i pomysły będę wdzięczny.

1

Kod, który masz w metodzie main przenieś do konstruktora:

public static void main(String[] args)
{
     new nazwaTwojej_Klasy();
}
public nazwaTwojejKlasy()
{
        final plikerShort okno=new plikerShort();  //tworzy okno programu.
        
        okno.bZapisz.addActionListener(new ActionListener(){ //button2
        ....
}
0

Dzięki
To nie było dokładnie to czego potrzebowałem, ale też rozwiązało kilka problemów.

Prawidłowe pytanie powinno brzmieć : "jak przenieść zmienną pomiędzy klasami czy też obiektami "- bo do końca jeszcze nie ogarniam tej terminologii , ale poradziłem sobie.

0

Skoro zaczynasz się uczyć, to warto, żebyś nie nabył pewnych fatalnych nawyków programowania. Wnętrze metod obsługujących zdarzenia powinno być krótkie i szybkie w wykonaniu. Na przykład nie więcej niż czas równy wykonaniu ok. 500 przypisań zmiennych.
Dlatego powinieneś poznać kilka faktów:
Jeżeli utworzenie zmiennej i zainicjowanie jej np: int a = 99 trwa 1 (jednostka bez znaczenia), to:

  1. Konstrukcja instrukcji try trwa ok. 500
  2. Wywołanie operacji new coś(...) trwa ok. 1000
  3. Wywołanie operacji new coś[10] trwa ok. 3000
  4. Wywołanie operacji otwarcia i/lub utworzenia pliku trwa od 1 mln w górę
    Żadnej z tych rzeczy nie powinieneś robić w obsłudze zdarzenia.
0

Czyli jeśli zastosować się do Twoich rad, to czy zmiana w kodzie poniżej ma sens ??
Teoretycznie nie ma bezpośredniej instrukcji tworzenia i przypisania zmiennej e w drugim przypadku, więc taki zapis powinien być lepszy ?

 okno.bZapisz.addActionListener(new ActionListener(){ //button2
            @Override
            public void actionPerformed(ActionEvent arg0) {
                Object e=arg0.getSource();
                if (e==okno.bZapisz){
                        okno.txtArea.setText(plik.getName());
                }
 okno.bZapisz.addActionListener(new ActionListener(){ //button2
            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (arg0.getSource==okno.bZapisz){
                        okno.txtArea.setText(plik.getName());
                }

Dodatkowo, czy zawsze da się umieścić try w innym miejscu ?
Przecież w przypadku z otwarciem/zamknięciem pliku jeśli jest to w obsłudze zdarzenia , to i wyjątki muszę chyba tam łapać?

0

Oba zapisy robią to samo poza tym, że w tym pierwszym tworzysz na stosie dodatkową zmienną referencyjną typu Object, co ma znikomy (wręcz niemierzalny) wpływ na szybkość obsługi. Nie miałem bezpośrednich odniesień do kodu, który pokazałeś ponieważ nie ma w nim żadnego antywzorca.
To było tylko zwrócenie Twojej uwagi na unikanie pewnych rzeczy które psują współpracę aplikacji z użytkownikiem. Poza tym klasa File choć sugeruje, że reprezentuje plik - faktycznie reprezentuje samą nazwę pliku. Operacje na nazwach nie powodują wyjątków, ani narzutu czasowego. Dopiero otwarcie/utworzenie pliku i transmisja są realnymi operacjami plikowymi (rzucającymi wyjątki), które nie powinny samodzielnie istnieć w kodzie obsługi listenera. Powinny się one znaleźć w zadaniu/nowym wątku, które będzie wykonywane równolegle z dalej biegnącą obsługą interfejsu gui, gdy sterowanie wyjdzie z metody obsługi listenera. Dlatego wtedy nie ma potrzeby używania w takiej metodzie instrukcji try bo nie powinno być nic co mogłoby się nie udać. Natomiast zwykle otwarcie pliku, transmisja i zamknięcie go jest zadaniem, którego wynikiem może być potwierdzenie sukcesu (np. jako wyliczona wartość/obiekt) lub rzucony wyjątek w przypadku niepowodzenia. W samej procedurze listenera nie powinieneś wywoływać niczego co może wywołać wyjątek. To można zrobić w zadaniu (np. Runnable Callable<?>), które można wykonać dowolnym wykonawcą (executor) lub w nowo uruchomionym wątku.
Jeżeli już wywołasz w obsłudze zdarzenia coś co może rzucać wyjątki, to trzeba to koniecznie łapać ponieważ nieobsłużone mogą prowadzić do nieprzewidzianych skoków sterowania w wątku wywołującym listenera.

0

Jeśli dobrze zrozumiałem Twoje rady @Olamagato, to chcąc utworzyć buttona np. do zapisu do pliku to prawidłowo powinno wyglądać to tak ? :

bZapisz.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent arg0){
                if (arg0.getSource()==bZapisz){
                    try {
					zapis z=new zapis().zapis("text do zapisania");
                    } catch (IOException ex) {                }
                }
            }
        });
		
		
    class zapis {
        private zapis zapis(String arg) throws IOException{
            PrintWriter out=null;
            String sZapis=arg;
            if(wybierzZ.showSaveDialog(null)==JFileChooser.APPROVE_OPTION){
                    plik2=wybierzZ.getSelectedFile();}
            if (!plik2.exists()) {
                plik2.createNewFile();
            }
                try {
                    out=new PrintWriter(new FileWriter(plik2));
                    out.println(sZapis);
                    out.close();
                }   catch(NullPointerException ex){
                    System.out.println("npe wylazł");
                }

            return null;
        }
    }

niestety ten try w ActionListenerze jest wymuszony przez NetBean'a, którego używam więc jednak czasem chyba nie da się go uniknąć

z tymi wątkami to jeszcze tego nie próbowałem nawet rozgryźć, więc może na razie zostańmy przy najprostszych rzeczach :).

1 użytkowników online, w tym zalogowanych: 0, gości: 1