所以我花了一个小时试图弄清楚如何从GUI打开这个文件,但每次我点击打开文件并点击我要打开的文件时,我的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
答案 0 :(得分:1)
我说实话,你的代码有点不对。
首先,你最好完全避免使用GUI。如果将以下main
方法添加到TwoDimRaggedArrayUtility
,则可以直接运行此类而无需启动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
中添加一行。
请注意,您在任何时候都不会从扫描仪中读取任何行。因此,如果扫描仪中有任何文本,此循环将永远运行,无休止地增加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][];
这是做什么的?它创建了一个包含6个元素的数组,因为row
在完成6
循环后最终得到值while
。但是,数组中的每个元素(即每个&#39;内部数组&#39;)都是null
,因为您还没有为内部数组指定大小。因此,当您尝试读取其中一个数组的长度时,会得到一个NullPointerException
,因为没有数组可以读取它的长度。
暂时搁置一下,假设array[0].length
返回,比如4
。然后我们可能期望以下循环运行四次:
for (int index = 0; index < array[0].length; index++)
array[0] = new double[index];
这里的问题是这个循环的第一次迭代(index
为零)然后将array[0]
设置为空数组。下一次循环index
为1,但array[0].length
现在为0,因此循环结束。
这个循环并不是非常有用,因为它只运行一次,如果我们能够运行它,它只是创建一个double
的空数组并将其放入{ {1}}。这个循环,以及其他十个循环,都不值得保留,所以让我们全部删除它们。
让我们回到顶部的array[0]
循环:
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++;
}
循环类似。在我们读出之前,我们检查是否还有另外while
从双打扫描仪中读出来,就像我们在阅读线条时所做的那样。
这让我们更加接近。但是,虽然我们现在正在从线扫描仪中读取double
值,但我们仍然没有将它们存储在任何位置。
不幸的是,这是事情在这里变得有点繁琐的地方。 Java的阵列是不灵活的,因为一旦你创建了它们,你就无法改变它们的大小。如果要使数组更大或更小,则必须创建所需大小的新数组并复制值。为了简单起见,并且因为这看起来像是一个类赋值而不是实际的生产代码,所以我们假设最多有10行和10列。因此,我们可以通过修改代码将值存储在数组中:
double
我添加了一行来创建数组,并调整了从 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++;
}
中读取double
的行。请注意,doubleScanner
是一个包含10个数组的数组,每个内部数组都有10个元素,最初都设置为零。
此时我们现在应该可以运行代码并让它显示一些输出。但是,结果并不是我们想要的,因为行和列用零填充以使它们达到10×10。解决此问题的最简单方法可能是使用Arrays.copyOfRange()
方法仅创建我们感兴趣的数组部分的副本,并将副本替换为副本。我们需要为每一行执行一次,对整个数组执行一次:
new double[10][10]
最后,这将返回我们想要的数据,没有任何填充零。
由于这是(疑似)课程作业,请花时间了解此代码的作用及其工作原理。使用软件,理解很重要。切勿盲目地将代码从互联网上复制而不了解它的作用。