Line deletion task ready

This commit is contained in:
2022-06-02 02:15:27 +03:00
parent c703e45d90
commit 58c3711ad0
10 changed files with 518 additions and 194 deletions

View File

@@ -7,15 +7,12 @@ public class Data {
this.harvest = harvest;
}
/**
* Restore data from table cell value
*
* @param data Value in JTable
*/
public Data(String data) {
// Restore data from table cell value
// data - "<tree - harvest>"
String[] split = data.split(" - ");
this.tree = split[0].trim();
this.harvest = Double.parseDouble(split[1].trim());
this.tree = split[0];
this.harvest = Double.parseDouble(split[1]);
}
public String getTree() {
@@ -30,10 +27,4 @@ public class Data {
public String toString() {
return String.format("%s - %.3f", tree, harvest);
}
public static void main(String[] args) {
System.out.println(new Data("Яблоко", 1.123));
System.out.println(new Data("Яблоко - 2.2345"));
System.out.println(new Data("Яблоко - 123456789.123456789"));
}
}

View File

@@ -6,92 +6,139 @@ public class DataTableModel extends AbstractTableModel {
private Data[][] rowData;
private String[] columnNames;
public DataTableModel(Data[][] rowData, String[] columnNames) {
public DataTableModel(Data[][] rowData) {
this.rowData = rowData;
this.columnNames = columnNames;
// Save string representation of indexes to use as top row
generateColumnNames(rowData[0].length);
}
private void generateColumnNames(int length) {
// Returns array of string representations of each number in range(1, length + 1)
columnNames = new String[length];
for (int i = 1; i <= length; i++) {
columnNames[i - 1] = i + "";
}
}
public void addRow(int newRowPos) {
int newRowCount = getRowCount() + 1;
Data[][] newRowData = new Data[newRowCount][getColumnCount()];
// Go through each row in new array
int oldDataIndex = 0;
for (int row = 0; row < newRowCount; row++) {
// If target position is reached
if (row == newRowPos) {
// Fill row with blank data
for (int col = 0; col < getColumnCount(); col++) {
newRowData[row][col] = new Data("", 0.);
}
} else {
// Copy old data
newRowData[row] = rowData[oldDataIndex];
// Advance position in old array
oldDataIndex++;
}
}
rowData = newRowData;
this.fireTableDataChanged();
this.fireTableStructureChanged();
}
public void addColumn(int newColumnPos) {
int newColumnCount = getColumnCount() + 1;
Data[][] newRowData = new Data[getRowCount()][newColumnCount];
// Go through each row in new array
for (int row = 0; row < getRowCount(); row++) {
// Go through each element of current row
int oldDataIndex = 0;
for (int col = 0; col < newColumnCount; col++) {
// If target position is reached
if (col == newColumnPos) {
// Fill element with blank data
newRowData[row][col] = new Data("", 0.);
} else {
// Copy old data
newRowData[row][col] = rowData[row][oldDataIndex];
// Advance position in old array
oldDataIndex++;
}
}
}
rowData = newRowData;
// Update column names
generateColumnNames(newColumnCount);
this.fireTableDataChanged();
this.fireTableStructureChanged();
}
public void deleteRow(int targetRowPos) {
int newRowCount = getRowCount() - 1;
Data[][] newRowData = new Data[newRowCount][getColumnCount()];
// Go through each row in new array
int oldDataIndex = 0;
for (int row = 0; row < newRowCount; row++) {
// If target position is reached
if (oldDataIndex == targetRowPos - 1) {
// Skip row without copying
oldDataIndex++;
}
// Copy old data
newRowData[row] = rowData[oldDataIndex];
// Advance position in old array
oldDataIndex++;
}
rowData = newRowData;
this.fireTableDataChanged();
this.fireTableStructureChanged();
}
public void deleteColumn(int targetColumnPos) {
int newColumnCount = getColumnCount() - 1;
Data[][] newRowData = new Data[getRowCount()][newColumnCount];
// Go through each row in new array
for (int row = 0; row < getRowCount(); row++) {
// Go through each element of current row
int oldDataIndex = 0;
for (int col = 0; col < newColumnCount; col++) {
// If target position is reached
if (oldDataIndex == targetColumnPos - 1) {
// Skip element without copying
oldDataIndex++;
}
// Copy old data
newRowData[row][col] = rowData[row][oldDataIndex];
// Advance position in old array
oldDataIndex++;
}
}
rowData = newRowData;
// Update column names
generateColumnNames(newColumnCount);
this.fireTableDataChanged();
this.fireTableStructureChanged();
}
public String[] getColumnNames() {
return columnNames;
}
public Data[][] getRowData() {
return rowData;
}
public void addColumn(int i) {
if (i > rowData[0].length) {
String message = String.format("Невозможно добавить столбец %d так как в таблце всего %d колонок", i, rowData[0].length);
JOptionPane.showMessageDialog(null, message, "Неправильный индекс столбца", JOptionPane.ERROR_MESSAGE);
return;
}
Data[][] newRowData = new Data[rowData.length][rowData[0].length + 1];
for (int row = 0; row < rowData.length; row++) {
for (int col = 0; col < rowData[0].length + 1; col++) {
if (col == i) {
newRowData[row][col] = new Data("", 0.);
} else if (col > i) {
newRowData[row][col] = rowData[row][col - 1];
} else {
newRowData[row][col] = rowData[row][col];
}
}
}
rowData = newRowData;
String[] newColumnNames = new String[columnNames.length + 1];
for (int col = 0; col < columnNames.length + 1; col++) {
newColumnNames[col] = col + 1 + "";
}
columnNames = newColumnNames;
this.fireTableDataChanged();
this.fireTableStructureChanged();
}
// public void removeColumn(int i) {
//
// Data colToDelete = columnNames.getColumnModel().getColumn(number);
// table.removeColumn(colToDelete);
// ColumnField.setText("");
// }
public void addRow(int i) {
if (i > rowData[0].length) {
String message = String.format("Невозможно добавить строчку %d так как в таблце всего %d колонок", i, rowData[0].length);
JOptionPane.showMessageDialog(null, message, "Неправильный индекс строчки", JOptionPane.ERROR_MESSAGE);
return;
}
Data[][] newRowData = new Data[rowData.length + 1][rowData[0].length];
for (int row = 0; row < rowData.length + 1; row++) {
for (int col = 0; col < rowData[0].length; col++) {
if (row == i) {
newRowData[row][col] = new Data("", 0.);
} else if (row > i) {
newRowData[row][col] = rowData[row - 1][col];
} else {
newRowData[row][col] = rowData[row][col];
}
}
}
rowData = newRowData;
this.fireTableDataChanged();
this.fireTableStructureChanged();
}
public void removeRow(int i)
{
}
public String[] getColumnNames() {
return columnNames;
}
public void setColumnNames(String[] columnNames) {
this.columnNames = columnNames;
}

70
src/IndexValidator.java Normal file
View File

@@ -0,0 +1,70 @@
import javax.swing.*;
public class IndexValidator {
private DataTableModel tableModel;
public IndexValidator(DataTableModel tableModel) {
this.tableModel = tableModel;
}
public int validateRowIndex(String userInput) {
int inputRow;
// Check for validity of input data (should be a number)
try {
inputRow = Integer.parseInt(userInput);
} catch (NumberFormatException error) {
// Error: empty input field / input not a number
String message = "Пожалуйста введите правильный индекс";
JOptionPane.showMessageDialog(null, message, "Неправильный индекс строчки", JOptionPane.ERROR_MESSAGE);
return -1;
}
// Error: number exceeds rows amount
if (inputRow > tableModel.getRowCount()) {
String message = String.format("Невозможно найти строчку %d так как в таблце всего %d строчек", inputRow, tableModel.getRowCount());
JOptionPane.showMessageDialog(null, message, "Неправильный индекс строчки", JOptionPane.ERROR_MESSAGE);
return -1;
}
// Error: resulting index is negative
if (inputRow <= 0) {
String message = String.format("Невозможно нийти строчку %d: номер должен быть больше 0", inputRow);
JOptionPane.showMessageDialog(null, message, "Неправильный индекс строчки", JOptionPane.ERROR_MESSAGE);
return -1;
}
return inputRow;
}
public int validateColumnIndex(String userInput) {
int inputColumn;
// Check for validity of input data (should be a number)
try {
inputColumn = Integer.parseInt(userInput);
} catch (NumberFormatException error) {
// Error: empty input field / input not a number
String message = "Пожалуйста введите правильный индекс";
JOptionPane.showMessageDialog(null, message, "Неправильный индекс столбца", JOptionPane.ERROR_MESSAGE);
return -1;
}
// Error: number exceeds column amount
if (inputColumn > tableModel.getColumnCount()) {
String message = String.format("Невозможно найти столбец %d так как в таблце всего %d столбцов", inputColumn, tableModel.getColumnCount());
JOptionPane.showMessageDialog(null, message, "Неправильный индекс столбца", JOptionPane.ERROR_MESSAGE);
return -1;
}
// Error: resulting index is negative
if (inputColumn <= 0) {
String message = String.format("Невозможно найти столбец %d: номер должен быть больше 0", inputColumn);
JOptionPane.showMessageDialog(null, message, "Неправильный индекс столбца", JOptionPane.ERROR_MESSAGE);
return -1;
}
// This point is reached only upon receival of valid number
return inputColumn;
}
}

View File

@@ -9,10 +9,10 @@ public class LivadaPlan extends JPanel {
public LivadaPlan(Data[][] data) {
super(new BorderLayout());
String[] header = createHeader(data[0].length);
tableModel = new DataTableModel(data, header);
// Initialize DataTableModel implementing cell lookups
tableModel = new DataTableModel(data);
JTable table = new JTable(tableModel);
JScrollPane scrollPane = new JScrollPane(table);
JTable rowTable = new RowNumberTable(table);
@@ -24,12 +24,4 @@ public class LivadaPlan extends JPanel {
public DataTableModel getTableModel() {
return tableModel;
}
private String[] createHeader(int length) {
String[] header = new String[length];
for (int i = 1; i <= length; i++) {
header[i - 1] = i + "";
}
return header;
}
}

View File

@@ -12,6 +12,7 @@ public class Main {
}
private static void createAndShowGUI() {
// Configure UI
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException |
@@ -23,11 +24,12 @@ public class Main {
JFrame frame = new JFrame("Livada");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Read data from files as two separate arrays
DataReader dataReader = new DataReader();
String[][] trees = dataReader.readTrees("Derevia.in");
double[][] harvest = dataReader.readHarvest("Urojai.in", trees.length);
// Merge data into a convenient Data(String tree, double harvest) classes
Data[][] data = dataReader.mergeData(trees, harvest);
// Create and set up the content pane.

View File

@@ -0,0 +1,77 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MenuActionAddColumn implements ActionListener {
private DataTableModel tableModel;
private boolean askForPosition;
public MenuActionAddColumn(DataTableModel tableModel, boolean askForPosition) {
this.tableModel = tableModel;
// If set to true user will be prompted to input column name
this.askForPosition = askForPosition;
}
public void actionPerformed(ActionEvent e) {
System.out.println("Create Column");
// Default parameters
// Direction: If true - append west, else append east
boolean direction = false;
int column = -1;
if (askForPosition) {
Object[] options = {"Добавить на запад", "Добавить на восток", "Отмена"};
JPanel panel = new JPanel();
panel.add(new JLabel("Введите номер столбца который должен быть добавлен"));
JTextField textField = new JTextField(10);
panel.add(textField);
// Keep asking for number until valid response is received
while (column == -1) {
int result = JOptionPane.showOptionDialog(
null,
panel,
"Введите номер столбца",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
options,
null
);
// Canceled by user
if (result == JOptionPane.CLOSED_OPTION || result == 2) {
return;
}
// Process user response
boolean inputDirection = result == 0;
IndexValidator indexValidator = new IndexValidator(tableModel);
int inputColumn = indexValidator.validateColumnIndex(textField.getText());
// If an error was encountered
if (inputColumn == -1) {
continue;
}
// This point is reached only upon receival of valid number
direction = inputDirection;
column = inputColumn;
}
} else {
// If askForPosition is false, then append column to the end
column = tableModel.getColumnCount();
}
// If direction is north, the actual index is the preceeding one
if (direction) {
column--;
}
tableModel.addColumn(column);
}
}

77
src/MenuActionAddRow.java Normal file
View File

@@ -0,0 +1,77 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MenuActionAddRow implements ActionListener {
private DataTableModel tableModel;
private boolean askForPosition;
public MenuActionAddRow(DataTableModel tableModel, boolean askForPosition) {
this.tableModel = tableModel;
// If set to true user will be prompted to input row name
this.askForPosition = askForPosition;
}
public void actionPerformed(ActionEvent e) {
System.out.println("Create Row");
// Default parameters
// Direction: If true - append north, else append south
boolean direction = false;
int row = -1;
if (askForPosition) {
Object[] options = {"Добавить на север", "Добавить на юг", "Отмена"};
JPanel panel = new JPanel();
panel.add(new JLabel("Введите номер строки который должен быть добавлен"));
JTextField textField = new JTextField(10);
panel.add(textField);
// Keep asking for number until valid response is received
while (row == -1) {
int result = JOptionPane.showOptionDialog(
null,
panel,
"Введите номер строки",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
options,
null
);
// Canceled by user
if (result == JOptionPane.CLOSED_OPTION || result == 2) {
return;
}
// Process user response
boolean inputDirection = result == 0;
IndexValidator indexValidator = new IndexValidator(tableModel);
int inputRow = indexValidator.validateRowIndex(textField.getText());
// If an error was encountered
if (inputRow == -1) {
continue;
}
// This point is reached only upon receival of valid number
direction = inputDirection;
row = inputRow;
}
} else {
// If askForPosition is false, then append row to the end
row = tableModel.getRowCount();
}
// If direction is north, the actual index is the preceeding one
if (direction) {
row--;
}
tableModel.addRow(row);
}
}

View File

@@ -0,0 +1,55 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MenuActionDeleteColumn implements ActionListener {
private DataTableModel tableModel;
public MenuActionDeleteColumn(DataTableModel tableModel) {
this.tableModel = tableModel;
}
public void actionPerformed(ActionEvent e) {
System.out.println("Delete Column");
Object[] options = {"Удалить", "Отмена"};
JPanel panel = new JPanel();
panel.add(new JLabel("Введите номер столбца который должен быть удалён"));
JTextField textField = new JTextField(10);
panel.add(textField);
int column = -1;
while (column == -1) {
int result = JOptionPane.showOptionDialog(
null,
panel,
"Введите номер столбца",
JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
options,
null
);
// Canceled by user
if (result == JOptionPane.CLOSED_OPTION || result == 2) {
return;
}
// Process user response
IndexValidator indexValidator = new IndexValidator(tableModel);
int inputColumn = indexValidator.validateColumnIndex(textField.getText());
// If an error was encountered
if (inputColumn == -1) {
continue;
}
column = inputColumn;
}
tableModel.deleteColumn(column);
}
}

View File

@@ -0,0 +1,55 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MenuActionDeleteRow implements ActionListener {
private DataTableModel tableModel;
public MenuActionDeleteRow(DataTableModel tableModel) {
this.tableModel = tableModel;
}
public void actionPerformed(ActionEvent e) {
System.out.println("Delete Row");
Object[] options = {"Удалить", "Отмена"};
JPanel panel = new JPanel();
panel.add(new JLabel("Введите номер строки который должен быть удалён"));
JTextField textField = new JTextField(10);
panel.add(textField);
int row = -1;
while (row == -1) {
int result = JOptionPane.showOptionDialog(
null,
panel,
"Введите номер строки",
JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
options,
null
);
// Canceled by user
if (result == JOptionPane.CLOSED_OPTION || result == 2) {
return;
}
// Process user response
IndexValidator indexValidator = new IndexValidator(tableModel);
int inputRow = indexValidator.validateRowIndex(textField.getText());
// If an error was encountered
if (inputRow == -1) {
continue;
}
row = inputRow;
}
tableModel.deleteRow(row);
}
}

View File

@@ -7,57 +7,54 @@ public class MenuBar extends JMenuBar {
public MenuBar(DataTableModel tableModel) {
this.tableModel = tableModel;
JMenu menu = new JMenu("Меню");
this.add(menu);
menu.add(createAddRowColItem());
menu.add(createRemoveRowColItem());
// Create add submenu
JMenu addMenu = new JMenu("Добавить");
// Row add items
JMenuItem addRowItem = new JMenuItem("Новый ряд (крайний)");
addRowItem.addActionListener(new MenuActionAddRow(tableModel, false));
addMenu.add(addRowItem);
JMenuItem addPositionedRowItem = new JMenuItem("Новый ряд (позиция)");
addPositionedRowItem.addActionListener(new MenuActionAddRow(tableModel, true));
addMenu.add(addPositionedRowItem);
// Column add items
JMenuItem addColumnItem = new JMenuItem("Новый столбец (крайний)");
addColumnItem.addActionListener(new MenuActionAddColumn(tableModel, false));
addMenu.add(addColumnItem);
JMenuItem addPositionedColumnItem = new JMenuItem("Новый столбец (позиция)");
addPositionedColumnItem.addActionListener(new MenuActionAddColumn(tableModel, true));
addMenu.add(addPositionedColumnItem);
// Create delete submenu
JMenu deleteMenu = new JMenu("Удалить");
// Row delete
JMenuItem deleteRowItem = new JMenuItem("Удалить строку");
deleteRowItem.addActionListener(new MenuActionDeleteRow(tableModel));
deleteMenu.add(deleteRowItem);
// Column delete
JMenuItem deleteColumnItem = new JMenuItem("Удалить столбец");
deleteColumnItem.addActionListener(new MenuActionDeleteColumn(tableModel));
deleteMenu.add(deleteColumnItem);
// Create main menu
JMenu menu = new JMenu("Меню");
menu.add(addMenu);
menu.add(deleteMenu);
// menu.add(createAddRowColItem());
// menu.add(createRemoveRowColItem());
menu.add(createMockMenuItem("Макс Урожай"));
menu.add(createMockMenuItem("Средн Урожай"));
menu.add(createMockMenuItem("Общий урожай"));
menu.add(createMockMenuItem("Lin Spec"));
menu.add(createMockMenuItem("Сектор К деревьев"));
}
private JMenuItem createRemoveRowColItem() {
JMenuItem item = new JMenuItem();
item.setText("Удалить");
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Remove Row/Col");
Object[] options = {"Удалить строку", "Удалить колонку", "Отмена"};
JPanel panel = new JPanel();
panel.add(new JLabel("Введите номер строки или стоблца который должен быть удален"));
JTextField textField = new JTextField(10);
panel.add(textField);
int result = JOptionPane.showOptionDialog(null,
panel, "Введите номер строки / столбца",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
options,
null);
if (textField.getText().trim().isEmpty()) {
return;
}
if (result == JOptionPane.YES_OPTION) {
int row = Integer.parseInt(textField.getText());
System.out.println("Remove row # " + row);
tableModel.removeRow(row - 1);
} else if (result == JOptionPane.NO_OPTION) {
int column = Integer.parseInt(textField.getText());
System.out.println("Remove column # " + column);
// tableModel.removeColumn(column - 1);
} else {
System.out.println("Cancel add row/col");
}
}
}); return item;
this.add(menu);
}
private JMenuItem createMockMenuItem(String text) {
@@ -71,44 +68,5 @@ public class MenuBar extends JMenuBar {
return item;
}
private JMenuItem createAddRowColItem() {
JMenuItem item = new JMenuItem();
item.setText("Добавить");
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Create Row/Col");
Object[] options = {"Добавить строку", "Добавить колонку", "Отмена"};
JPanel panel = new JPanel();
panel.add(new JLabel("Введите номер строки или стоблца который должен быть добавлен"));
JTextField textField = new JTextField(10);
panel.add(textField);
int result = JOptionPane.showOptionDialog(null,
panel, "Введите номер строки / столбца",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
options,
null);
if (textField.getText().trim().isEmpty()) {
return;
}
if (result == JOptionPane.YES_OPTION) {
int row = Integer.parseInt(textField.getText());
System.out.println("Add row # " + row);
tableModel.addRow(row);
} else if (result == JOptionPane.NO_OPTION) {
int column = Integer.parseInt(textField.getText());
System.out.println("Add column # " + column);
tableModel.addColumn(column - 1);
} else {
System.out.println("Cancel add row/col");
}
}
});
return item;
}
}