如何使用特定格式的 JTextField 编辑 txt 文件?

How to edit a txt file using JTextField with a specific format?

我正在创建一个涉及收银员和管理员模式的库存程序。管理员模式可以更改商品的商品名称、价格和库存。所有项目都存储在一个 txt 文件中。

txt 文件的内容(用斜杠分隔名称、价格等):

 ID     Item Name                 Price   Stocks
00001 / Xbox 360                 / 7999  / 10
00002 / Xbox Series X            / 25999 / 20
00003 / Playstation 4 Pro        / 22999 / 15
00004 / Nintendo Switch          / 17999 / 27
00005 / Nintendo Switch Lite     / 11999 / 15

我使用 JTable 读取和显示项目。 headers列添加到代码中:

String filePath = "C:\Users\zagad\IdeaProjects\DATABYTES\stock\consoles\consoles.txt";
                File file = new File(filePath);
                try {
                    BufferedReader br = new BufferedReader(new FileReader(file));
                    DefaultTableModel model = (DefaultTableModel) productTable.getModel();
                    Object[] tableLines = br.lines().toArray();

                    for (int i = 0; i < tableLines.length; i++) {
                        String line = tableLines[i].toString().trim();
                        String[] dataRow = line.split("/");
                        productTable.getColumnModel().getColumn(0).setPreferredWidth(21);
                        productTable.getColumnModel().getColumn(1).setPreferredWidth(120);
                        productTable.getColumnModel().getColumn(2).setPreferredWidth(30);
                        productTable.getColumnModel().getColumn(3).setPreferredWidth(30);
                        model.addRow(dataRow);
                    }

这是布局的参考图片:

它有一个 JTable 和四个 JTextField。有没有什么想法可以直接编辑 txt 文件,用户从 JTextFields 输入的内容以及 txt 文件中项目的相应位置?

如有任何想法,我们将不胜感激。谢谢!

因为您的文件数据行(数据记录)以具有各种间距的特定方式格式化,所以您应该在读取列状数据时删除任何前导或尾随白色-spaces放在 JTable 中。目前,您将每个数据文件行拆分为:

String[] dataRow = line.split("/"); 

这不会删除所有白色-space 填充,该填充应用于在格式化并保存到文件时放置在该数据上的每一列数据。当您实际需要使用该数据时,将需要处理(删除)此填充。最好在执行拆分时删除所有这个 white-space 填充,如下所示:

String[] dataRow = line.split("\s{0,}/\s{0,}");

关于您的特定应用程序真正包含的内容,例如数据类型(尽管大多数是显而易见的)、已经创建的内容(classes、member/instance 变量、字段,静态等),用于将数据从 JTable 保存到文件等的代码,等等。因此,这使整个作品对假设或 101 个问题开放,我特别不会问这些问题。因此,我在下面展示的代码将是基本的,更适合控制台风格的库存系统,而不是 GUI 风格的系统。您需要将代码应用到您认为合适的应用程序的特定区域。

首先,您需要 class。由于每个库存项目都包含特定属性,例如 ID项目名称价格Quantity(在 Stock 中),您需要一种方法将此数据保存在内存中,以便可以以可以快速获取和操作任何数据的方式使用它。您的 class 可能如下所示:

public class InventoryItems {

    private String id;
    private String itemName;
    private double price;
    private int quantity;

    public InventoryItems() {    }

    public InventoryItems(String id, String itemName, double price, int quantity) {
        this.id = id;
        this.itemName = itemName;
        this.price = price;
        this.quantity = quantity;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    @Override
    public String toString() {
        return new StringBuffer("").append("ID: ").append(id).append(", Item Name: ")
                                   .append(itemName).append(", Price: $").append(price)
                                   .append(", Quantity: ").append(quantity).toString();
    }

    /**
     * Returns instance data as a String in the format specified in your supplied 
     * format string.
     * 
     * @param formatString
     * @return
    */
    public String toString(String formatString) {
        if (formatString == null || formatString.equals("")) {
            return toString();
        }
        // String Format Specifiers must be separated 
        // with a single white-space.
        switch (formatString.split("\s+").length) {
            case 1:
                return String.format(formatString, id);
            case 2:
                return String.format(formatString, id, itemName);
            case 3:
                return String.format(formatString, id, itemName, price);
            case 4:
                return String.format(formatString, id, itemName, price, quantity);
            default:
                return toString();
        }
    }
}

现在您需要辅助方法来:加载文件数据(库存记录)、检索特定记录、检索特定项目属性、保存特定项目属性、保存记录等。这些方法可能如下所示:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;


public class InventoryDemo {

public enum ErrorMsg {
    LOAD_ERR("Inventory Items have not been loaded in yet!"),
    NOT_ADMIN("Invalid Operation! Admin Status Required!"),
    ID_EXISTS("Invalid ID! That ID Already Exists!"),
    NAME_EXISTS("Invalid Item Name! That Name Already Exists!");

    private String msg;

    ErrorMsg(String msg) {
        this.msg = msg;
    }

    public String msg() {
        return msg;
    }

}

private String encoding = "UTF-8"; // options: "US-ASCII", "UTF-8", "UTF-16"
private final List<InventoryItems> items = new ArrayList<>();
private boolean isInAdminMode = true;
private String dataFile = "InventoryItems.txt";
private String ls = System.lineSeparator();

public static void main(String[] args) {
    // App is started this way to avoid the need for statics.
    new InventoryDemo().startApp(args);
}

private void startApp(String[] args) {
    if (!loadDataFile()) {
        System.err.println("Error Loading: " + dataFile);
        System.exit(0);
    }

    Scanner input = new Scanner(System.in);

    System.out.println("This code is run from the startApp() method" + ls 
                     + "located within the InventoryDemo class. Its" + ls
                     + "intent is to demonstrate the how the methods" + ls
                     + "withint this class function." );
    pressAnyKey(input);

    System.out.println("Available Inventory Items");
    System.out.println("=========================");
    String[] allItems = getAllInventoryItems();
    if (allItems != null) {
        for (String strg : allItems) {
            System.out.println(strg);
        }
    }

    pressAnyKey(input);

    showFormattedTable();

    pressAnyKey(input);

    System.out.println();
    System.out.println("Available Inventory Items (with formated ID & Name)");
    String header = String.format("%-7s %-26s", "ID", "Item Name");
    String topLine = String.join("", Collections.nCopies(header.length(), "="));
    String underline = String.join("", Collections.nCopies(header.length(), "-"));
    System.out.println(topLine);
    System.out.println(header);
    System.out.println(underline);
    allItems = getAllInventoryItems("%-7s %-26s");
    if (allItems != null) {
        for (String strg : allItems) {
            System.out.println(strg);
        }
    }
    System.out.println(topLine);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific Record (by ID: 00004)");
    System.out.println("=========================================");
    String itemString = getItemString("00004");
    System.out.println(itemString);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific ID (by Name: Playstation 4 Pro)");
    System.out.println("===================================================");
    itemString = getItemID("Playstation 4 Pro");
    System.out.println(itemString);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific Name (by ID: 00004)");
    System.out.println("=======================================");
    itemString = getItemName("00004");
    System.out.println(itemString);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific Price (by ID: 00003)");
    System.out.println("========================================");
    double itemprice = getItemPrice("00003");
    System.out.println(itemprice);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific Quantity (by ID: 00002)");
    System.out.println("===========================================");
    int itemQuant = getItemQuantity("00002");
    System.out.println(itemQuant);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Change Name for: 'Playstation 4 Pro' at ID: "
            + "'00003' TO 'Some Kinda Game-Box'");
    System.out.println("============================================"
            + "================================");
    itemString = getItemString("00003");
    System.out.println("Current Name: -->  " + itemString);
    setItemName("00003", "Some Kinda Game-Box");
    itemString = getItemString("00003");
    System.out.println("Name is Now:  -->  " + itemString);

    pressAnyKey(input);

    System.out.println();
    String itemToAdd = "00006/LG LED 60\" Television/70555.0/08";
    System.out.println("Add a new Inventory Item (duplicate ID's are not allowed).");
    System.out.println("Adding (with 'NO Auto-ID-Increment'): "
            + itemToAdd);
    System.out.println("======================================"
            + "======================================");
    if (addInventoryItem(itemToAdd)) {
        showFormattedTable();
    }
    else {
        System.err.println("Could not add (" + itemToAdd + ") to Records List!");
    }

    pressAnyKey(input);

    System.out.println();
    itemToAdd = "DYSON 430 Vacume/65437.0/6";
    System.out.println("Add a new Inventory Item (duplicate ID's are not allowed).");
    System.out.println("Adding (with 'Auto-ID-Increment'): "
            + itemToAdd);
    System.out.println("======================================"
            + "=======================");
    if (addInventoryItem(itemToAdd)) {
        showFormattedTable();
    }
    else {
        System.err.println("Could not add (" + itemToAdd + ") to Records List!");
    }

    pressAnyKey(input);

    System.out.println();
    System.out.println("Delete an Inventory Item ID (based on Item ID: 00006).");
    String itemIDToDelete = "00006";
    if (deleteInventoryItemID(itemIDToDelete)) {
        showFormattedTable();
    }
    else {
        System.err.println("Could not delete record ID (" + itemIDToDelete + ") from Records List!");
    }

    pressAnyKey(input);

    System.out.println();
    System.out.println("Delete an Inventory Item Name (based on Item Name: DYSON 430 Vacume).");
    String itemNameToDelete = "DYSON 430 Vacume";
    if (deleteInventoryItemName(itemNameToDelete)) {
        showFormattedTable();
    }
    else {
        System.err.println("Could not delete record Item Name (" + itemNameToDelete + ") from Records List!");
    }
}

private void showFormattedTable() {
    System.out.println();
    System.out.println("   Available Inventory Items (with formatting)");
    String header = String.format("%-7s %-26s %-8s %-5s", "ID", "Item Name", "Price", "Stock");
    String topLine = String.join("", Collections.nCopies(header.length(), "="));
    String underline = String.join("", Collections.nCopies(header.length(), "-"));
    System.out.println(topLine);
    System.out.println(header);
    System.out.println(underline);
    String[] allItems = getAllInventoryItems("%-7s %-26s $%-9s %-5s");
    if (allItems != null) {
        for (String strg : allItems) {
            System.out.println(strg);
        }
    }
    System.out.println(topLine);
}

/**
 * Deletes the Inventory Item in Records List and data file that contains the 
 * supplied Item ID.<br><br>
 * 
 * @param idToDelete (String) The ID Number of the record to delete.<br>
 * 
 * @return (Boolean) True if successful and False if not.
 */
public boolean deleteInventoryItemID(String idToDelete) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return false;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return false;
    }
    for (int i = 0; i < items.size(); i++) {
        if (items.get(i).getId().equals(idToDelete)) {
            items.remove(i);
            break;
        }
    }
    refreshDataBase();
    return true;
}

/**
 * Deletes ALL Inventory Items in Records List and data file that contains the 
 * supplied Item Name.<br><br>
 * 
 * @param nameToDelete (String) The Item Name to delete (case insensitive).<br>
 * 
 * @return (Boolean) True if successful and False if not.
 */
public boolean deleteInventoryItemName(String nameToDelete) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return false;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return false;
    }
    for (int i = 0; i < items.size(); i++) {
        if (items.get(i).getItemName().equalsIgnoreCase(nameToDelete)) {
            items.remove(i);
            i--;
        }
    }
    refreshDataBase();
    return true;
}

/**
 * Admin Rights required!<br><BR>
 * <p>
 * Adds a Inventory Item to the Records List and database file.<br><br>
 * This method can produce a unique ID string automatically if (and only if)
 * an ID value is <b>not</b> supplied within the Inventory Item string. If
 * an ID <b>is supplied</b> within the Inventory Item string then that ID
 * will be used <b>UNLESS</b> that particular ID already exists in which
 * case this method will not apply the addition and a message is displayed
 * to Console indicating as such.
 *
 * @param itemToAdd (String) The string to be supplied must be a forward
 *                  slash (<b>/</b>) delimited <b>String</b> consisting
 *                  consisting of the 4 data parts that make up any
 *                  particular Inventory Item:<pre>
 *
 *     1) The unique Item ID String (optional);
 *     2) The Item Name String;
 *     3) The Item Price (as a String);
 *     4) The Item Quantity (as a String).</pre><br>
 *
 * A typical Inventory Item String supplied to this method should look like:
 * <pre>
 *     "00006/LG LED 60\" Television/70555.0/08"</pre><br>
 *
 * Or it can look like (if an Auto-ID is requested):
 * <pre>
 *     "LG LED 60\" Television/70555.0/08"</pre><br>
 *
 * Providing duplicate ID's (an ID that is already in the database file or
 * records List) is not allowed.
 *
 * @return (Boolean) True if the addition is successful and False if not.
 */
public boolean addInventoryItem(String itemToAdd) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return false;
    }
    try {
        String[] itemParts = itemToAdd.split("\s{0,}/\s{0,}");

        // Is Auto-ID-Increment required?
        if (!itemParts[0].matches("\d+") && itemParts.length == 3) {
            //Yes...
            String newID = getUniqueID();
            String[] parts = new String[4];
            parts[0] = newID;
            parts[1] = itemParts[0];
            parts[2] = itemParts[1];
            parts[3] = itemParts[2];
            itemParts = parts;
        }
        String id = itemParts[0];
        if (doesItemIDAlreadyExist(id)) {
            System.err.println("The Item ID (" + id + ") is an " + ErrorMsg.ID_EXISTS.msg);
            return false;
        }
        String name = itemParts[1];
        if (doesItemNameAlreadyExist(name)) {
            System.err.println("The Item Name (" + name + ") is an " + ErrorMsg.NAME_EXISTS.msg);
            return false;
        }
        double price = Double.parseDouble(itemParts[2]);
        int quant = Integer.parseInt(itemParts[3]);
        items.add(new InventoryItems(id, name, price, quant));
        refreshDataBase();
    }
    catch (Exception ex) {
        System.err.println(ex);
        return false;
    }
    return true;
}

public boolean doesItemIDAlreadyExist(String id) {
    boolean res = false;
    if (items.isEmpty()) {
        res = false;
    }
    else {
        for (InventoryItems itms : items) {
            if (itms.getId().equals(id)) {
                res = true;
                break;
            }
        }
    }
    return res;
}

public boolean doesItemNameAlreadyExist(String name) {
    boolean res = false;
    if (items.isEmpty()) {
        res = false;
    }
    else {
        for (InventoryItems itms : items) {
            if (itms.getItemName().equalsIgnoreCase(name)) {
                res = true;
                break;
            }
        }
    }
    return res;
}

public String getUniqueID() {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    int max = 0;
    for (InventoryItems itms : items) {
        String idVal = itms.getId();
        if (!idVal.matches("\d+")) {
            continue;
        }
        int val = Integer.parseInt(idVal);
        if (val > max) {
            max = val;
        }
    }
    if (max == 0) {
        return String.format("%5s", 1).replace(' ', '0');
    }
    else {
        return String.format("%5s", (max + 1)).replace(' ', '0');
    }
}

public String[] getAllInventoryItems(String... formatString) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    String format = "";
    if (formatString.length > 0) {
        format = formatString[0];
    }
    String[] itms = new String[items.size()];
    for (int i = 0; i < items.size(); i++) {
        if (!format.equals("")) {
            itms[i] = items.get(i).toString(format);
        }
        else {
            itms[i] = items.get(i).toString();
        }
    }
    return itms;
}

public String getItemID(String itemName) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    String res = null;
    for (InventoryItems item : items) {
        if (item.getItemName().equalsIgnoreCase(itemName)) {
            res = item.getId();
            break;
        }
    }
    return res;
}

public void setItemID(String itemName, String newIDValue) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return;
    }

    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return;
    }
    for (InventoryItems item : items) {
        if (item.getItemName().equalsIgnoreCase(itemName)) {
            item.setId(newIDValue);
            break;
        }
    }
    refreshDataBase();
}

public String getItemString(String idNumber) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    String res = null;
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            res = item.toString();
            break;
        }
    }
    return res;
}

public String getItemName(String idNumber) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    String res = null;
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            res = item.getItemName();
            break;
        }
    }
    return res;
}

public void setItemName(String idNumber, String newName) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return;
    }
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            item.setItemName(newName);
            break;
        }
    }
    refreshDataBase();
}

private double getItemPrice(String idNumber) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return 0.0d;
    }
    double res = 0.0d;
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            res = item.getPrice();
            break;
        }
    }
    return res;
}

public void setItemPrice(String idNumber, double newPrice) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return;
    }
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            item.setPrice(newPrice);
            break;
        }
    }
    refreshDataBase();
}

public int getItemQuantity(String idNumber) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return 0;
    }
    int res = 0;
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            res = item.getQuantity();
            break;
        }
    }
    return res;
}

public void setItemQuantity(String idNumber, int newQuantity) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return;
    }
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            item.setQuantity(newQuantity);
        }
    }
    refreshDataBase();
}

public boolean loadDataFile() {
    boolean success;
    items.clear();  // Clear the Records Data List.

    try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(dataFile), encoding))) {
    // try (BufferedReader reader = new BufferedReader(new FileReader(dataFile))) {
        String line;
        while ((line = reader.readLine()) != null) {
            // Trim the data line and remove BOM's (if any).
            line = trimBOMs(line);
            // Skip the header line and blank lines (if any).
            if (line.equals("") || line.toLowerCase().startsWith("id")) {
                continue;
            }
            String[] lineParts = line.split("\s{0,}/\s{0,}");
            // Validate record data types...
            String id = "";
            String name = "Unknown";
            double price = 0.0d;
            int quant = 0;
            if (lineParts.length >= 1) {
                // Is it an actual integer value string
                if (lineParts[0].matches("\d+")) {
                    id = lineParts[0];
                }
                if (lineParts.length >= 2) {
                    // Does the string contain a name or is it empty.
                    name = (lineParts[1].equals("") ? "Unknown" : lineParts[1]);
                    if (lineParts.length >= 3) {
                        // Is it an actual integer or double/float value string
                        if (lineParts[2].matches("-?\d+(\.\d+)?")) {
                            price = Double.parseDouble(lineParts[2]);
                        }
                        if (lineParts.length >= 4) {
                            // Is it an actual integer value string
                            if (lineParts[0].matches("\d+")) {
                                quant = Integer.parseInt(lineParts[3]);
                            }
                        }
                    }
                }
            }
            items.add(new InventoryItems(id, name, price, quant));
        }
        success = true;
    }
    catch (FileNotFoundException ex) {
        System.err.println(ex);
        success = false;
    }
    catch (IOException ex) {
        System.err.println(ex);
        success = false;
    }
    return success;
}

public boolean saveItemsToFile() {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return false;
    }
    String header = String.format("%-8s%-27s%-10s%-5s%n", "ID", "Item Name", "Price", "Stocks");

    try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(dataFile), encoding))) {
    // try (PrintWriter writer = new PrintWriter(new File(dataFile))) {
        writer.append(header);
        for (int i = 0; i < items.size(); i++) {
            String id = items.get(i).getId();
            String name = items.get(i).getItemName();
            double price = items.get(i).getPrice();
            int quant = items.get(i).getQuantity();
            String dataLine = String.format("%-6s/ %-25s/ %-8s/ %-4s%n", id, name, price, quant);
            writer.append(dataLine);
        }
        writer.flush();
    }
    catch (FileNotFoundException | UnsupportedEncodingException ex) {
        System.err.println(ex);
        return false;
    }
    return true;
}

public void refreshDataBase() {
    saveItemsToFile();
    loadDataFile();

    // Call and method to update your JTable(s) here!
}

public boolean isIsInAdminMode() {
    return isInAdminMode;
}

public void setIsInAdminMode(boolean isInAdminMode) {
    this.isInAdminMode = isInAdminMode;
}

public String getDataFilePath() {
    return dataFile;
}

public void setDataFilePath(String dataFile) {
    this.dataFile = dataFile;
}

public String getEncoding() {
    return encoding;
}

public void setEncoding(String encoding) {
    this.encoding = encoding;
}

/**
 * Removes (trims away) leading and trailing white-spaces and Removes 
 * any BOM's (Byte Order Marks) from all the different Character Encodings.<br><br>
 * 
 * @param inputString (String) The Unicode string to remove BOM's from.<br>
 * 
 * @return (String) 
 */
private static String trimBOMs(String inputString) {
    inputString = inputString.trim()
            .replaceAll("\uFEFF|\uEFBBBF|\uFFFE|\u0000FEFF|\uFFFE0000|\u2B2F7638","")
            .replaceAll("\u2B2F7639|\u2B2F762B|\u2B2F762F|\u2B2F76382D|\uF7644C", "")
            .replaceAll("\uDD736673|\u0EFEFF|\uFBEE28|\u84319533", "");
    return inputString;
}

private void pressAnyKey(Scanner input) {
    System.out.println(ls + "Press Enter key to continue (q to quit)...");
    String anyKey = input.nextLine();
    if (anyKey.toLowerCase().equals("q")) {
        System.exit(0);
    }
}
}

创建一个名为 InventoryDe​​mo 的新 Java 应用程序项目,并将 copy/paste 提供的 class 放入其中。这应该让您了解如何创建工具来完成您需要的工作。

对于延迟,我深表歉意,但我还有其他更紧迫的承诺。

正如所承诺的那样,这里有一个演示,说明如何针对 similar 表单使用 InventoryDe​​mo class 中包含的方法] 到您在 post 中显示的内容。

这个 运行nable 演示应用程序是一个快速的作品,所以不要指望任何真正的优化。这将取决于您创建自己的应用程序。简单易懂。

下面的 运行nable 演示(名为 DB_GUI)使用了我的 中提供的 classes:

  • 库存物品 Class (InventoryItems.java)
  • 库存演示 Class (InventoryDemo.java)

InventoryDe​​mo class 进行了非常小的调整,并在我的 中对该代码进行了更新。

这个 运行nable 是这样工作的:

您从一个空白数据库开始(没有文本文件)。文本数据文件会根据需要自动创建,每个文件代表一个特定的库存类别,例如:书写工具游戏机等。这些类别是通过位于应用程序 window 顶部的 editable JComboBox 创建的。如果此 JComboBox 中提供的类别 not 已包含在组合列表中,则将其添加到该列表并创建数据文件以准备保存与该特定相关的库存项目类别。

数据文件是在名为 InventoryCategories 的目录中创建的,该目录是在您的本地文件系统的 root 目录中自动创建的驱动您的特定应用程序 运行 正在运行。 在尝试 运行 此演示应用程序之前,请确保存在此类操作的适当权限。

要在表单的 JTextFields 中创建类别和编辑、添加、保存或删除数据,必须获得管理员权限 。普通用户可以修改的唯一数据项是 Quantity 字段。要进入管理模式,select 位于 JTable 正下方的 Admin link。您将需要输入密码,目前密码为 1234。您可以通过修改下面代码中 ADMIN_PASSWORD class 字段变量中包含的字符串值来将此密码更改为您喜欢的任何内容。

在管理员模式下:

  • 要在 Table 中编辑库存项目 select 然后执行 JTextFields 中您喜欢的任何编辑。当完成编辑和 要保存您的工作,select 保存 按钮。
  • 要将库存项目添加到当前活动类别,select 添加 按钮。所有 JTextField 都将清除。供应 表单的 JTextFields 中所需的数据然后完成后 select 保存 按钮。该记录将保存(附加)到 相关数据文件,放入JTable。提供项目 ID 是可选的,因为如果没有提供一个 ID 将自动生成 起始 ID 为 00001。您不能提供重复的 ID 值 在同一类别中。
  • 要从当前活动类别中删除库存项目,select JTable 中所需的库存项目,该项目将 显示在位于 形式。 Select 删除 按钮。确认对话框是 显示,select 按钮确认删除和 库存项目已从数据文件和 JTable.
  • 中删除

要退出管理模式:

只是select再次位于JTable底部的Adminlink。 link 是进入和退出管理模式的开关。

申请代码:

/*
Data text file names are based from the names of the categoryies 
created in Form. If a 'Writing Instruments' category is created 
then the data file created for that category's date will be named: 

                  Writing Instruments.txt

If a 'Game Consoles' category is created then the data file created 
for that category's date will be named: 

                     Game Consoles.txt

and so on. Categories are created by entering a specific category 
name (that DOES NOT already exist) into the Categories Drop-Down 
List (comboBox).
*/
package inventorydemo;

import com.sun.glass.events.KeyEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;



public class DB_GUI extends javax.swing.JFrame {

    private static final long serialVersionUID = 1L;
    private final InventoryDemo demo = new InventoryDemo();
    private final String ADMIN_PASSWORD = "1234";
    private boolean appStarted = false;

public DB_GUI() {
    initComponents();

    fillCategoriesCombo();
    categoryComboBox.setSelectedIndex(-1);

    // Set the JTable's Header font size to match the JTable's font size.
    JTableHeader header = jTable1.getTableHeader();
    header.setFont(header.getFont().deriveFont((float) jTable1.getFont().getSize()));

    // Center Text in JTable Header Cells.
    alignJTableHeaderText(jTable1, 0);

    // Set JTable's Column Widths
    setJTableColumnWidths(jTable1, 13d, 62d, 15d, 10d);

    // Set JTable's background color to White.
    jTable1.setFillsViewportHeight(true);
    jScrollPane1.getViewport().setBackground(Color.white);

    // Modifying the Look & Feel
    // Set JTable Header Background color to White.
    UIManager.getDefaults().put("TableHeader.background", Color.WHITE);
    // Remove JTable Header borders
    UIManager.getDefaults().put("TableHeader.cellBorder", BorderFactory.createEmptyBorder(0, 0, 0, 0));
    // Set JTextField's inactive background color to White.
    UIManager.getDefaults().put("TextField.inactiveBackground", Color.WHITE);

    // Key Binding for Category Combo. Passes what was entered to 
    // the addNewCategory() method when the ENTER key is pressed.
    // Used to add new Categories.
    categoryComboBox.getEditor().addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent evt) {
            if (demo.isInAdminMode()) {
                addNewCategory(categoryComboBox.getEditor().getItem().toString());
            }
            else {
                JFrame iFrame = new JFrame();
                iFrame.setAlwaysOnTop(true); 
                iFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                iFrame.setLocationRelativeTo(null);
                JOptionPane.showMessageDialog(iFrame, "You need Admin Access to "
                        + "create categories!", "Admin Required!", JOptionPane.WARNING_MESSAGE);
                iFrame.dispose();
            }
        }
    });

    // Center text in ComboBox.
    ((JLabel) categoryComboBox.getRenderer()).setHorizontalAlignment(SwingConstants.CENTER);

    // Set startup focus to the Admin link.
    lblAdminAccess.requestFocus();
    appStarted = true;
}

@SuppressWarnings("unchecked")
private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jLabel1 = new javax.swing.JLabel();
    jLabel2 = new javax.swing.JLabel();
    jSeparator1 = new javax.swing.JSeparator();
    productNameBox = new javax.swing.JTextField();
    categoryComboBox = new javax.swing.JComboBox<>();
    jLabel3 = new javax.swing.JLabel();
    jSeparator2 = new javax.swing.JSeparator();
    productIDBox = new javax.swing.JTextField();
    jSeparator5 = new javax.swing.JSeparator();
    productPriceBox = new javax.swing.JTextField();
    jSeparator6 = new javax.swing.JSeparator();
    productQuantityBox = new javax.swing.JTextField();
    jScrollPane1 = new javax.swing.JScrollPane();
    jTable1 = new javax.swing.JTable();
    saveButton = new javax.swing.JButton();
    doneButton = new javax.swing.JButton();
    deleteButton = new javax.swing.JButton();
    addButton = new javax.swing.JButton();
    lblAdminAccess = new javax.swing.JLabel();
    lblStatus = new javax.swing.JLabel();
    jSeparator3 = new javax.swing.JSeparator();
    jSeparator4 = new javax.swing.JSeparator();
    lblItems = new javax.swing.JLabel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setAlwaysOnTop(true);
    setResizable(false);

    jPanel1.setBackground(new java.awt.Color(255, 255, 255));

    jLabel1.setFont(new java.awt.Font("sansserif", 1, 12)); // NOI18N
    jLabel1.setText("Product ID:");
    jLabel1.setToolTipText("");

    jLabel2.setFont(new java.awt.Font("sansserif", 1, 12)); // NOI18N
    jLabel2.setText("Price:");
    jLabel2.setToolTipText("");

    jSeparator1.setBackground(new java.awt.Color(255, 51, 51));
    jSeparator1.setForeground(new java.awt.Color(255, 0, 0));
    jSeparator1.setToolTipText("");
    jSeparator1.setName(""); // NOI18N
    jSeparator1.setOpaque(true);
    jSeparator1.setRequestFocusEnabled(false);
    jSeparator1.setVerifyInputWhenFocusTarget(false);

    productNameBox.setEditable(false);
    productNameBox.setFont(new java.awt.Font("sansserif", 1, 12)); // NOI18N
    productNameBox.setForeground(new java.awt.Color(153, 153, 153));
    productNameBox.setHorizontalAlignment(javax.swing.JTextField.CENTER);
    productNameBox.setToolTipText("");
    productNameBox.setBorder(null);
    productNameBox.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
    productNameBox.setDisabledTextColor(new java.awt.Color(153, 153, 153));
    productNameBox.setSelectionColor(new java.awt.Color(204, 204, 204));

    categoryComboBox.setBackground(new java.awt.Color(255, 255, 255));
    categoryComboBox.setEditable(true);
    categoryComboBox.setForeground(new java.awt.Color(51, 51, 255));
    categoryComboBox.setAutoscrolls(true);
    categoryComboBox.setBorder(null);
    categoryComboBox.addItemListener(new java.awt.event.ItemListener() {
        public void itemStateChanged(java.awt.event.ItemEvent evt) {
            categoryComboBoxItemStateChanged(evt);
        }
    });

    jLabel3.setFont(new java.awt.Font("sansserif", 1, 12)); // NOI18N
    jLabel3.setText("Quantity:");

    jSeparator2.setBackground(new java.awt.Color(255, 51, 51));
    jSeparator2.setForeground(new java.awt.Color(255, 0, 0));
    jSeparator2.setToolTipText("");
    jSeparator2.setName(""); // NOI18N
    jSeparator2.setOpaque(true);
    jSeparator2.setRequestFocusEnabled(false);
    jSeparator2.setVerifyInputWhenFocusTarget(false);

    productIDBox.setEditable(false);
    productIDBox.setForeground(new java.awt.Color(153, 153, 153));
    productIDBox.setToolTipText("");
    productIDBox.setBorder(null);

    jSeparator5.setBackground(new java.awt.Color(255, 51, 51));
    jSeparator5.setForeground(new java.awt.Color(255, 0, 0));
    jSeparator5.setToolTipText("");
    jSeparator5.setName(""); // NOI18N
    jSeparator5.setOpaque(true);
    jSeparator5.setRequestFocusEnabled(false);
    jSeparator5.setVerifyInputWhenFocusTarget(false);

    productPriceBox.setEditable(false);
    productPriceBox.setForeground(new java.awt.Color(153, 153, 153));
    productPriceBox.setBorder(null);

    jSeparator6.setBackground(new java.awt.Color(255, 51, 51));
    jSeparator6.setForeground(new java.awt.Color(255, 0, 0));
    jSeparator6.setToolTipText("");
    jSeparator6.setName(""); // NOI18N
    jSeparator6.setOpaque(true);
    jSeparator6.setRequestFocusEnabled(false);
    jSeparator6.setVerifyInputWhenFocusTarget(false);

    productQuantityBox.setForeground(new java.awt.Color(0, 0, 255));
    productQuantityBox.setBorder(null);

    jScrollPane1.setBackground(new java.awt.Color(255, 255, 255));
    jScrollPane1.setBorder(null);
    jScrollPane1.setViewportBorder(null);
    jScrollPane1.setOpaque(true);

    jTable1.setBorder(null);
    jTable1.setFont(new java.awt.Font("sansserif", 0, 11)); // NOI18N
    jTable1.setForeground(new java.awt.Color(102, 102, 102));
    jTable1.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {null, null, null, null},
            {null, null, null, null},
            {null, null, null, null},
            {null, null, null, null}
        },
        new String [] {
            "ID", "Product Name", "Price", "Qty"
        }
    ) {
        Class[] types = new Class [] {
            java.lang.String.class, java.lang.String.class, java.lang.Double.class, java.lang.Integer.class
        };
        boolean[] canEdit = new boolean [] {
            false, false, false, false
        };

        public Class getColumnClass(int columnIndex) {
            return types [columnIndex];
        }

        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return canEdit [columnIndex];
        }
    });
    jTable1.setFillsViewportHeight(true);
    jTable1.setGridColor(new java.awt.Color(255, 255, 255));
    jTable1.setOpaque(false);
    jTable1.setSelectionBackground(new java.awt.Color(204, 204, 204));
    jTable1.setSelectionForeground(new java.awt.Color(0, 0, 0));
    jTable1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
    jTable1.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            jTable1MouseClicked(evt);
        }
    });
    jTable1.addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyReleased(java.awt.event.KeyEvent evt) {
            jTable1KeyReleased(evt);
        }
    });
    jScrollPane1.setViewportView(jTable1);

    saveButton.setText("Save");
    saveButton.setEnabled(false);
    saveButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            saveButtonActionPerformed(evt);
        }
    });

    doneButton.setText("Done");
    doneButton.setToolTipText("");
    doneButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            doneButtonActionPerformed(evt);
        }
    });

    deleteButton.setText("Delete");
    deleteButton.setToolTipText("");
    deleteButton.setEnabled(false);
    deleteButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            deleteButtonActionPerformed(evt);
        }
    });

    addButton.setText("Add");
    addButton.setToolTipText("");
    addButton.setEnabled(false);
    addButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            addButtonActionPerformed(evt);
        }
    });

    lblAdminAccess.setFont(new java.awt.Font("sansserif", 0, 10)); // NOI18N
    lblAdminAccess.setForeground(java.awt.Color.blue);
    lblAdminAccess.setText("<html><u>Admin</u></html>");
    lblAdminAccess.setToolTipText("<html> Turn Admin Mode: <font color=red>ON</font> </html> ");
    lblAdminAccess.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
    lblAdminAccess.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            lblAdminAccessMouseClicked(evt);
        }
    });

    lblStatus.setBackground(new java.awt.Color(255, 255, 255));
    lblStatus.setFont(new java.awt.Font("sansserif", 0, 11)); // NOI18N
    lblStatus.setForeground(new java.awt.Color(102, 102, 102));
    lblStatus.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    lblStatus.setText("<html>Add or select a product category (Admin required to add).</html>");
    lblStatus.setToolTipText("");
    lblStatus.setBorder(null);
    lblStatus.setOpaque(true);

    jSeparator3.setBackground(new java.awt.Color(0, 153, 153));
    jSeparator3.setToolTipText("");

    jSeparator4.setBackground(new java.awt.Color(0, 153, 153));
    jSeparator4.setToolTipText("");

    lblItems.setFont(new java.awt.Font("sansserif", 0, 11)); // NOI18N
    lblItems.setText("<html>Items: <font color=blue>0</font></html>");

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(50, 50, 50)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 72, Short.MAX_VALUE))
                    .addGap(32, 32, 32)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(jSeparator6, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jSeparator5, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(productIDBox, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(productPriceBox, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(productQuantityBox, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 238, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(productNameBox, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 238, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addComponent(lblStatus)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(lblItems, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(lblAdminAccess, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addContainerGap()
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 337, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addGap(28, 28, 28)
                            .addComponent(categoryComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 285, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addGap(30, 30, 30)
                            .addComponent(saveButton)
                            .addGap(18, 18, 18)
                            .addComponent(addButton)
                            .addGap(18, 18, 18)
                            .addComponent(deleteButton)
                            .addGap(18, 18, 18)
                            .addComponent(doneButton)))
                    .addGap(0, 0, Short.MAX_VALUE)))
            .addContainerGap())
        .addComponent(jSeparator3)
        .addComponent(jSeparator4)
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(12, 12, 12)
            .addComponent(categoryComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(18, 18, 18)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 212, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(lblAdminAccess, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(lblItems, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(4, 4, 4)
            .addComponent(productNameBox, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(24, 24, 24)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                    .addComponent(jLabel1)
                    .addGap(18, 18, 18)
                    .addComponent(jLabel2)
                    .addGap(18, 18, 18)
                    .addComponent(jLabel3))
                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                    .addComponent(productIDBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(productPriceBox, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jSeparator5, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(productQuantityBox, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jSeparator6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addGap(18, 18, 18)
            .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(saveButton)
                .addComponent(doneButton)
                .addComponent(deleteButton)
                .addComponent(addButton))
            .addGap(11, 11, 11)
            .addComponent(jSeparator4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(lblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(0, 0, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    pack();
    setLocationRelativeTo(null);
}

因为代码太大,我分两个 post 提供了。只需 copy/paste 此代码正下方 post 中的代码。

下面post的剩余代码:

private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {                                     
    fillProductBoxes();
    lblStatus.setText("<html><center>View or edit fields.</center></html>");
}                                    

private void lblAdminAccessMouseClicked(java.awt.event.MouseEvent evt) {                                            
    // Admin label foreground color is Blue
    if (lblAdminAccess.getForeground().getRGB() == -16776961) {
        lblStatus.setText("<html><center>Provide Admin Password!</center></html>");
        String passWrd = JOptionPane.showInputDialog(this, "<html>Please provide "
                + "your <font color=magenta>Admin</font> Password:<br><br></html>",
                "Admin Password", JOptionPane.PLAIN_MESSAGE);
        if (passWrd == null) {
            lblStatus.setText("");
            return;
        }
        if (!passWrd.equals(ADMIN_PASSWORD)) {
            lblStatus.setText("<html><center>Invalid Admin password supplied!</center></html>");
            JOptionPane.showMessageDialog(this, "<html><center><b>You have supplied an Invalid "
                                        + "Password!</b></center><br></html>",
                                        "Invalid Password!", JOptionPane.ERROR_MESSAGE);
            return;
        }
        lblAdminAccess.setForeground(Color.MAGENTA);
        lblAdminAccess.setToolTipText("<html> Turn Admin Mode: <font color=red>OFF</font> </html>");
        demo.setIsInAdminMode(true);
        setFormForAdminEditing(true);
        lblStatus.setText("<html><center>In Admin Mode!</center></html>");
    }

    else {
        lblAdminAccess.setForeground(Color.BLUE);
        lblAdminAccess.setToolTipText("<html> Turn Admin Mode: <font color=red>ON</font> </html>");
        setFormForAdminEditing(false);
        demo.setIsInAdminMode(false);
        lblStatus.setText("<html><center>Released from Admin Mode!</center></html>");
    }

}                                           

private void doneButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
    System.exit(0);
}                                          

private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
    if (productNameBox.getText().equals("")
            || productPriceBox.getText().equals("")
            || productQuantityBox.getText().equals("")) {
        lblStatus.setText("<html><center><b>A required field is empty!</b></center></html>");
        JOptionPane.showMessageDialog(this, "<html>A required field is empty! All fields<br>"
                + "(except the <font color=blue>ID</font> field) must be "
                + "supplied!<br><br><font size='2'><center>The "
                + "<font color=red>ID</font> field is optional."
                + "</center></font><br><br></html>", "Field Empty!",
                JOptionPane.WARNING_MESSAGE);
        return;
    }

    // If it's just an edit...
    if (!InventoryDemo.items.isEmpty() && jTable1.getSelectedRow() != -1 && 
            productIDBox.getText().equals(InventoryDemo.items.get(jTable1.getSelectedRow()).getId())) {
        InventoryDemo.items.get(jTable1.getSelectedRow()).setItemName(productNameBox.getText());
        if (productIDBox.getText().equals("")) {
            productIDBox.setText(demo.getUniqueID());
        }
        else {
            productIDBox.setText(String.format("%5s", productIDBox.getText()).replace(' ', '0'));
        }
        InventoryDemo.items.get(jTable1.getSelectedRow()).setId(productIDBox.getText());
        InventoryDemo.items.get(jTable1.getSelectedRow()).setPrice(Double.parseDouble(productPriceBox.getText()));
        InventoryDemo.items.get(jTable1.getSelectedRow()).setQuantity(Integer.parseInt(productQuantityBox.getText()));
        demo.refreshDataBase();
        lblItems.setText("<html>Items: <font color=blue>" + fillJTableFromList(jTable1) + "</font></html>");
        lblStatus.setText("<html><b><center><font color=red>Item Saved!</font></center></b></html>");
        return;
    }

    else if (!productIDBox.getText().equals("") && demo.getItemName(productIDBox.getText()) != null) {
        String existingItemName = demo.getItemName(productIDBox.getText());
        lblStatus.setText("<html><center><b>Item ID Already Exists In Database!</b></center></html>");
        int res = JOptionPane.showConfirmDialog(this, "<html>The ID supplied already "
                + "exists for another product item<br>named:<br><center><font color=blue>"
                + existingItemName + "</font></center><br>You can not change an ID of "
                + "this particualar product unless<br>the ID is <b>unique</b> (does not "
                + "already exist).<br><br><center>Do you want to auto-generate a unique "
                + "ID?</center><br><br></html>", "Invalid ID Supplied",
                JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);

        if (res != JOptionPane.YES_OPTION) {
            return;
        }
        // Set a Unique ID number
        productIDBox.setText(demo.getUniqueID());
    }

    // Get a unique ID number if one isn't provided.
    if (productIDBox.getText().equals("")) {
        productIDBox.setText(demo.getUniqueID());
    }
    else {
        // Make sure the Product ID has the proper 0 padding (for example: 00012).
        productIDBox.setText(String.format("%5s", productIDBox.getText()).replace(' ', '0'));
    }

    demo.addInventoryItem(new StringBuffer("").append(productIDBox.getText()).append("/")
            .append(productNameBox.getText()).append("/")
            .append(productPriceBox.getText()).append("/")
            .append(productQuantityBox.getText()).toString());
    demo.refreshDataBase();
    lblItems.setText("<html>Items: <font color=blue>" + fillJTableFromList(jTable1) + "</font></html>");
    lblStatus.setText("<html><b><center><font color=red>Item Saved!</font></center></b></html>");
}                                          

private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {                                          
    clearFields();
    productNameBox.requestFocus();
    lblStatus.setText("<html><center>Add desired Item (ID is optional).</center></html>");
}                                         

private void categoryComboBoxItemStateChanged(java.awt.event.ItemEvent evt) {                                                  
    // Ignore firings when combo is getting filled.
    if (!appStarted) {
        return;
    }
    String selected = categoryComboBox.getSelectedItem().toString();
    if (selected == null || selected.equals("")) {
        return;
    }
    // If an attempt is made to create a category without admin rights
    if (!demo.isInAdminMode() && !new File("/InventoryCategories/" + selected + ".txt").exists()) {
        return;
    }
    demo.setDataFilePath("/InventoryCategories/" + selected + ".txt");
    clearFields();
    clearJTable(jTable1);
    if (demo.loadDataFile()) {
        lblItems.setText("<html>Items: <font color=blue>" + fillJTableFromList(jTable1) + "</font></html>");
        lblStatus.setText("<html><center>View or edit desired Item.</center></html>");
    }
    else {
        lblStatus.setText("<html>Loading of data file (<font color=red>" + selected + ".txt</font>) failed to carry out!</html>");
    }
}                                                 

private void jTable1KeyReleased(java.awt.event.KeyEvent evt) {                                    
    if ((evt.getKeyCode() == KeyEvent.VK_DOWN || 
                            evt.getKeyCode() == KeyEvent.VK_UP) && 
                            jTable1.getRowCount() >= 0) {
        fillProductBoxes();
        lblStatus.setText("<html><center>View or edit fields.</center></html>");
    }
}                                   

private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
    if (InventoryDemo.items.isEmpty()) {
        JOptionPane.showMessageDialog(this, "There are no Inventory Items to delete!", 
                                      "Nothing To Delete", JOptionPane.INFORMATION_MESSAGE);
    }
    else if (jTable1.getSelectedRow() == -1) {
        JOptionPane.showMessageDialog(this, "There is no Inventory Item Selected To Delete!", 
                                      "Nothing Selected To Delete", JOptionPane.INFORMATION_MESSAGE);
    }
    else if (JOptionPane.showConfirmDialog(this, "<html>Are you sure you want "
                + "to delete the item:<br><br><font color=blue><b><center>" + 
                InventoryDemo.items.get(jTable1.getSelectedRow()).getItemName() + 
                "</b></font><br><center>from database for this Category?" + "<br><br><font size='2'>"
                + "<center>There is no <b>Undo</b> for this action!</font><br><br></html>", 
                "Delete Record?", JOptionPane.YES_NO_OPTION, 
                JOptionPane.QUESTION_MESSAGE) != JOptionPane.YES_OPTION) {
    }
    else {
        InventoryDemo.items.remove(jTable1.getSelectedRow());
        demo.refreshDataBase();
        clearFields();
        lblItems.setText("<html>Items: <font color=blue>" + fillJTableFromList(jTable1) + "</font></html>");
        lblStatus.setText("<html><center><b>Item Deleted!</b></center></html>");
    }
}                                            

private void addNewCategory(String categoryName) {
    if (!demo.isInAdminMode()) {
        lblStatus.setText("<html<center><b>Admin rights required!</b></center></html>");
        JOptionPane.showMessageDialog(this, "<html>You must have <b>Administrator Rights</b> to add<br>"
                + "Categories to the database!<br><br></html>", "Admin Required!",
                JOptionPane.WARNING_MESSAGE);
        categoryComboBox.getEditor().setItem("");
        return;
    }
    String dataFileName = "/InventoryCategories/" + categoryName.trim() + ".txt";
    if (new File(dataFileName).exists()) {
        lblStatus.setText("<html><center><b>Category Already Exists!</b></center></html>");
        JOptionPane.showMessageDialog(this, "The Category named '" + categoryName
                + "' already exits!", "New Category Error!", JOptionPane.WARNING_MESSAGE);
        return;
    }
    else {
        lblStatus.setText("");
        int res = JOptionPane.showConfirmDialog(this, "<html>The Category named "
                + "'<font color=blue>" + categoryName + "</font>' does not exist."
                + "<br><br><center>Do you want to create it?</center><br><br></html>",
                "Create Category?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
        if (res != JOptionPane.YES_OPTION) {
            return;
        }
        else {
            demo.setDataFilePath(dataFileName);
        }
    }

    lblStatus.setText("<html>New category named <font color=blue>" + categoryName
            + "</font> was created.</html>");
    categoryComboBox.addItem(categoryName);
    categoryComboBox.revalidate(); categoryComboBox.repaint();
    categoryComboBox.setSelectedItem(categoryName);
    demo.loadDataFile();
}

private void clearFields() {
    productNameBox.setText("");
    productIDBox.setText("");
    productPriceBox.setText("");
    productQuantityBox.setText("");
}

private void setFormForAdminEditing(boolean onOff) {
    productNameBox.setEditable(onOff);
    productIDBox.setEditable(onOff);
    productPriceBox.setEditable(onOff);
    saveButton.setEnabled(onOff);
    addButton.setEnabled(onOff);
    deleteButton.setEnabled(onOff);

    if (onOff) {
        productNameBox.setForeground(Color.BLUE);
        productIDBox.setForeground(Color.BLUE);
        productPriceBox.setForeground(Color.BLUE);
        productNameBox.requestFocus();
    }
    else {
        productNameBox.setForeground(Color.GRAY);
        productIDBox.setForeground(Color.GRAY);
        productPriceBox.setForeground(Color.GRAY);
        jTable1.requestFocus();
    }

}

public static void main(String args[]) {
    new DB_GUI().startApp(args);
}

private void startApp(String[] args) {
    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new DB_GUI().setVisible(true);
        }
    });


}

@SuppressWarnings("unchecked")
private void fillCategoriesCombo() {
    File files = new File("/InventoryCategories");
    if (!files.exists()) {
        return;
    }

    final List<String> values = new ArrayList<>();
    String[] categories = getFilesListFromDirectory("/InventoryCategories", true);
    values.addAll(Arrays.asList(categories));
    categoryComboBox.setModel(new DefaultComboBoxModel(values.toArray()));
}

private int fillJTableFromList(JTable table) {
    clearJTable(jTable1);

    if (InventoryDemo.items.isEmpty()) {
        JOptionPane.showMessageDialog(this, "<html>There are currently no inventory "
                              + "items<br>for this category!<br><br></html>", 
                              "No Inventory", JOptionPane.INFORMATION_MESSAGE);
        return 0;
    }

    DefaultTableModel model = (DefaultTableModel) table.getModel();
    int recordCount = 0;
    table.removeAll();

    // Clear current table rows
    while (model.getRowCount() > 0) {
        for (int i = 0; i < model.getRowCount(); i++) {
            model.removeRow(i);
        }
    }

    // Fill the JTable Model.
    Object[] dataArray = new Object[4];
    for (int i = 0; i < InventoryDemo.items.size(); i++) {
        dataArray[0] = InventoryDemo.items.get(i).getId();
        dataArray[1] = InventoryDemo.items.get(i).getItemName();
        dataArray[2] = InventoryDemo.items.get(i).getPrice();
        dataArray[3] = InventoryDemo.items.get(i).getQuantity();
        model.addRow(dataArray);
        recordCount++;
    }
    return recordCount;

}

private void fillProductBoxes() {
    int selRow = jTable1.getSelectedRow();
    if (selRow < 0) {
        return;
    }
    String id = (String) jTable1.getValueAt(selRow, 0);
    String name = (String) jTable1.getValueAt(selRow, 1);
    String price = String.valueOf(jTable1.getValueAt(selRow, 2));
    String qty = String.valueOf(jTable1.getValueAt(selRow, 3));

    productNameBox.setText(name);
    productIDBox.setText(id);
    productPriceBox.setText(price);
    productQuantityBox.setText(qty);
}

/**
 * Returns a String Array containing all the file names that are contained
 * within the supplied folder (directory) path. This method does not check
 * nested folders. Sub-Folders are ignored during the process.<br><br>
 * <p>
 * The file names string array that is returned can be made to return the
 * file names with name extensions removed if the optional
 * removeFileExtension parameter is supplied a boolean true.<br>
 *
 * @param directoryPath       (String) The directory to get file names
 *                            from.<br>
 *
 * @param removeFileExtension (Optional - Boolean - Default is False) Read
 *                            above information.<br>
 *
 * @return (1D String Array) A String Array containing all the file names
 *         found within the supplied folder path.
 */
public static String[] getFilesListFromDirectory(String directoryPath, boolean... removeFileExtension) {
    File file = new File(directoryPath);
    if (!file.isDirectory()) {
        System.err.println("getFilesListFromDirectory() Method Error! "
                + "The supplied directoy path does not lead to a directory!"
                + System.lineSeparator() + "(" + directoryPath + ")"
                + System.lineSeparator());
        return null;
    }
    boolean noExtension = false;
    if (removeFileExtension.length > 0) {
        noExtension = removeFileExtension[0];
    }
    String[] files = file.list();
    ArrayList<String> list = new ArrayList<>();
    for (String string : files) {
        if (new File(file.getPath() + File.separator + string).isFile()) {
            if (noExtension) {
                if (string.lastIndexOf(".") > 0) {
                    if (string.split("\.\.").length > 1) {
                        list.add(string);
                    }
                    else {
                        list.add(string.substring(0, string.lastIndexOf(".")));
                    }
                }
                else {
                    list.add(string);
                }
            }
            else {
                list.add(string);
            }
        }
    }
    return list.toArray(new String[0]);
}

public static void clearJTable(JTable theTable) {
    DefaultTableModel dtm = (DefaultTableModel) theTable.getModel();
    while (dtm.getRowCount() > 0) {
        for (int i = 0; i < dtm.getRowCount(); i++) {
            dtm.removeRow(i);
        }
    }
}

public static void alignJTableHeaderText(JTable theTable, int alignType) {
    // Alignment options are: Align_LEFT (2), Align_CENTER (0), Align_RIGHT (4),
    // Align_LEADING (10), or Align_TRAILING (11)
    for (int i = 0; i < theTable.getColumnCount(); i++) {
        theTable.getTableHeader().getColumnModel().getColumn(i)
                .setHeaderRenderer(new HeaderRenderer(theTable, alignType));
    }
}

/**
 * Set the pixel widths for the supplied Table Columns by way of
 * percentage.<br><br>
 *
 * @param table            (JTable) The JTable variable name.<br>
 *
 * @param widthPercentages (Double) Double values need to be supplied.
 *                         Consider the JTable being a width of 100%. When
 *                         supplying width percentages for all columns then
 *                         the sum of all percentages supplied should equal
 *                         100% (although not absolutely necessary).
 */
public static void setJTableColumnWidths(JTable table, double... widthPercentages) {
    int tablePreferredWidth = table.getParent().getSize().width; //.getPreferredSize().width;
    double total = 0;
    for (int i = 0; i < table.getColumnModel().getColumnCount(); i++) {
        total += widthPercentages[i];
    }

    for (int i = 0; i < table.getColumnModel().getColumnCount(); i++) {
        TableColumn column = table.getColumnModel().getColumn(i);
        column.setPreferredWidth((int) (tablePreferredWidth * (widthPercentages[i] / total)));
    }
}


// Variables declaration - do not modify                     
private javax.swing.JButton addButton;
private javax.swing.JComboBox<String> categoryComboBox;
private javax.swing.JButton deleteButton;
private javax.swing.JButton doneButton;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JSeparator jSeparator2;
private javax.swing.JSeparator jSeparator3;
private javax.swing.JSeparator jSeparator4;
private javax.swing.JSeparator jSeparator5;
private javax.swing.JSeparator jSeparator6;
private javax.swing.JTable jTable1;
private javax.swing.JLabel lblAdminAccess;
private javax.swing.JLabel lblItems;
private javax.swing.JLabel lblStatus;
private javax.swing.JTextField productIDBox;
private javax.swing.JTextField productNameBox;
private javax.swing.JTextField productPriceBox;
private javax.swing.JTextField productQuantityBox;
private javax.swing.JButton saveButton;
// End of variables declaration                   
}

Renderer SubClass ***">
class HeaderRenderer implements TableCellRenderer {

DefaultTableCellRenderer renderer;
int horAlignment;

public HeaderRenderer(JTable table, int horizontalAlignment) {
    horAlignment = horizontalAlignment;
    renderer = (DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer();
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value,
        boolean isSelected, boolean hasFocus, int row, int col) {
    Component c = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
    JLabel label = (JLabel) c;
    label.setHorizontalAlignment(horAlignment);
    return label;
}
}

我无法更新我之前 post 中的 InventoryDe​​mo class 代码,所以我会在这里更新:

package inventorydemo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;


public class InventoryDemo {

public enum ErrorMsg {
    LOAD_ERR("Inventory Items have not been loaded in yet!"),
    NOT_ADMIN("Invalid Operation! Admin Status Required!"),
    ID_EXISTS("Invalid ID! That ID Already Exists!"),
    NAME_EXISTS("Invalid Item Name! That Name Already Exists!");

    String msg;

    ErrorMsg(String msg) {
        this.msg = msg;
    }

    public String msg() {
        return msg;
    }

}

private String encoding = "UTF-8"; // options: "US-ASCII", "UTF-8", "UTF-16"
public static List<InventoryItems> items = new ArrayList<>();
private boolean isInAdminMode = false;
private String dataFile = "";
private String ls = System.lineSeparator();


public static void main(String[] args) {
    // App is started this way to avoid the need for statics.
    new InventoryDemo().startApp(args);
}

private void startApp(String[] args) {
    if (!loadDataFile()) {
        System.err.println("Error Loading: " + dataFile);
        System.exit(0);
    }

    Scanner input = new Scanner(System.in);

    System.out.println("This code is run from the startApp() method" + ls 
                     + "located within the InventoryDemo class. Its" + ls
                     + "intent is to demonstrate the how the methods" + ls
                     + "withint this class function." );
    pressAnyKey(input);

    System.out.println("Available Inventory Items");
    System.out.println("=========================");
    String[] allItems = getAllInventoryItems();
    if (allItems != null) {
        for (String strg : allItems) {
            System.out.println(strg);
        }
    }

    pressAnyKey(input);

    showFormattedTable();

    pressAnyKey(input);

    System.out.println();
    System.out.println("Available Inventory Items (with formated ID & Name)");
    String header = String.format("%-7s %-26s", "ID", "Item Name");
    String topLine = String.join("", Collections.nCopies(header.length(), "="));
    String underline = String.join("", Collections.nCopies(header.length(), "-"));
    System.out.println(topLine);
    System.out.println(header);
    System.out.println(underline);
    allItems = getAllInventoryItems("%-7s %-26s");
    if (allItems != null) {
        for (String strg : allItems) {
            System.out.println(strg);
        }
    }
    System.out.println(topLine);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific Record (by ID: 00004)");
    System.out.println("=========================================");
    String itemString = getItemString("00004");
    System.out.println(itemString);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific ID (by Name: Playstation 4 Pro)");
    System.out.println("===================================================");
    itemString = getItemID("Playstation 4 Pro");
    System.out.println(itemString);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific Name (by ID: 00004)");
    System.out.println("=======================================");
    itemString = getItemName("00004");
    System.out.println(itemString);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific Price (by ID: 00003)");
    System.out.println("========================================");
    double itemprice = getItemPrice("00003");
    System.out.println(itemprice);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Retrieve A Specific Quantity (by ID: 00002)");
    System.out.println("===========================================");
    int itemQuant = getItemQuantity("00002");
    System.out.println(itemQuant);

    pressAnyKey(input);

    System.out.println();
    System.out.println("Change Name for: 'Playstation 4 Pro' at ID: "
            + "'00003' TO 'Some Kinda Game-Box'");
    System.out.println("============================================"
            + "================================");
    itemString = getItemString("00003");
    System.out.println("Current Name: -->  " + itemString);
    setItemName("00003", "Some Kinda Game-Box");
    itemString = getItemString("00003");
    System.out.println("Name is Now:  -->  " + itemString);

    pressAnyKey(input);

    System.out.println();
    String itemToAdd = "00006/LG LED 60\" Television/70555.0/08";
    System.out.println("Add a new Inventory Item (duplicate ID's are not allowed).");
    System.out.println("Adding (with 'NO Auto-ID-Increment'): "
            + itemToAdd);
    System.out.println("======================================"
            + "======================================");
    if (addInventoryItem(itemToAdd)) {
        showFormattedTable();
    }
    else {
        System.err.println("Could not add (" + itemToAdd + ") to Records List!");
    }

    pressAnyKey(input);

    System.out.println();
    itemToAdd = "DYSON 430 Vacume/65437.0/6";
    System.out.println("Add a new Inventory Item (duplicate ID's are not allowed).");
    System.out.println("Adding (with 'Auto-ID-Increment'): "
            + itemToAdd);
    System.out.println("======================================"
            + "=======================");
    if (addInventoryItem(itemToAdd)) {
        showFormattedTable();
    }
    else {
        System.err.println("Could not add (" + itemToAdd + ") to Records List!");
    }

    pressAnyKey(input);

    System.out.println();
    System.out.println("Delete an Inventory Item ID (based on Item ID: 00006).");
    String itemIDToDelete = "00006";
    if (deleteInventoryItemID(itemIDToDelete)) {
        showFormattedTable();
    }
    else {
        System.err.println("Could not delete record ID (" + itemIDToDelete + ") from Records List!");
    }

    pressAnyKey(input);

    System.out.println();
    System.out.println("Delete an Inventory Item Name (based on Item Name: DYSON 430 Vacume).");
    String itemNameToDelete = "DYSON 430 Vacume";
    if (deleteInventoryItemName(itemNameToDelete)) {
        showFormattedTable();
    }
    else {
        System.err.println("Could not delete record Item Name (" + itemNameToDelete + ") from Records List!");
    }
}

private void showFormattedTable() {
    System.out.println();
    System.out.println("   Available Inventory Items (with formatting)");
    String header = String.format("%-7s %-26s %-8s %-5s", "ID", "Item Name", "Price", "Stock");
    String topLine = String.join("", Collections.nCopies(header.length(), "="));
    String underline = String.join("", Collections.nCopies(header.length(), "-"));
    System.out.println(topLine);
    System.out.println(header);
    System.out.println(underline);
    String[] allItems = getAllInventoryItems("%-7s %-26s $%-9s %-5s");
    if (allItems != null) {
        for (String strg : allItems) {
            System.out.println(strg);
        }
    }
    System.out.println(topLine);
}

/**
 * Deletes the Inventory Item in Records List and data file that contains the 
 * supplied Item ID.<br><br>
 * 
 * @param idToDelete (String) The ID Number of the record to delete.<br>
 * 
 * @return (Boolean) True if successful and False if not.
 */
public boolean deleteInventoryItemID(String idToDelete) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return false;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return false;
    }
    for (int i = 0; i < items.size(); i++) {
        if (items.get(i).getId().equals(idToDelete)) {
            items.remove(i);
            break;
        }
    }
    refreshDataBase();
    return true;
}

/**
 * Deletes ALL Inventory Items in Records List and data file that contains the 
 * supplied Item Name.<br><br>
 * 
 * @param nameToDelete (String) The Item Name to delete (case insensitive).<br>
 * 
 * @return (Boolean) True if successful and False if not.
 */
public boolean deleteInventoryItemName(String nameToDelete) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return false;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return false;
    }
    for (int i = 0; i < items.size(); i++) {
        if (items.get(i).getItemName().equalsIgnoreCase(nameToDelete)) {
            items.remove(i);
            i--;
        }
    }
    refreshDataBase();
    return true;
}

/**
 * Admin Rights required!<br><BR>
 * <p>
 * Adds a Inventory Item to the Records List and database file.<br><br>
 * This method can produce a unique ID string automatically if (and only if)
 * an ID value is <b>not</b> supplied within the Inventory Item string. If
 * an ID <b>is supplied</b> within the Inventory Item string then that ID
 * will be used <b>UNLESS</b> that particular ID already exists in which
 * case this method will not apply the addition and a message is displayed
 * to Console indicating as such.
 *
 * @param itemToAdd (String) The string to be supplied must be a forward
 *                  slash (<b>/</b>) delimited <b>String</b> consisting
 *                  consisting of the 4 data parts that make up any
 *                  particular Inventory Item:<pre>
 *
 *     1) The unique Item ID String (optional);
 *     2) The Item Name String;
 *     3) The Item Price (as a String);
 *     4) The Item Quantity (as a String).</pre><br>
 *
 * A typical Inventory Item String supplied to this method should look like:
 * <pre>
 *     "00006/LG LED 60\" Television/70555.0/08"</pre><br>
 *
 * Or it can look like (if an Auto-ID is requested):
 * <pre>
 *     "LG LED 60\" Television/70555.0/08"</pre><br>
 *
 * Providing duplicate ID's (an ID that is already in the database file or
 * records List) is not allowed.
 *
 * @return (Boolean) True if the addition is successful and False if not.
 */
public boolean addInventoryItem(String itemToAdd) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return false;
    }
    try {
        String[] itemParts = itemToAdd.split("\s{0,}/\s{0,}");

        // Is Auto-ID-Increment required?
        if (!itemParts[0].matches("\d+") && itemParts.length == 3) {
            //Yes...
            String newID = getUniqueID();
            String[] parts = new String[4];
            parts[0] = newID;
            parts[1] = itemParts[0];
            parts[2] = itemParts[1];
            parts[3] = itemParts[2];
            itemParts = parts;
        }
        String id = itemParts[0];
        if (doesItemIDAlreadyExist(id)) {
            System.err.println("The Item ID (" + id + ") is an " + ErrorMsg.ID_EXISTS.msg);
            return false;
        }
        String name = itemParts[1];
        if (doesItemNameAlreadyExist(name)) {
            System.err.println("The Item Name (" + name + ") is an " + ErrorMsg.NAME_EXISTS.msg);
            return false;
        }
        double price = Double.parseDouble(itemParts[2]);
        int quant = Integer.parseInt(itemParts[3]);
        items.add(new InventoryItems(id, name, price, quant));
        refreshDataBase();
    }
    catch (Exception ex) {
        System.err.println(ex);
        return false;
    }
    return true;
}

public boolean doesItemIDAlreadyExist(String id) {
    boolean res = false;
    if (items.isEmpty()) {
        res = false;
    }
    else {
        for (InventoryItems itms : items) {
            if (itms.getId().equals(id)) {
                res = true;
                break;
            }
        }
    }
    return res;
}

public boolean doesItemNameAlreadyExist(String name) {
    boolean res = false;
    if (items.isEmpty()) {
        res = false;
    }
    else {
        for (InventoryItems itms : items) {
            if (itms.getItemName().equalsIgnoreCase(name)) {
                res = true;
                break;
            }
        }
    }
    return res;
}

public String getUniqueID() {
    if (items.isEmpty()) {
        return "00001";
    }
    int max = 0;
    for (InventoryItems itms : items) {
        String idVal = itms.getId();
        if (!idVal.matches("\d+")) {
            continue;
        }
        int val = Integer.parseInt(idVal);
        if (val > max) {
            max = val;
        }
    }
    if (max == 0) {
        return String.format("%5s", 1).replace(' ', '0');
    }
    else {
        return String.format("%5s", (max + 1)).replace(' ', '0');
    }
}

public String[] getAllInventoryItems(String... formatString) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    String format = "";
    if (formatString.length > 0) {
        format = formatString[0];
    }
    String[] itms = new String[items.size()];
    for (int i = 0; i < items.size(); i++) {
        if (!format.equals("")) {
            itms[i] = items.get(i).toString(format);
        }
        else {
            itms[i] = items.get(i).toString();
        }
    }
    return itms;
}

public String getItemID(String itemName) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    String res = null;
    for (InventoryItems item : items) {
        if (item.getItemName().equalsIgnoreCase(itemName)) {
            res = item.getId();
            break;
        }
    }
    return res;
}

public void setItemID(String itemName, String newIDValue) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return;
    }

    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return;
    }
    for (InventoryItems item : items) {
        if (item.getItemName().equalsIgnoreCase(itemName)) {
            item.setId(newIDValue);
            break;
        }
    }
    refreshDataBase();
}

public String getItemString(String idNumber) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    String res = null;
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            res = item.toString();
            break;
        }
    }
    return res;
}

public String getItemName(String idNumber) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return null;
    }
    String res = null;
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            res = item.getItemName();
            break;
        }
    }
    return res;
}

public void setItemName(String idNumber, String newName) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return;
    }
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            item.setItemName(newName);
            break;
        }
    }
    refreshDataBase();
}

private double getItemPrice(String idNumber) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return 0.0d;
    }
    double res = 0.0d;
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            res = item.getPrice();
            break;
        }
    }
    return res;
}

public void setItemPrice(String idNumber, double newPrice) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return;
    }
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            item.setPrice(newPrice);
            break;
        }
    }
    refreshDataBase();
}

public int getItemQuantity(String idNumber) {
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return 0;
    }
    int res = 0;
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            res = item.getQuantity();
            break;
        }
    }
    return res;
}

public void setItemQuantity(String idNumber, int newQuantity) {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return;
    }
    if (items.isEmpty()) {
        System.err.println(ErrorMsg.LOAD_ERR.msg);
        return;
    }
    for (InventoryItems item : items) {
        if (item.getId().equals(idNumber)) {
            item.setQuantity(newQuantity);
        }
    }
    refreshDataBase();
}

public boolean loadDataFile() {
    // See if the data file exists. If it doesn't then create it. 
    // This will also create the the path to the file if it doesn't 
    // already exist.
    if (!new File(dataFile).exists()) {
        createPathAndTextFile(dataFile);
        items.clear();  // Clear the Records Data List so to start fresh.
        return true; // Nothing in file at this point so, we exit method.
    }

    boolean success;
    items.clear();  // Clear the Records Data List.

    try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(dataFile), encoding))) {
        String line;
        while ((line = reader.readLine()) != null) {
            // Trim the data line and remove BOM's (if any).
            line = trimBOMs(line);
            // Skip the header line and blank lines (if any).
            if (line.equals("") || line.toLowerCase().startsWith("id")) {
                continue;
            }
            String[] lineParts = line.split("\s{0,}/\s{0,}");
            // Validate record data types...
            String id = "";
            String name = "Unknown";
            double price = 0.0d;
            int quant = 0;
            if (lineParts.length >= 1) {
                // Is it an actual integer value string
                if (lineParts[0].matches("\d+")) {
                    id = lineParts[0];
                }
                if (lineParts.length >= 2) {
                    // Does the string contain a name or is it empty.
                    name = (lineParts[1].equals("") ? "Unknown" : lineParts[1]);
                    if (lineParts.length >= 3) {
                        // Is it an actual integer or double/float value string
                        if (lineParts[2].matches("-?\d+(\.\d+)?")) {
                            price = Double.parseDouble(lineParts[2]);
                        }
                        if (lineParts.length >= 4) {
                            // Is it an actual integer value string
                            if (lineParts[0].matches("\d+")) {
                                quant = Integer.parseInt(lineParts[3]);
                            }
                        }
                    }
                }
            }
            items.add(new InventoryItems(id, name, price, quant));
        }
        success = true;
    }
    catch (FileNotFoundException ex) {
        System.err.println(ex);
        success = false;
    }
    catch (IOException ex) {
        System.err.println(ex);
        success = false;
    }
    return success;
}

public boolean saveItemsToFile() {
    if (!isInAdminMode) {
        System.err.println(ErrorMsg.NOT_ADMIN.msg);
        return false;
    }
    String header = String.format("%-8s%-27s%-10s%-5s%n", "ID", "Item Name", "Price", "Stocks");

    try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(dataFile), encoding))) {
        writer.append(header);
        for (int i = 0; i < items.size(); i++) {
            String id = items.get(i).getId();
            String name = items.get(i).getItemName();
            double price = items.get(i).getPrice();
            int quant = items.get(i).getQuantity();
            String dataLine = String.format("%-6s/ %-25s/ %-8s/ %-4s%n", id, name, price, quant);
            writer.append(dataLine);
        }
        writer.flush();
    }
    catch (FileNotFoundException | UnsupportedEncodingException ex) {
        System.err.println(ex);
        return false;
    }
    return true;
}

public void refreshDataBase() {
    saveItemsToFile();
    loadDataFile();
}

/**
 * Will create the supplied path and text file into the local file system if
 * they do not already exist. If the path to file already does exist but the
 * file does not then just the file is created. Make sure file system
 * permissions are properly set before using this method. If an Exception is
 * encountered then false is returned.<br><br>
 * <p>
 * This method will return true if the supplied path and file name already
 * exist.
 *
 * @param pathString The path and file to create (if they don't already
 *                   exist).
 *
 * @return Boolean true or false. Returns true if the creation was
 *         successful and false if not successful.
 */
public static boolean createPathAndTextFile(String pathString) {
    if (pathString.isEmpty()) {
        System.err.println("createPathAndTextFile() - Path & Text File Created: " + false);
        return false;
    }
    if (new File(pathString).exists()) {
        return true;
    }
    String pathToFile = new File(pathString).getAbsolutePath().substring(0, new File(pathString).getAbsolutePath().lastIndexOf(File.separator));
    String fileToCreate = new File(pathString).getAbsolutePath().substring(new File(pathString).getAbsolutePath().lastIndexOf(File.separator) + 1);

    try {
        //Make the directories path if it doesn't already exist...
        File dir = new File(pathToFile);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        //Make the text file...
        File file = new File(dir, fileToCreate);
        FileWriter newFile = new FileWriter(file);
        newFile.close();
        if (new File(pathString).exists()) {
            return true;
        }
    }
    catch (IOException ex) {
        System.err.println("createPathAndTextFile() - Exception Encountered: " 
                            + System.lineSeparator() + ex.getMessage());
    }
    return false;
}

public boolean isInAdminMode() {
    return isInAdminMode;
}

public void setIsInAdminMode(boolean isInAdminMode) {
    this.isInAdminMode = isInAdminMode;
}

public String getDataFilePath() {
    return dataFile;
}

public void setDataFilePath(String dataFile) {
    this.dataFile = dataFile;
}

public String getEncoding() {
    return encoding;
}

public void setEncoding(String encoding) {
    this.encoding = encoding;
}

/**
 * Removes (trims away) leading and trailing white-spaces and Removes 
 * any BOM's (Byte Order Marks) from all the different Character Encodings.<br><br>
 * 
 * @param inputString (String) The Unicode string to remove BOM's from.<br>
 * 
 * @return (String) 
 */
private static String trimBOMs(String inputString) {
    inputString = inputString.trim()
            .replaceAll("\uFEFF|\uEFBBBF|\uFFFE|\u0000FEFF|\uFFFE0000|\u2B2F7638","")
            .replaceAll("\u2B2F7639|\u2B2F762B|\u2B2F762F|\u2B2F76382D|\uF7644C", "")
            .replaceAll("\uDD736673|\u0EFEFF|\uFBEE28|\u84319533", "");
    return inputString;
}

private void pressAnyKey(Scanner input) {
    System.out.println(ls + "Press Enter key to continue (q to quit)...");
    String anyKey = input.nextLine();
    if (anyKey.toLowerCase().equals("q")) {
        System.exit(0);
    }
}
}

如果实际用于 DB_GUI 应用程序,则可以从此 class 中删除很多代码。