Project received

This commit is contained in:
2022-06-01 21:19:28 +03:00
commit c703e45d90
16 changed files with 882 additions and 0 deletions

39
src/Data.java Normal file
View File

@@ -0,0 +1,39 @@
public class Data {
private String tree;
private double harvest;
public Data(String tree, double harvest) {
this.tree = tree;
this.harvest = harvest;
}
/**
* Restore data from table cell value
*
* @param data Value in JTable
*/
public Data(String data) {
String[] split = data.split("-");
this.tree = split[0].trim();
this.harvest = Double.parseDouble(split[1].trim());
}
public String getTree() {
return tree;
}
public double getHarvest() {
return harvest;
}
@Override
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"));
}
}

63
src/DataReader.java Normal file
View File

@@ -0,0 +1,63 @@
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
public class DataReader {
public String[][] readTrees(String fileName) {
String[][] data;
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String header = br.readLine();
String[] size = header.split(" ");
int n = Integer.parseInt(size[0]);
int m = Integer.parseInt(size[1]);
System.out.printf("Array size is %d x %d", n, m);
data = new String[n][m];
String line;
int row = 0;
while ((line = br.readLine()) != null) {
String[] trees = line.split(" ");
data[row++] = trees;
}
Arrays.toString(data);
} catch (IOException e) {
throw new RuntimeException(e);
}
return data;
}
public double[][] readHarvest(String fileName, int rows) {
double[][] data = new double[rows][];
int row = 0;
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = br.readLine()) != null) {
String[] s = line.split(" ");
double[] centners = new double[s.length];
for (int i = 0; i < s.length; i++) {
centners[i] = Double.parseDouble(s[i]);
}
data[row++] = centners;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return data;
}
public Data[][] mergeData(String[][] trees, double[][] harvest) {
Data[][] result = new Data[trees.length][trees[0].length];
for (int row = 0; row < trees.length; row++) {
for (int col = 0; col < trees[0].length; col++) {
result[row][col] = new Data(trees[row][col], harvest[row][col]);
}
}
return result;
}
}

129
src/DataTableModel.java Normal file
View File

@@ -0,0 +1,129 @@
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
public class DataTableModel extends AbstractTableModel {
private Data[][] rowData;
private String[] columnNames;
public DataTableModel(Data[][] rowData, String[] columnNames) {
this.rowData = rowData;
this.columnNames = 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;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public int getRowCount() {
return rowData.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int row, int col) {
return rowData[row][col];
}
@Override
public boolean isCellEditable(int row, int column) {
return true;
}
@Override
public void setValueAt(Object value, int row, int col) {
rowData[row][col] = new Data(value.toString());
fireTableCellUpdated(row, col);
}
}

35
src/LivadaPlan.java Normal file
View File

@@ -0,0 +1,35 @@
import javax.swing.*;
import java.awt.*;
public class LivadaPlan extends JPanel {
private DataTableModel tableModel;
public LivadaPlan(Data[][] data) {
super(new BorderLayout());
String[] header = createHeader(data[0].length);
tableModel = new DataTableModel(data, header);
JTable table = new JTable(tableModel);
JScrollPane scrollPane = new JScrollPane(table);
JTable rowTable = new RowNumberTable(table);
scrollPane.setRowHeaderView(rowTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());
add(scrollPane, BorderLayout.CENTER);
}
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;
}
}

45
src/Main.java Normal file
View File

@@ -0,0 +1,45 @@
import javax.swing.*;
public class Main {
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException |
IllegalAccessException e) {
e.printStackTrace();
}
//Create and set up the window.
JFrame frame = new JFrame("Livada");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DataReader dataReader = new DataReader();
String[][] trees = dataReader.readTrees("Derevia.in");
double[][] harvest = dataReader.readHarvest("Urojai.in", trees.length);
Data[][] data = dataReader.mergeData(trees, harvest);
//Create and set up the content pane.
LivadaPlan livadaPlan = new LivadaPlan(data);
livadaPlan.setOpaque(true);
frame.setContentPane(livadaPlan);
// Add menu bar with all 7 actions
frame.setJMenuBar(new MenuBar(livadaPlan.getTableModel()));
//Display the window.
frame.pack();
frame.setVisible(true);
}
}

114
src/MenuBar.java Normal file
View File

@@ -0,0 +1,114 @@
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MenuBar extends JMenuBar {
private DataTableModel tableModel;
public MenuBar(DataTableModel tableModel) {
this.tableModel = tableModel;
JMenu menu = new JMenu("Меню");
this.add(menu);
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;
}
private JMenuItem createMockMenuItem(String text) {
JMenuItem item = new JMenuItem(text);
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, text);
}
});
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;
}
}

234
src/MenuDemo.java Normal file
View File

@@ -0,0 +1,234 @@
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/* MenuDemo.java requires images/middle.gif. */
/*
* This class is just like MenuLookDemo, except the menu items
* actually do something, thanks to event listeners.
*/
public class MenuDemo implements ActionListener, ItemListener {
JTextArea output;
JScrollPane scrollPane;
String newline = "\n";
public JMenuBar createMenuBar() {
JMenuBar menuBar;
JMenu menu, submenu;
JMenuItem menuItem;
JRadioButtonMenuItem rbMenuItem;
JCheckBoxMenuItem cbMenuItem;
//Create the menu bar.
menuBar = new JMenuBar();
//Build the first menu.
menu = new JMenu("A Menu");
menu.setMnemonic(KeyEvent.VK_A);
menu.getAccessibleContext().setAccessibleDescription(
"The only menu in this program that has menu items");
menuBar.add(menu);
//a group of JMenuItems
menuItem = new JMenuItem("A text-only menu item",
KeyEvent.VK_T);
//menuItem.setMnemonic(KeyEvent.VK_T); //used constructor instead
menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_1, ActionEvent.ALT_MASK));
menuItem.getAccessibleContext().setAccessibleDescription(
"This doesn't really do anything");
menuItem.addActionListener(this);
menu.add(menuItem);
ImageIcon icon = createImageIcon("images/middle.gif");
menuItem = new JMenuItem("Both text and icon", icon);
menuItem.setMnemonic(KeyEvent.VK_B);
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem(icon);
menuItem.setMnemonic(KeyEvent.VK_D);
menuItem.addActionListener(this);
menu.add(menuItem);
//a group of radio button menu items
menu.addSeparator();
ButtonGroup group = new ButtonGroup();
rbMenuItem = new JRadioButtonMenuItem("A radio button menu item");
rbMenuItem.setSelected(true);
rbMenuItem.setMnemonic(KeyEvent.VK_R);
group.add(rbMenuItem);
rbMenuItem.addActionListener(this);
menu.add(rbMenuItem);
rbMenuItem = new JRadioButtonMenuItem("Another one");
rbMenuItem.setMnemonic(KeyEvent.VK_O);
group.add(rbMenuItem);
rbMenuItem.addActionListener(this);
menu.add(rbMenuItem);
//a group of check box menu items
menu.addSeparator();
cbMenuItem = new JCheckBoxMenuItem("A check box menu item");
cbMenuItem.setMnemonic(KeyEvent.VK_C);
cbMenuItem.addItemListener(this);
menu.add(cbMenuItem);
cbMenuItem = new JCheckBoxMenuItem("Another one");
cbMenuItem.setMnemonic(KeyEvent.VK_H);
cbMenuItem.addItemListener(this);
menu.add(cbMenuItem);
//a submenu
menu.addSeparator();
submenu = new JMenu("A submenu");
submenu.setMnemonic(KeyEvent.VK_S);
menuItem = new JMenuItem("An item in the submenu");
menuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_2, ActionEvent.ALT_MASK));
menuItem.addActionListener(this);
submenu.add(menuItem);
menuItem = new JMenuItem("Another item");
menuItem.addActionListener(this);
submenu.add(menuItem);
menu.add(submenu);
//Build second menu in the menu bar.
JMenuItem anotherMenu = new JMenuItem("Another Menu");
anotherMenu.setMnemonic(KeyEvent.VK_N);
anotherMenu.getAccessibleContext().setAccessibleDescription("This menu does nothing");
anotherMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Click!");
// JOptionPane.showMessageDialog(null, "Hello There!");
}
});
menuBar.add(anotherMenu);
return menuBar;
}
public Container createContentPane() {
//Create the content-pane-to-be.
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setOpaque(true);
//Create a scrolled text area.
output = new JTextArea(5, 30);
output.setEditable(false);
scrollPane = new JScrollPane(output);
//Add the text area to the content pane.
contentPane.add(scrollPane, BorderLayout.CENTER);
return contentPane;
}
public void actionPerformed(ActionEvent e) {
JMenuItem source = (JMenuItem)(e.getSource());
String s = "Action event detected."
+ newline
+ " Event source: " + source.getText()
+ " (an instance of " + getClassName(source) + ")";
output.append(s + newline);
output.setCaretPosition(output.getDocument().getLength());
}
public void itemStateChanged(ItemEvent e) {
JMenuItem source = (JMenuItem)(e.getSource());
String s = "Item event detected."
+ newline
+ " Event source: " + source.getText()
+ " (an instance of " + getClassName(source) + ")"
+ newline
+ " New state: "
+ ((e.getStateChange() == ItemEvent.SELECTED) ?
"selected":"unselected");
output.append(s + newline);
output.setCaretPosition(output.getDocument().getLength());
}
// Returns just the class name -- no package info.
protected String getClassName(Object o) {
String classString = o.getClass().getName();
int dotIndex = classString.lastIndexOf(".");
return classString.substring(dotIndex+1);
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = MenuDemo.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("MenuDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
MenuDemo demo = new MenuDemo();
frame.setJMenuBar(demo.createMenuBar());
frame.setContentPane(demo.createContentPane());
//Display the window.
frame.setSize(450, 260);
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

167
src/RowNumberTable.java Normal file
View File

@@ -0,0 +1,167 @@
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/*
* This code is taken from - https://tips4java.wordpress.com/2008/11/18/row-number-table/
* Use a JTable as a renderer for row numbers of a given main table.
* This table must be added to the row header of the scrollpane that contains the main table.
*/
public class RowNumberTable extends JTable
implements ChangeListener, PropertyChangeListener, TableModelListener {
private JTable main;
public RowNumberTable(JTable table) {
main = table;
main.addPropertyChangeListener(this);
main.getModel().addTableModelListener(this);
setFocusable(false);
setAutoCreateColumnsFromModel(false);
setSelectionModel(main.getSelectionModel());
TableColumn column = new TableColumn();
column.setHeaderValue(" ");
addColumn(column);
column.setCellRenderer(new RowNumberRenderer());
getColumnModel().getColumn(0).setPreferredWidth(50);
setPreferredScrollableViewportSize(getPreferredSize());
}
@Override
public void addNotify() {
super.addNotify();
Component c = getParent();
// Keep scrolling of the row table in sync with the main table.
if (c instanceof JViewport) {
JViewport viewport = (JViewport) c;
viewport.addChangeListener(this);
}
}
/*
* Delegate method to main table
*/
@Override
public int getRowCount() {
return main.getRowCount();
}
@Override
public int getRowHeight(int row) {
int rowHeight = main.getRowHeight(row);
if (rowHeight != super.getRowHeight(row)) {
super.setRowHeight(row, rowHeight);
}
return rowHeight;
}
/*
* No model is being used for this table so just use the row number
* as the value of the cell.
*/
@Override
public Object getValueAt(int row, int column) {
return Integer.toString(row + 1);
}
/*
* Don't edit data in the main TableModel by mistake
*/
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
/*
* Do nothing since the table ignores the model
*/
@Override
public void setValueAt(Object value, int row, int column) {
}
//
// Implement the ChangeListener
//
public void stateChanged(ChangeEvent e) {
// Keep the scrolling of the row table in sync with main table
JViewport viewport = (JViewport) e.getSource();
JScrollPane scrollPane = (JScrollPane) viewport.getParent();
scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
}
//
// Implement the PropertyChangeListener
//
public void propertyChange(PropertyChangeEvent e) {
// Keep the row table in sync with the main table
if ("selectionModel".equals(e.getPropertyName())) {
setSelectionModel(main.getSelectionModel());
}
if ("rowHeight".equals(e.getPropertyName())) {
repaint();
}
if ("model".equals(e.getPropertyName())) {
main.getModel().addTableModelListener(this);
revalidate();
}
}
//
// Implement the TableModelListener
//
@Override
public void tableChanged(TableModelEvent e) {
revalidate();
}
/*
* Attempt to mimic the table header renderer
*/
private static class RowNumberRenderer extends DefaultTableCellRenderer {
public RowNumberRenderer() {
setHorizontalAlignment(JLabel.CENTER);
}
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (table != null) {
JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
}
if (isSelected) {
setFont(getFont().deriveFont(Font.BOLD));
}
setText((value == null) ? "" : value.toString());
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
}
}