Java, Referencja i zapis do pliku

0

Witam, Powiązałem przez referencję zapis programu do pliku z klasą baza, ale podkreśla mi że jest niekompatybilna klasa.. Domyślam się, że jest to spowodowane tym, że nie wywołuje tego w oknie głównym:

 /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package wypozyczalnia_filmow;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import javax.swing.JOptionPane;

/**
 *
 * @author Marek
 */
public class zapisz_program extends baza {
    
  baza mainWindow = null;    
 
public zapisz_program(baza mainWindow)
{   
this.mainWindow = mainWindow;
try
{
FileOutputStream f = new FileOutputStream("bazadmina.txt");
ObjectOutputStream str = new ObjectOutputStream(f);
str.writeObject( mainWindow.baza.getModel());
str.flush();
f.close();
}
catch(IOException exx)
{
JOptionPane.showMessageDialog(null,exx.getMessage(),"Zapisywanie do pliku "+"bazadmina.txt",JOptionPane.INFORMATION_MESSAGE);
}
    
}
}

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package wypozyczalnia_filmow;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;



class baza extends JFrame implements ActionListener
{
   
File a;
JButton dodaj,usun,edytuj,impo,ekspo,wyszukaj;
JTable baza;
Object wiersz[][]; //objektreprezentujący wiersz tabeli
DefaultTableModel model;
JFileChooser chooserzapis= new JFileChooser();
JFileChooser chooserodczyt= new JFileChooser();


  
public void  baza()
{
  
    
setTitle("Baza"); //tytuł okna
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 
String kolumna[] = {"Tytuł","Czas trwania","Kategoria","Nośnik","Rok premiery","Opis","Obsada","Reżyser"}; // tytuły kolumn tabeli
model = new DefaultTableModel(wiersz, kolumna); //definiowanie modeu tabeli
baza = new JTable(model);
setLayout(new FlowLayout(FlowLayout.CENTER));
JScrollPane js = new JScrollPane(baza,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
js.setPreferredSize(new Dimension(700,700)); // rozmiar obszaru tabeli
new wczytywanie_przy_otwieraniu(this);




dodaj = new JButton("Dodaj");
usun = new JButton("Usuń");
edytuj=new JButton("Edytuj");
impo=new JButton("Importuj");
ekspo=new JButton("Eksportuj");
wyszukaj=new JButton("Wyszukaj");

add(dodaj);
add(usun);
add(edytuj);
add(impo);
add(ekspo);
add(wyszukaj);
add(js);

dodaj.addActionListener(this);
usun.addActionListener(this);
impo.addActionListener(this);
ekspo.addActionListener(this);
baza.setAutoCreateRowSorter(true);


setSize(1000,1000);
setVisible(true);
WindowListener sluchacz = new Zamykanie();
addWindowListener(sluchacz);
   
}

// Zamykanie okna
class Zamykanie extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
int answer = JOptionPane.showConfirmDialog(null, "Czy na pewno chcesz zamknąć program", "Koniec", JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION)
{
    new zapisz_program(this);
    dispose();
}   
}
}




@Override
public void actionPerformed(ActionEvent e) {

Object z=e.getSource(); // Stworzenie obiektu, który jest źródłem sygnału

      
 if(z==dodaj)
{
    
formularz_dodawania_filmow y= new formularz_dodawania_filmow(baza.this);
   
}
    
else if(z==usun)
{
    
model = (DefaultTableModel) baza.getModel();
model.removeRow(baza.getSelectedRow());
}

else if(z==edytuj)
    
{    
    
    
    
}

//Zapis tabeli do pliku
 else if(z==impo)
 {
   
 }

 
//Wczytanie modelu tabeli z pliku  
else if(z==ekspo)
{ 
    


}  

}
}




 

W tym miejscu wywołuję klasę zapisz_program, domyślam się, że nie jest to okno główne i na tym polega błąd, ale jak to zmienić?

 // Zamykanie okna
class Zamykanie extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
int answer = JOptionPane.showConfirmDialog(null, "Czy na pewno chcesz zamknąć program", "Koniec", JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION)
{
    new zapisz_program(this);
    dispose();
}   
}
}
0

Tak właściwie to dlaczego klasa zapisz_program dziedziczy po klasie baza oraz przyjmuje ją jako argument?
PS nie nazywaj klas w ten sposób - poczytaj o konwencji nazewnictwa w Javie.

0

Bo robiłem odczyt w ten sam spośób i myślałem, że zapis trzeba zrobić tak samo.. a jak powinno być?

0

A odczyt dlaczego zrobiłeś dziedzicząc? :|

0

Bo modelu tabeli nie da się inaczej odczytać? a Ty jakbyś to zrobił?

0

@Patryk27, zajrzyj tu http://4programmers.net/Forum/Java/264671-laczenie_modelu_bazy_z_zapisanym_plikiem. Może Cię to powstrzyma przed aktywnością w tym wątku.

0

Przez wstrzyknięcie zależności?
Przecież i tak z tego co widzę, to tylko potrzebujesz tego baza mainWindow, aby zrobić mainWindow.baza.getModel(), więc równie dobrze możesz od razu ten model przekazać.
A dziedziczenia w dalszym ciągu nie pojmuję.

0

@bogdans
Tak wczytywanie mam, ale ja chcę zrobić zapis.

0

Nie znam się na Javie, więc się nie wypowiem, ale coś mi nie pasuje w tym programie.

0

@bogdans

package wypozyczalnia_filmow;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
 
public class wczytywanie_przy_otwieraniu
{
    baza mainWindow = null;    
 
    public wczytywanie_przy_otwieraniu(baza mainWindow)
    {   
        this.mainWindow = mainWindow;
        try
        {
            FileInputStream h = new FileInputStream("bazadmina.txt");
            ObjectInputStream obe = new ObjectInputStream(h);
            mainWindow.baza.setModel((DefaultTableModel) obe.readObject());
            mainWindow.model.fireTableDataChanged();
            h.close();
        }
        catch(Exception ex)
        {
            //JOptionPane.showMessageDialog(null,ex.getMessage(),"Czytanie pliku "+"mojabazajestzapisana.txt",JOptionPane.INFORMATION_MESSAGE);
        }    
    }
} 
 /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package wypozyczalnia_filmow;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;



class baza extends JFrame implements ActionListener
{
   
File a;
JButton dodaj,usun,edytuj,impo,ekspo,wyszukaj;
JTable baza;
Object wiersz[][]; //objektreprezentujący wiersz tabeli
DefaultTableModel model;
JFileChooser chooserzapis= new JFileChooser();
JFileChooser chooserodczyt= new JFileChooser();


  
public void  baza()
{
  
    
setTitle("Baza"); //tytuł okna
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 
String kolumna[] = {"Tytuł","Czas trwania","Kategoria","Nośnik","Rok premiery","Opis","Obsada","Reżyser"}; // tytuły kolumn tabeli
model = new DefaultTableModel(wiersz, kolumna); //definiowanie modeu tabeli
baza = new JTable(model);
setLayout(new FlowLayout(FlowLayout.CENTER));
JScrollPane js = new JScrollPane(baza,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
js.setPreferredSize(new Dimension(700,700)); // rozmiar obszaru tabeli
new wczytywanie_przy_otwieraniu(this);




dodaj = new JButton("Dodaj");
usun = new JButton("Usuń");
edytuj=new JButton("Edytuj");
impo=new JButton("Importuj");
ekspo=new JButton("Eksportuj");
wyszukaj=new JButton("Wyszukaj");

add(dodaj);
add(usun);
add(edytuj);
add(impo);
add(ekspo);
add(wyszukaj);
add(js);

dodaj.addActionListener(this);
usun.addActionListener(this);
impo.addActionListener(this);
ekspo.addActionListener(this);
baza.setAutoCreateRowSorter(true);


setSize(1000,1000);
setVisible(true);
WindowListener sluchacz = new Zamykanie();
addWindowListener(sluchacz);
   
}

// Zamykanie okna
class Zamykanie extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
int answer = JOptionPane.showConfirmDialog(null, "Czy na pewno chcesz zamknąć program", "Koniec", JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION)
{
    
    new zapisz_program(this);
    dispose();
}   
}
}




@Override
public void actionPerformed(ActionEvent e) {

Object z=e.getSource(); // Stworzenie obiektu, który jest źródłem sygnału

      
 if(z==dodaj)
{
    
formularz_dodawania_filmow y= new formularz_dodawania_filmow(baza.this);
   
}
    
else if(z==usun)
{
    
model = (DefaultTableModel) baza.getModel();
model.removeRow(baza.getSelectedRow());
}

else if(z==edytuj)
    
{    
    
    
    
}

//Zapis tabeli do pliku
 else if(z==impo)
 {
   
 }

 
//Wczytanie modelu tabeli z pliku  
else if(z==ekspo)
{ 
    


}  

}
}






Podkreśla this tutaj: i nie wiem dlaczego.

new zapisz_program(this); 

Jest napisane, że zamykanie nie może być konwertowane na baza

0

ref

1

Pomaganie Tobie, to syzyfowa praca - Ty nic z Javy nie rozumiesz. A na dodatek fatalnie formatujesz kod i niezgodnie z konwencją nazywasz klasy - co bardzo utrudnia czytanie kodu.

   class Zamykanie extends WindowAdapter
   {
      public void windowClosing(WindowEvent e)
      {
          int answer = JOptionPane.showConfirmDialog(null, "Czy na pewno chcesz zamknąć program", "Koniec", JOptionPane.YES_NO_OPTION);
          if (answer == JOptionPane.YES_OPTION)
          {
              new zapisz_program(this);
              dispose();
          }   
      }
  }
  1. Nadal próbujesz zakończyć program wywołaniem metody dispose. To nie zakończy programu, jeżeli jest otwarte okno formularza dopisywania.
  2. W wierszu
new zapisz_program(this);

słowo this oznacza ten obiekt klasy wewnętrznej Zamykanie, a nie ten obiekt klasy zewnętrznej baza. Zamień nanew zapisz_program(baza.this);

0

Wszystko działa, dzięki .. Mam jeszcze jedno pytanie czy w ten sam sposób mogę wywołać np odczyt w innej klasie czy muszę stworzyć nową klasę odczyt skierowaną specjalnie pod tą klasę w której chcę wyświetlić?

0

Pokaż jak to aktualnie zrobiłeś.

0

@Patryk27

package wypozyczalnia_filmow;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
 
public class wczytywanie_przy_otwieraniu
{
baza mainWindow = null;    
 
public wczytywanie_przy_otwieraniu(baza mainWindow)
{   
this.mainWindow = mainWindow;
try
{
    FileInputStream h = new FileInputStream("bazadmina.txt");
    ObjectInputStream obe = new ObjectInputStream(h);
    mainWindow.baza.setModel((DefaultTableModel) obe.readObject());
    mainWindow.model.fireTableDataChanged();
    h.close();
}
catch(Exception exe)
{
   JOptionPane.showMessageDialog(null,exe.getMessage(),"Zapisywanie do pliku "+"bazadmina.txt",JOptionPane.INFORMATION_MESSAGE);
}    
}
} 

Wywołanie a zapis analogicznie i wywołanie jak na górze podał bogdans

new wczytywanie_przy_otwieraniu(this); 
0

Separation of concerns - klasy odpowiedzialna za ładowanie nie powinny obchodzić części GUI... ani za bardzo inne części niezwiązane z wczytywaniem.

Ja napisałbym to tak:

public class MyBestFileLoader {

	public static SomeModel load(String fileName) {
		FileInputStream fileStream = new FileInputStream(fileName);
		ObjectInputStream objectStream = new ObjectInputStream(fileStream);
		
		SomeModel model = null;
		
		try {
			model = objectStream.readObject(); // jeśli istnieje JAKAKOLWIEK szansa na to, że readObject() zwróci null - tutaj powinno to być odpowiednio obsłużone (!)
			model.fireTableDataChanged();
		} finally {
			fileStream.close();
		}
		
		return model;
	}
	
	public static SomeModel loadAdminDatabase() {
		return MyBestFileLoader.load("baza-admina.txt");
	}
}

Zwróć uwagę na:

  1. Wykorzystanie metod statycznych.
  2. Blok try...finally.
  3. Nazewnictwo (w tym zmienne lokalne!).
  4. Formatowanie.
  5. Metoda wczytująca zwraca gotowy do działania model ALBO rzuca wyjątek. Obsługa wyjątku nie jest procesem wczytywania i nie powinna mieć miejsca w klasie odpowiedzialnej za wczytywanie. Istnieje za to wzorzec projektowy fasada, który mógłbyś tutaj wykorzystać, aby mieć wczytywanie połączone z obsługą błędów, ale to już zostawiam Tobie ;)

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