2016-11-24 2 views
1

GUIからこのファイルを開く方法を調べるのに1時間かかるのですが、ファイルをクリックしてファイルをクリックするたびにGUIを開きますクラッシュします。ここでは、私のコードは何か間違って教えてください。 これは私に与えられたものなので、間違ってはいけません。JavaオープニングファイルGUIからの不揃いのアレイの倍数

import java.io.File; 
import java.io.FileNotFoundException; 
import java.text.NumberFormat; 

import javafx.application.Application; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.Tooltip; 
import javafx.stage.FileChooser; 
import javafx.stage.Stage; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 
import javafx.scene.text.Font; 

public class MvGuiFx extends Application {; 
    private double[][] sales; 
    public static final int MAX_STORES = 6; 
    public static final int MAX_ITEMS = 6; 
    private NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(); 
    Button readFileBtn, exitBtn; 
    GridPane dataPane; 


    /** 
    * Lets the user choose a file to read the sales information and displays 
    * the information on the screen 
    * @throws FileNotFoundException 
    */ 
    public void readFile() throws FileNotFoundException { 
     File selectedFile; 

     FileChooser chooser = new FileChooser(); 
     chooser.setTitle("Choose a file to read retail items' sales information"); 
     if ((selectedFile = chooser.showOpenDialog(null)) != null) { 
      // Read the file 
      sales = TwoDimRaggedArrayUtility.readFile(selectedFile); 
     } 
     //display on the screen 
     int row,col; 
     double total; 
     for(row=0;row<sales.length; row++) 
      for(col=0;col<sales[row].length;col++) 
       dataPane.add(new TextField(currencyFormat.format(sales[row][col])),col+1,row+1); 

     //display row totals 
     for(row=0;row<sales.length;row++) 
     { 
      total = TwoDimRaggedArrayUtility.getRowTotal(sales, row); 
      dataPane.add(new TextField(currencyFormat.format(total)), 7, row+1); 
     } 

     //find the row with largest number of columns 
     int columns = 0; 
     for(row=0;row<sales.length;row++) 
      if(sales[row].length > columns) columns = sales[row].length; 

     //display column totals 
     for(col=0;col<columns;col++) 
     { 
      total = TwoDimRaggedArrayUtility.getColumnTotal(sales, col); 
      dataPane.add(new TextField(currencyFormat.format(total)), col+1, 7); 
     } 

     //find highest in each column 
     for(col=0;col<columns;col++) 
     { 
      total = TwoDimRaggedArrayUtility.getHighestInColumn(sales, col); 
      TextField temp = new TextField(currencyFormat.format(total)); 
      temp.setStyle("-fx-background-color: gray;"); 
      for(row=0;row<sales.length;row++) { 
       if(col < sales[row].length){ 
        if(sales[row][col]==total) 
         dataPane.add(temp, col+1, row+1); 
       } 
      } 
     } 


} 

    // Handler class. 
    private class ButtonEventHandler implements EventHandler<ActionEvent> { 
     @Override 
     public void handle(ActionEvent e) { 
      //handler for Load Sales Data 
      if (e.getSource() == readFileBtn) { 

       try { 
        readFile(); 
       } catch (FileNotFoundException e1) { 
        e1.printStackTrace(); 
       } 

      //handler for Exit button 
      } else if (e.getSource() == exitBtn) 

       System.exit(0); 
     } 
    } 

    @Override 
    public void start(Stage stage) { 

     Tooltip buttonToolTipArr[] = new Tooltip[5]; 
     buttonToolTipArr[0] = new Tooltip(
       "Load sales data from a file and Display"); 
     buttonToolTipArr[1] = new Tooltip("Exit Application"); 

     // Main Pane 
     BorderPane MainPane = new BorderPane(); 

     // Create Title Pane, add title label and add it to the top of the Main 
     // Pane 
     HBox titlePanel = new HBox(); 
     titlePanel.setAlignment(Pos.BASELINE_CENTER); 
     Label titleLbl = new Label("DisneyWorld District 5 Sales Report\n"); 
     titleLbl.setFont(new Font(30)); 
     titleLbl.setTextFill(Color.BLUE); 

     titlePanel.getChildren().add(titleLbl); 
     MainPane.setTop(titlePanel); 

     // CenterPane 
     VBox centerPane = new VBox(); 
     centerPane.setAlignment(Pos.CENTER); 

     // columnHeader Pane 
     HBox columnHeaderPane = new HBox(10); 
     columnHeaderPane.setAlignment(Pos.CENTER); 


     int i,j; 
     dataPane = new GridPane(); 
     dataPane.setAlignment(Pos.BASELINE_CENTER); 
     dataPane.add(new Label("  "), 0, 0); 
     dataPane.add(new Label("Books"), 1, 0); 
     dataPane.add(new Label("Tsum Tsum"), 2, 0); 
     dataPane.add(new Label("Trading Pins"), 3, 0); 
     dataPane.add(new Label("Star Wars"), 4, 0); 
     dataPane.add(new Label("Lego"), 5, 0); 
     dataPane.add(new Label("Marvel"), 6, 0); 
     dataPane.add(new Label("Total"), 7, 0); 

     for(i=1;i<8;i++) 
     { 
      dataPane.add(new Label("  "), 0,i); 
      for(j = 1; j<8;j++) 
       dataPane.add(new TextField(), i,j); 
     } 


     dataPane.add(new Label("Emporium"), 0, 1); 
     dataPane.add(new Label("World Traveler"), 0, 2); 
     dataPane.add(new Label("Discovery Trading Center"), 0, 3); 
     dataPane.add(new Label("Merchant of Venus"), 0, 4); 
     dataPane.add(new Label("Once Upon a Toy"), 0, 5); 
     dataPane.add(new Label("Tatooine Traders"), 0, 6); 
     dataPane.add(new Label("Total"), 0, 7); 

     // Create bottom Pane 
     HBox bottomPane = new HBox(10); 
     bottomPane.setAlignment(Pos.BASELINE_CENTER); 

     // Create buttons 
     readFileBtn = new Button("Load Sales Data"); 
     readFileBtn.setTooltip(buttonToolTipArr[0]); 
     exitBtn = new Button("Exit"); 
     exitBtn.setTooltip(buttonToolTipArr[1]); 

     // add event handler to buttons 
     readFileBtn.setOnAction(new ButtonEventHandler()); 
     exitBtn.setOnAction(new ButtonEventHandler()); 

     // add buttons to bottomPane 
     bottomPane.getChildren().addAll(readFileBtn, exitBtn); 
     MainPane.setBottom(bottomPane); 

     // add panes to center pane 
     centerPane.getChildren().addAll(dataPane); 

     MainPane.setCenter(centerPane); 

     Scene scene = new Scene(MainPane, 1200, 400); 
     stage.setScene(scene); 

     // Set stage title and show the stage. 
     stage.setTitle("District Sales Report"); 
     stage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

相続人は、私がこれまでにしたもの:

import java.io.PrintWriter; 
import java.util.Scanner; 

public class TwoDimRaggedArrayUtility { 

    public TwoDimRaggedArrayUtility() 
    { 

    } 

    public static double[][] readFile(java.io.File file) throws java.io.FileNotFoundException 
    { 

     Scanner scan = new Scanner(file); 
     int row = 0; 

     while(scan.hasNextLine()) 
     { 
      row++; 
     } 

     double[][] array = new double[row][]; 

     for(int index = 0; index < array[0].length; index++) 

       array[0] = new double[index]; 

     for(int index = 0; index < array[1].length; index++) 

       array[1] = new double[index]; 

     for(int index = 0; index < array[2].length; index++) 

       array[2] = new double[index]; 

     for(int index = 0; index < array[3].length; index++) 

       array[3] = new double[index]; 

     for(int index = 0; index < array[4].length; index++) 

       array[4] = new double[index]; 

     for(int index = 0; index < array[5].length; index++) 

       array[5] = new double[index]; 

     for(int index = 0; index < array[6].length; index++) 

       array[6] = new double[index]; 

     for(int index = 0; index < array[7].length; index++) 

       array[7] = new double[index]; 

     for(int index = 0; index < array[8].length; index++) 

       array[8] = new double[index]; 

     for(int index = 0; index < array[9].length; index++) 

       array[9] = new double[index]; 

     for(int index = 0; index < array[10].length; index++) 

       array[10] = new double[index]; 

     scan.close(); 

     return array; 
    } 

    public static void writeToFile(double[][] data, java.io.File outputFile)throws java.io.FileNotFoundException 
    { 
     PrintWriter print = new PrintWriter(outputFile); 
     print.print(data); 
     print.close(); 
    } 

そして、ここでは、.txtファイルぼろぼろの配列です:私は正直に言うつもりです

1253.65 4566.50 2154.36 7532.45 3388.44 6598.23 
2876.22 3576.24 1954.66 
4896.23 2855.29 2386.36 5499.29 
2256.76 3623.76 4286.29 5438.48 3794.43 
3184.38 3654.65 3455.76 6387.23 4265.77 4592.45 
2657.46 3265.34 2256.38 8935.26 5287.34 

答えて

1

、間違った公平なビットがありますあなたのコードで。

GUIの使用を避けることをお勧めします。あなたはTwoDimRaggedArrayUtilityに次のmainメソッドを追加した場合は、GUIを起動することなく、このクラスを直接実行することができます。

public static void main(String[] args) throws Exception { 
    double[][] sales = readFile(new java.io.File("path/to/your/file")); 
    for (double[] row : sales) { 
     System.out.println(java.util.Arrays.toString(row)); 
    } 
} 

すべてが順調であれば、それはあなたのファイルを読み込み、その内容をプリントアウトする必要があります。

まず、コードがあまりクラッシュしない(つまり、厄介なエラーで停止する)、実際にはハングします(何もしていないと思われます)。

は、このループを見てとることで起動するのをしてみましょう:これは

while(scan.hasNextLine()) 
    { 
     row++; 
    } 

何をしますか?

答えは次のとおりです。スキャナに次の行がありますが、rowに1を加えてください。

スキャナからどのラインも読み取らないことに注意してください。したがって、スキャナにテキストが全くない場合、このループは永久に実行され、無限にrowをインクリメントします。

スキャナからラインを読み取るには、nextLine()メソッドを呼び出します。スキャナで作業する場合は、そのデータを読み取る前にそこにデータがあるかどうかチェックするのが一般的です。だから私たちは今持っている:

while (scan.hasNextLine()) { 
     String line = scan.nextLine(); 
     row++; 
    } 

私たちはあなたのコードにこの変更を加えると、それ以上ハングしません。ファイルからすべての行を読み込みます。しかし、それは、この行にNullPointerExceptionをスロー:

for (int index = 0; index < array[0].length; index++) 

、我々は前の行を見てみる必要がある理由を理解するには:

double[][] array = new double[row][]; 

これは何をしますか? whileループを終了した後、の値でrowが終了するため、6つの要素の配列が作成されます。ただし、内部配列のサイズを指定していないため、配列内の各要素(つまり各 'inner'配列)はnullです。したがって、これらの配列の長さを読み取ろうとすると、長さを読み取る配列がないため、NullPointerExceptionが返されます。

これを脇に置いて、array[0].lengthが返します。たとえば、4とします。

for (int index = 0; index < array[0].length; index++) 

     array[0] = new double[index]; 

ここでの問題は、(indexゼロで)このループの最初の繰り返しは、空の配列であることをarray[0]を設定していることです:私たちは、その後、4回を実行するには、次のループを期待するかもしれません。次回のループindexは1ですが、array[0].lengthは0になるため、ループは終了します。

このループは、まったく実行できなかった場合には一度だけ実行され、doubleの空の配列が作成され、array[0]に格納されます。このループとそのような他の10個のループは保存する価値がありませんので、すべて削除しましょう。

のは、一番上に戻っwhileループへ行こう:

while (scan.hasNextLine()) { 
     String line = scan.nextLine(); 
     row++; 
    } 

我々はまだlineが読み込まれていると何もしていない私たちは、それの中の数字にそれを分割し、それらを読みたいです。すべてでは現時点では、我々が行にファイルを分割するためにスキャナを使用している、と私たちは実際には数に行を分割するために、別のスキャナを使用することができます。

while (scan.hasNextLine()) { 
     String line = scan.nextLine(); 

     int column = 0; 
     Scanner doubleScanner = new Scanner(line); 
     while (doubleScanner.hasNextDouble()) { 
      double value = doubleScanner.nextDouble(); 
      column++; 
     } 

     row++; 
    } 

注意私がきた5行こと挿入されるのは、while我々が始めたループ。私たちは、読書する前にdouble-scannerから読み取る別のdoubleがあるかどうかをチェックします。これは、読書のときと同じです。

これが私たちをもっと近づけています。ただし、ラインスキャナからdoubleの値を読み取っていますが、まだどこにでも保存していません。

残念ながら、これはここで少しばかげています。 Javaの配列は、一度作成するとサイズを変更できないという柔軟性がありません。配列を大きくまたは小さくする場合は、目的のサイズの新しい配列を作成し、その値をコピーする必要があります。簡単にするために、実際のプロダクションコードではなくクラス割り当てのように見えるので、最大10行10列と仮定しましょう。したがって、我々は次のように私たちのコードを修正して、配列内の値を格納することができます:

double[][] array = new double[10][10]; 
    while (scan.hasNextLine()) { 
     String line = scan.nextLine(); 
     int column = 0; 
     Scanner doubleScanner = new Scanner(line); 
     while (doubleScanner.hasNextDouble()) { 
      array[row][column] = doubleScanner.nextDouble(); 
      ++column; 
     } 

     row++; 
    } 

私は配列を作成するために、1行を追加し、doubleScannerのうち、double Sを読み込み、行を調整してきました。 new double[10][10]は10個の配列の配列であり、各内部配列は10個の要素を持ち、最初はすべて0に設定されています。

この時点で、コードを実行して出力を表示できるようになりました。しかし、結果は、行と列が10で10になるようにゼロで埋められているという点で、私たちが望むものではありません。おそらく、これを修正する最も簡単な方法は、Arrays.copyOfRange()メソッドを使用して、関心のある配列の部分のみのコピーを作成し、元のものをコピーに置き換えることです。私たちは、アレイ全体のために一度行ごとに一度これを行う、とする必要があります。

double[][] array = new double[10][10]; 
    while (scan.hasNextLine()) { 
     String line = scan.nextLine(); 
     int column = 0; 
     Scanner doubleScanner = new Scanner(line); 
     while (doubleScanner.hasNextDouble()) { 
      array[row][column] = doubleScanner.nextDouble(); 
      ++column; 
     } 

     array[row] = java.util.Arrays.copyOfRange(array[row], 0, column); 
     row++; 
    } 

    array = java.util.Arrays.copyOfRange(array, 0, row); 

最後に、これは、任意のパディングゼロなしで、我々が望んでいたデータを返します。

これは(疑わしい)クラス割り当てなので、このコードの動作とその動作を理解してください。ソフトウェアでは、理解が重要です。それが何を理解することなく、インターネットから盲目的にコードをコピーすることは決してありません。