[Pliki] Problem z czytaniem z pliku

0

Witam,
Wiele czasu spędziłem na tym forum aby nauczyć się programować a teraz sam znalazłem się w kropce. Chodzi o to że potrzebuję przeczytać plik tekstowy a następnie narysować go na wykresie. Wszystko ładnie pięknie działało ale się popsuło gdy utworzyłem funkcję ReadFile(). Czy mógłby mi ktoś pomóc oraz wyjaśnić gdzie mam błąd (w miarę możliwości ponieważ chcę zrozumieć swój błąd a nie tylko napisać program). Kod źródłowy zamieszczam poniżej :

package cw;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.*;
import javax.swing.border.*;

import org.jfree.chart.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class przyciski extends JFrame implements WindowListener, ActionListener, MouseListener{
	
	private static final long serialVersionUID = 1L;
	
	JLabel From_label      = new JLabel("<HTML><font size=28>From</font></HTML>"),
		   To_label        = new JLabel("<HTML><font size=28>to</font></HTML>"),
		   Integrate_label = new JLabel("<HTML><font size=28>Integrate = </font></HTML>"),
		   Start_label = new JLabel("<HTML><font size=4>How many started lines in file I shouldn't read</font></HTML>"),
		   Stop_label = new JLabel("<HTML><font size=4>How many endeded lines in file I should't read</font></HTML>");
	
	JFileChooser choose_file = new JFileChooser();
	
	XYSeries series = new XYSeries("Spectrum");
	XYSeriesCollection dataset = new XYSeriesCollection();
	JFreeChart chart;
	
	JButton exit      = new JButton("EXIT"),
		    draw      = new JButton("Draw chart"),
		    Open_file = new JButton("Open File"),
		    del       = new JButton("Clear chart"),
			Calculate = new JButton("Calculate");
	
	JComboBox XPoints = new JComboBox(),
		      YPoints = new JComboBox();
	
	JTextField From       = new JTextField(),
			   To         = new JTextField(),
			   Integrate  = new JTextField(),
			   Line_start = new JTextField(),
			   Line_end   = new JTextField();
			   
	JPanel window_panel        = new JPanel(),
		   menu_panel          = new JPanel(),
		   chart_panel         = new JPanel(),
		   menu_open_dir       = new JPanel(),
		   menu_list_of_points = new JPanel(),
		   menu_buttons        = new JPanel();
	
	JFileChooser fc = new JFileChooser();
	
	TitledBorder menu_panel_border,chart_panel_border;
	
	File file;
	
	static double X[];

	static double Y[];
	
	public przyciski(){
		
		//=========================DEKLARACJA WYGLADU OKNA===========================//
		super();
		setTitle("Całkowanie");
		setSize(1000,600);
		setVisible(true);
		
		window_panel.setLayout(new BoxLayout(window_panel, BoxLayout.LINE_AXIS));
		window_panel.setPreferredSize(new Dimension(1000,600));
		this.add(window_panel);
		window_panel.add(menu_panel);
		
		menu_panel.add(menu_open_dir);
		menu_panel.add(menu_list_of_points);
		menu_panel.add(menu_buttons);
		menu_panel_border = BorderFactory.createTitledBorder("Menu");
		menu_panel.setBorder(menu_panel_border);
		menu_panel.setLayout(new BoxLayout(menu_panel, BoxLayout.Y_AXIS));
		menu_panel.setPreferredSize(new Dimension(400,600));
		window_panel.add(chart_panel);
		
		chart_panel_border = BorderFactory.createTitledBorder("Chart");
		chart_panel.setBorder(chart_panel_border);
		chart_panel.setPreferredSize(new Dimension(600,600));
		chart_panel.setLayout(new GridLayout(1,1));
		
		//==============KONIEC DEKLARACJI WYGLąDU PANELU==================//
		
		//==============DODAWANIE KOMPONENTÓW DO PANELU===================//
		
		From.setEditable(true);
		
		To.setEditable(true);
		
		Integrate.setEditable(false);
		
		JFreeChart chart = ChartFactory.createXYLineChart(
							"Preview",
							"Lambda",
							"Intensivity [au]",
							dataset,
							PlotOrientation.VERTICAL,
							true,
							true,
							false);
		
		ChartPanel panel = new ChartPanel(chart);
		panel.setSize(600,800);
		chart_panel.add(panel);
		
		menu_buttons.setLayout(new GridLayout(7,2));
		menu_buttons.setPreferredSize(new Dimension(400,400));
		menu_buttons.add(draw);
		menu_buttons.add(del);
		menu_buttons.add(From_label);
		menu_buttons.add(To_label);
		menu_buttons.add(From);
		menu_buttons.add(To);
		menu_buttons.add(Integrate_label);
		menu_buttons.add(Integrate);
		menu_buttons.add(Calculate);
		menu_buttons.add(exit);
		
		menu_open_dir.setLayout(new GridLayout(1,1));
		menu_open_dir.setPreferredSize(new Dimension(400,100));
		menu_open_dir.add(Open_file);
		
		menu_list_of_points.setPreferredSize(new Dimension(400,200));
		menu_list_of_points.setLayout(new GridLayout(3,2));
		menu_list_of_points.add(Start_label);
		menu_list_of_points.add(Stop_label);
		menu_list_of_points.add(Line_start);
		menu_list_of_points.add(Line_end);
		menu_list_of_points.add(XPoints);
		menu_list_of_points.add(YPoints);
		
		Open_file.addActionListener(this);
		
		Calculate.addActionListener(this);
		
		draw.addActionListener(this);
		
		del.addActionListener(this);
		
		exit.addActionListener(this);
		
		//menu_panel.add(exit);
		//menu_panel.add(draw);
		
		setVisible(true);
	}
	
	public void ClearChart(){
		
		dataset.removeAllSeries();
	}
	
	public void DrawChart(){
		
		int k;
		k = X.length;
		for (int i=0; i<k; i++){
			series.add(X[i], Y[i]);
		}
		dataset.addSeries(series);
		
	}
	
	@Override
	public void windowActivated(WindowEvent arg0) {
		
	}

	@Override
	public void windowClosed(WindowEvent arg0) {
		
	}

	@Override
	public void windowClosing(WindowEvent arg0) {
		dispose();
	}

	@Override
	public void windowDeactivated(WindowEvent arg0) {
		
	}

	@Override
	public void windowDeiconified(WindowEvent arg0) {
		
	}

	@Override
	public void windowIconified(WindowEvent arg0) {
		
	}

	@Override
	public void windowOpened(WindowEvent arg0) {
		
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		
		String command = e.getActionCommand();
		if(command.equals("EXIT")){
			dispose();
		}
		if(command.equals("Open File")){
			showDialog();
			try{
				ReadFile();
			}catch(IOException ex){}
		}
		if(command.equals("Clear chart")){
			ClearChart();
		}
		if(command.equalsIgnoreCase("Draw chart")){
			DrawChart();
		}
	}
	
	public void showDialog(){
		int returnVal = fc.showOpenDialog(przyciski.this);
		
		if (returnVal == JFileChooser.APPROVE_OPTION)
		file = fc.getSelectedFile();
	}
	
	public void ReadFile() throws IOException{
		@SuppressWarnings("unused")
		String rubbish = null;
		int i=0;
		Reader br = new BufferedReader(new FileReader(file.toString()));
		StreamTokenizer stok = new StreamTokenizer(br);
	    stok.parseNumbers();
	    stok.nextToken();
	    
	    while(stok.ttype != StreamTokenizer.TT_EOF){
	    	i++;
	    	if(stok.ttype != StreamTokenizer.TT_NUMBER){
	    		X[i] = stok.nval;
	    		Y[i] = stok.nval;
	    	}
	    	else{
	    		rubbish = "nonumber";
	    	}
	    }
		
	}
	
	@Override
	public void mouseClicked(MouseEvent arg0) {
		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		
	}

	public void mouseExited(MouseEvent arg0) {
		
	}

	public void mousePressed(MouseEvent arg0) {
		
	}

	public void mouseReleased(MouseEvent arg0) {
		
	}
	
	public static void main(String arg[]){
		
		@SuppressWarnings("unused")
		przyciski okno = new przyciski();
		
	}
}

A tutaj zamieszczam widok z konsoli błędów :

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at cw.przyciski.ReadFile(przyciski.java:249)
	at cw.przyciski.actionPerformed(przyciski.java:217)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$2.run(Unknown Source)
	at java.awt.EventQueue$2.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at cw.przyciski.DrawChart(przyciski.java:164)
	at cw.przyciski.actionPerformed(przyciski.java:224)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$2.run(Unknown Source)
	at java.awt.EventQueue$2.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

Plik który chcę przeczytać załączam.

Z góry dziękuje za pomoc i szybką odpowiedź
Z poważaniem
Etherlord

PS. To nie jest żadna praca zaliczeniowa mimo że są to dane z labolatorium - to jest program pisany aby się czegoś więcej nauczyć dla hobby

0
  1. Prawie na pewno plik tekstowy ma niewłaściwą budowę.
  2. Źle obsługujesz kliknięcie w przycisk zamykający okno - u Ciebie to kliknięcie nie kończy programu. Są dwie możliwości naprawy, pierwsza, to wyrzucić całego WindowListenera i dodać w konstruktorze wiersz:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Druga, zamienić w metodzie windowClosing() dispose(); na System.exit(0);

1

Dopiero teraz zauważyłem, że dostarczyłeś dane. Błąd jest w czytaniu:

  1. Dlaczego jest:
if(stok.ttype != StreamTokenizer.TT_NUMBER)
//powinno być
if(stok.ttype == StreamTokenizer.TT_NUMBER)

,
2. Dlaczego tylko raz jest wywołana metoda nextToken()?
3. Dlaczego jest

    X[i] = stok.nval;
    Y[i] = stok.nval;

X[i] to chyba jest pierwsza liczba w wierszu, a Y[i] druga.

0

Odpowiedzi na pierwszy post :

  1. Plik ma taką budowę jak załączyłem. Po prostu się zastanawiałem jak takie coś odczytać. Po drugie zdecydowałem się że użytkownik będzie podawał ilość linijek które chce opuścić na początku pliku oraz na końcu pliku.
    2.Na zajęciach z javy (jakiś rok temu) obniżali mi ocenę za używanie metody System.exit(0); tylko dispose();. Więc w sumie dispose używam z przyzwyczajenia. Już poprawiłem metodę WindowClosing tak jak mi poradziłeś.

Odpowiedzi na drugi post :

  1. Wiem głupi błąd który nie powinien mi się przytrafić.
    2&3. Więc metodę nextToken() powinienem wywoływać przy każdej nowej liczbie. Więc powinienem napisać mniej więcej coś takiego :
While(stok.ttype != StreamTokenizer.TT_EOF){
     
     X[i]=stok.sval;               // Zmieniłem ponieważ w pliku są przecinki i będę musiał je jakoś zamienić na kropki jednak na to już znajdę metodę
     stok.nextToken();
     Y[i]=stok.sval;
     stok.nextToken();
     i++
}

Czy mam rację ? Oczywiście tablicę X i Y przerobię na Stringi a potem będę na nich przeprowadzał operację w celu możliwości rzutowania wartości na double.

0

Twoje rozwiązanie ma dwie poważne wady.

  1. Używasz tablic do przechowywania liczb, nie wiesz przecież ile liczb wystąpi w pliku i jak duże tablice są potrzebne.
  2. StreamTokenizer nie da się "zlokalizować", stąd problemy z przecinkami w liczbach. Pomysł by czytać Stringi, a potem je przerabiać raczej nie zadziała: albo zostawisz wywołanie stock.parseNumbers() i wtedy wszystkie dane pominięte zostaną (a wczytane zostaną pewne liczby z nagłówka), albo wyrzucisz to wywołanie i będziesz jakoś tam pomijał nagłówek i stopkę.
    Moja propozycja:
ArrayList<Double> X=new ArrayList<Double>();
ArrayList<Double> Y=new ArrayList<Double>();
...                
try
{
    Scanner scanner=new Scanner(file);
                
    while(scanner.hasNextLine())
    {
         Scanner scan=new Scanner(scanner.nextLine());
         scan.useLocale(new Locale("pl","PL"));
         if(scan.hasNextDouble()) //wiersz zaczyna sie od liczby
         {
              X.add(scan.nextDouble());
              Y.add(scan.nextDouble());
         }                    
    }
}
catch(Exception e)
{
    System.out.println(e);
}
0

Powinienes też zmienić metodę DrawChart

public void DrawChart()
{
    for (int i=0; i<X.size(); i++)
    {
         series.add(X.get(i), Y.get(i));
    }
    dataset.addSeries(series);
}

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