Skip to content

Instantly share code, notes, and snippets.

@uvlad7
Last active March 30, 2019 04:02
Show Gist options
  • Save uvlad7/ad5831e2469c3e1a2146acd530c71870 to your computer and use it in GitHub Desktop.
Save uvlad7/ad5831e2469c3e1a2146acd530c71870 to your computer and use it in GitHub Desktop.
УП 5
public abstract class Cell {
private String renderedValue;
public Cell(String renderedValue) {
this.renderedValue = renderedValue;
}
public Cell() {
this.renderedValue = "";
}
public void setRenderedValue(String renderedValue) {
this.renderedValue = renderedValue;
}
abstract public Type getType();
abstract public Object getValue();
public String getEditableValue() {
return renderedValue;
}
@Override
public String toString() {
return renderedValue;
}
public enum Type {
INT,
DATE,
FINT,
FDATE
}
}
public class CycleRefException extends ExcelException {
public CycleRefException(String message) {
super(message);
}
}
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class DateCell extends Cell {
private Calendar value;
public DateCell(Calendar value) {
this.value = value;
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
setRenderedValue(format.format(value.getTime()));
}
public DateCell(Calendar value, String renderedValue) {
super(renderedValue);
this.value = value;
}
@Override
public Calendar getValue() {
return value;
}
@Override
public Type getType() {
return Type.DATE;
}
}
public class DateException extends ExcelException {
public DateException(String message) {
super(message);
}
}
public class ExcelException extends Exception {
public ExcelException(String message) {
super(message);
}
}
import java.util.List;
public class FuncCell extends Cell {
private String editableValue;
private Type type;
private Long value;
private List<Long> constArgs;
private List<Link> links;
private FuncType funcType;
private boolean containsDate;
public FuncCell(String editableValue, List<Long> constArgs, List<Link> links, FuncType funcType, boolean containsDate) {
this.editableValue = editableValue;
this.constArgs = constArgs;
this.links = links;
this.funcType = funcType;
this.containsDate = containsDate;
}
@Override
public String getEditableValue() {
return editableValue;
}
public void setType(Type type) {
this.type = type;
}
public void setValue(Long value) {
this.value = value;
}
public List<Long> getConstArgs() {
return constArgs;
}
public FuncType getFuncType() {
return funcType;
}
public List<Link> getLinks() {
return links;
}
public boolean getContainsDate() {
return containsDate;
}
@Override
public Long getValue() {
return value;
}
@Override
public Type getType() {
return type;
}
public enum FuncType {
SUM,
MIN,
MAX
}
}
public class FuncFormatException extends ExcelException {
public FuncFormatException(String message) {
super(message);
}
}
public class IntCell extends Cell {
private Long value;
public IntCell(Long value) {
super(((value == null) ? "" : value.toString()));
this.value = ((value == null) ? null : value * 86400000);
}
@Override
public Long getValue() {
return value;
}
@Override
public Type getType() {
return Type.INT;
}
}
public class Main {
public static void main(String[] args) {
new MyController();
}
}
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.table.TableCellEditor;
import java.awt.*;
public class MyCellEditor extends DefaultCellEditor implements TableCellEditor {
Cell value;
MyController controller;
MyTable view;
JTable table;
public MyCellEditor(JTextField textField, MyController controller, MyTable view, JTable table) {
super(textField);
this.controller = controller;
this.view = view;
this.table = table;
}
public boolean stopCellEditing() {
try {
value = controller.addCell(table.getEditingColumn(), table.getEditingRow(), (String) super.getCellEditorValue());
} catch (DateException e) {
((JComponent) getComponent()).setBorder(new LineBorder(Color.red));
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(view, e.getMessage(), "Некорректная дата", JOptionPane.ERROR_MESSAGE)
);
return false;
} catch (FuncFormatException e) {
((JComponent) getComponent()).setBorder(new LineBorder(Color.red));
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(view, e.getMessage(), "Некорректная запись функции", JOptionPane.ERROR_MESSAGE)
);
return false;
} catch (CycleRefException e) {
((JComponent) getComponent()).setBorder(new LineBorder(Color.red));
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(view, e.getMessage(), "Циклическая ссылка", JOptionPane.ERROR_MESSAGE)
);
return false;
} catch (ExcelException e) {
((JComponent) getComponent()).setBorder(new LineBorder(Color.red));
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(view, e.getMessage(), "Некорректный формат", JOptionPane.ERROR_MESSAGE)
);
return false;
}
return super.stopCellEditing();
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected,
int row, int column) {
this.value = null;
((JComponent) getComponent()).setBorder(new LineBorder(Color.black));
Cell cell = (Cell) value;
return super.getTableCellEditorComponent(table, cell.getEditableValue(), isSelected, row, column);
}
public Cell getCellEditorValue() {
return value;
}
/*@Override
public void cancelCellEditing() {
value = new IntCell(null);
super.cancelCellEditing();
}*/
}
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class MyController implements TableModelListener {
private MyModel model;
private MyTable view;
private List<List<Integer>> observers;
private List<List<Integer>> observed;
private int maxFilledCol;
private int maxFilledRow;
public MyController() {
model = new MyModel(this);
view = new MyTable(model, this);
model.addTableModelListener(this);
observed = new ArrayList<>(3328);
observers = new ArrayList<>(3328);
for (int i = 0; i < 3328; i++) {
observed.add(new ArrayList<>());
observers.add(new ArrayList<>());
}
}
public Cell addCell(int col, int row, String value) throws ExcelException {
Integer pos = row * 26 + col;
List<Integer> observedByCur = observed.get(row * 26 + col);
int size = observedByCur.size();
for (int i = 0; i < size; i++) {
observers.get(observedByCur.get(i)).remove(pos);
}
observedByCur.clear();
if (value.equals("")) {
return new IntCell(null);
}
if (value.charAt(0) == '=') {
List<String> tokens = MyParser.parseFunc(value.substring(1));
List<Long> constArgs = new ArrayList<>();
List<Link> links = new ArrayList<>();
Integer link;
boolean containsDate = false;
FuncCell.FuncType funcType;
if (tokens.get(0).equals("MAX")) {
funcType = FuncCell.FuncType.MAX;
} else if (tokens.get(0).equals("MIN")) {
funcType = FuncCell.FuncType.MIN;
} else funcType = FuncCell.FuncType.SUM;
size = tokens.size();
for (int i = 1; i < size; i++) {
if ((tokens.get(i).equals(";")) || (tokens.get(i).equals("+")) || (tokens.get(i).equals("-"))) {
continue;
} else if ((tokens.get(i).equals(":"))) {
int maxl = Integer.parseInt(tokens.get(i + 1).substring(1));
int maxj = tokens.get(i + 1).charAt(0) - 65;
for (int l = Integer.parseInt(tokens.get(i - 1).substring(1)); l <= maxl; l++) {
for (int j = tokens.get(i - 1).charAt(0) - 65; j <= maxj; j++) {
link = j + 26 * l - 26;
links.add(new Link(1, link));
observedByCur.add(link);
observers.get(link).add(pos);
if (link == row * 26 + col)
throw new CycleRefException("Функция содержит ссылку на текущую ячейку");
if (isCycle(row * 26 + col, row * 26 + col, link))
throw new CycleRefException("Функция содержит циклическую ссылку на текущую ячейку");
}
}
} else if (MyParser.intVerify(tokens.get(i))) {
try {
if (tokens.get(i - 1).equals("-"))
constArgs.add(-86400000L * Integer.parseInt(tokens.get(i)));
else
constArgs.add(86400000L * Integer.parseInt(tokens.get(i)));
} catch (NumberFormatException e) {
throw new ExcelException("Слишком длинное число");
}
} else if (MyParser.smellsLikeDate(tokens.get(i))) {
containsDate = true;
if (tokens.get(i - 1).equals("-"))
constArgs.add(-1 * parseDate(tokens.get(i)).getTime().getTime());
else
constArgs.add(parseDate(tokens.get(i)).getTime().getTime());
} else if ((tokens.get(i - 1).equals(":")) || ((i < size - 1) && (tokens.get(i + 1).equals(":")))) {
continue;
} else {
link = tokens.get(i).charAt(0) - 91 + Integer.parseInt(tokens.get(i).substring(1)) * 26;
if (tokens.get(i - 1).equals("-"))
links.add(new Link(-1, link));
else
links.add(new Link(1, link));
observedByCur.add(link);
observers.get(link).add(pos);
if (link == row * 26 + col)
throw new CycleRefException("Функция содержит ссылку на текущую ячейку");
if (isCycle(row * 26 + col, row * 26 + col, link))
throw new CycleRefException("Функция содержит циклическую ссылку на текущую ячейку");
}
}
maxFilledCol = Math.max(maxFilledCol, col);
maxFilledRow = Math.max(maxFilledRow, row);
return new FuncCell(value, constArgs, links, funcType, containsDate);
} else if (MyParser.intVerify(value)) {
try {
maxFilledCol = Math.max(maxFilledCol, col);
maxFilledRow = Math.max(maxFilledRow, row);
return new IntCell((long) Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new ExcelException("Слишком длинное число");
}
}
if (MyParser.smellsLikeDate(value)) {
if (MyParser.dateVerify(value)) {
maxFilledCol = Math.max(maxFilledCol, col);
maxFilledRow = Math.max(maxFilledRow, row);
return new DateCell(parseDate(value), value);
} else throw new DateException("Дата не существует");
}
throw new ExcelException("Формат не распознан");
}
private Calendar parseDate(String value) {
SimpleDateFormat format1 = new SimpleDateFormat("dd.MM.yyyy");
SimpleDateFormat format3 = new SimpleDateFormat("M/d/yyyy");
Calendar calendar = Calendar.getInstance();
try {
calendar.setTime(format1.parse(value));
} catch (ParseException e) {
}
try {
calendar.setTime(format3.parse(value));
} catch (ParseException e) {
}
return calendar;
}
private boolean isCycle(int checked, int cur, int link) {
if (link == checked)
return true;
boolean cycle = false;
for (int i = 0; i < observed.get(cur).size(); i++) {
if (isCycle(checked, link, observed.get(cur).get(i))) {
cycle = true;
break;
}
}
return cycle;
}
private void updateCell(int col, int row) {
int size;
if (model.getValueAt(row, col) instanceof FuncCell) {
FuncCell cell = (FuncCell) model.getValueAt(row, col);
Cell linkedCell;
List<Long> constArgs = cell.getConstArgs();
List<Link> links = cell.getLinks();
Long value = 0L;
boolean isDate = cell.getContainsDate();
if (FuncCell.FuncType.MAX.equals(cell.getFuncType())) {
size = constArgs.size();
if (size != 0)
value = constArgs.get(0);
for (int i = 1; i < size; i++) {
value = Math.max(value, constArgs.get(i));
}
size = links.size();
if (size != 0) {
linkedCell = (Cell) model.getValueAt(links.get(0).link / 26, links.get(0).link % 26);
if (Cell.Type.DATE.equals(linkedCell.getType())) {
isDate = true;
value = Math.max(value, ((Calendar) linkedCell.getValue()).getTime().getTime());
} else {
if (linkedCell.getValue() != null)
value = Math.max(value, (Long) linkedCell.getValue());
if (Cell.Type.FDATE.equals(linkedCell.getType()))
isDate = true;
}
}
for (int i = 1; i < size; i++) {
linkedCell = (Cell) model.getValueAt(links.get(i).link / 26, links.get(i).link % 26);
if (Cell.Type.DATE.equals(linkedCell.getType())) {
isDate = true;
value = Math.max(value, ((Calendar) linkedCell.getValue()).getTime().getTime());
} else {
if (linkedCell.getValue() != null)
value = Math.max(value, (Long) linkedCell.getValue());
if (Cell.Type.FDATE.equals(linkedCell.getType()))
isDate = true;
}
}
} else if (FuncCell.FuncType.MIN.equals(cell.getFuncType())) {
size = constArgs.size();
if (size != 0)
value = constArgs.get(0);
for (int i = 1; i < size; i++) {
value = Math.min(value, constArgs.get(i));
}
size = links.size();
if (size != 0) {
linkedCell = (Cell) model.getValueAt(links.get(0).link / 26, links.get(0).link % 26);
if (Cell.Type.DATE.equals(linkedCell.getType())) {
isDate = true;
value = Math.min(value, ((Calendar) linkedCell.getValue()).getTime().getTime());
} else {
if (linkedCell.getValue() != null)
value = Math.min(value, (Long) linkedCell.getValue());
if (Cell.Type.FDATE.equals(linkedCell.getType()))
isDate = true;
}
}
for (int i = 1; i < size; i++) {
linkedCell = (Cell) model.getValueAt(links.get(i).link / 26, links.get(i).link % 26);
if (Cell.Type.DATE.equals(linkedCell.getType())) {
isDate = true;
value = Math.min(value, ((Calendar) linkedCell.getValue()).getTime().getTime());
} else {
if (linkedCell.getValue() != null)
value = Math.min(value, (Long) linkedCell.getValue());
if (Cell.Type.FDATE.equals(linkedCell.getType()))
isDate = true;
}
}
} else {
size = constArgs.size();
for (int i = 0; i < size; i++) {
value += constArgs.get(i);
}
size = links.size();
for (int i = 0; i < size; i++) {
linkedCell = (Cell) model.getValueAt(links.get(i).link / 26, links.get(i).link % 26);
if (Cell.Type.DATE.equals(linkedCell.getType())) {
isDate = true;
value += links.get(i).abs * ((Calendar) linkedCell.getValue()).getTime().getTime();
} else {
if (linkedCell.getValue() != null)
value += links.get(i).abs * (Long) linkedCell.getValue();
if (Cell.Type.FDATE.equals(linkedCell.getType()))
isDate = true;
}
}
}
cell.setValue(value);
if (!isDate) {
value /= 86400000;
cell.setRenderedValue((value).toString());
cell.setType(Cell.Type.FINT);
} else {
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
cell.setRenderedValue(format.format(new Date(value)));
cell.setType(Cell.Type.FDATE);
}
}
List<Integer> observersOfCur = observers.get(row * 26 + col);
size = observersOfCur.size();
for (int i = 0; i < size; i++) {
updateCell(observersOfCur.get(i) % 26, observersOfCur.get(i) / 26);
}
}
@Override
public void tableChanged(TableModelEvent e) {
if ((e.getColumn() != -1) && (e.getLastRow() != -1))
updateCell(e.getColumn(), e.getLastRow());
view.updateUI();
}
public void save(String path) {
try (PrintStream printStream = new PrintStream(path)) {
StringBuilder stringBuilder = new StringBuilder();
Cell cell;
for (int i = 0; i <= maxFilledRow; i++) {
for (int j = 0; j <= maxFilledCol; j++) {
cell = (Cell) model.getValueAt(i, j);
stringBuilder.append(cell.getEditableValue()).append(',');
}
while (stringBuilder.charAt(stringBuilder.length() - 1) == ',')
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
stringBuilder.append("\r\n");
}
printStream.print(stringBuilder);
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(view, "Ошибка: путь не существует", "Сохранить",
JOptionPane.ERROR_MESSAGE, new ImageIcon("src\\save.png"));
}
}
public void open(String path) {
try (Scanner scanner = new Scanner(new File(path))) {
model.clear();
for (int i = 0; i < 3328; i++) {
observed.get(i).clear();
observers.get(i).clear();
}
maxFilledCol = 0;
maxFilledRow = 0;
imp(scanner);
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(view, "Ошибка: файл не найден", "Открыть",
JOptionPane.ERROR_MESSAGE, new ImageIcon("src\\open.png"));
}
}
public void insert(String path) {
try (Scanner scanner = new Scanner(new File(path))) {
imp(scanner);
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(view, "Ошибка: файл не найден", "Импортировать",
JOptionPane.ERROR_MESSAGE, new ImageIcon("src\\import.png"));
}
}
private void imp(Scanner scanner) {
StringTokenizer tokenizer;
int i, j;
String token;
i = 0;
while (scanner.hasNextLine()) {
tokenizer = new StringTokenizer(scanner.nextLine(), "[,]", true);
j = 0;
while (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
if (!token.equals(",")) {
try {
model.setValueAt(addCell(j, i, token), i, j);
} catch (DateException e) {
String label = (char) (65 + j) + Integer.toString(i);
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(view, e.getMessage(), "Некорректная дата: " + label, JOptionPane.ERROR_MESSAGE)
);
} catch (FuncFormatException e) {
String label = (char) (65 + j) + Integer.toString(i);
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(view, e.getMessage(), "Некорректная запись функции: " + label, JOptionPane.ERROR_MESSAGE)
);
} catch (CycleRefException e) {
String label = (char) (65 + j) + Integer.toString(i);
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(view, e.getMessage(), "Циклическая ссылка: " + label, JOptionPane.ERROR_MESSAGE)
);
} catch (ExcelException e) {
String label = (char) (65 + j) + Integer.toString(i);
SwingUtilities.invokeLater(() ->
JOptionPane.showMessageDialog(view, e.getMessage(), "Некорректный формат: " + label, JOptionPane.ERROR_MESSAGE)
);
}
} else j++;
}
i++;
}
}
}
class Link {
int abs;
int link;
public Link(int abs, int link) {
this.abs = abs;
this.link = link;
}
}
import javax.swing.table.DefaultTableModel;
public class MyModel extends DefaultTableModel {
private MyController controller;
public MyModel(MyController controller) {
this.controller = controller;
clear();
}
@Override
public Class getColumnClass(int column) {
return String.class;
}
public void clear() {
Cell[][] data = new IntCell[128][26];
Cell[] row = new IntCell[26];
String[] names = new String[26];
for (int i = 0; i < 26; i++) {
names[i] = Character.toString(((char) (65 + i)));
row[i] = new IntCell(null);
}
for (int j = 0; j < 128; j++) {
data[j] = row;
}
setDataVector(data, names);
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MyParser {
private static Pattern intPattern = Pattern.compile("^(?:(?:-?[1-9]\\d*)|0)$");
private static Pattern likeDatePattern = Pattern.compile("^(?:(?:\\d{2}\\.\\d{2}\\.\\d{4})|(?:\\d{1,2}/\\d{1,2}/\\d{4}))$");
private static Pattern datePattern = Pattern.compile("^(?:(?:(?:(?:(?:(?:0[1-9])|(?:1\\d)|(?:2[0-8]))\\.(?:(?:0[1-9])|(?:1[0-2])))|(?:(?:(?:29)|(?:30))\\.(?:(?:0[13-9])|(?:1[0-2])))|(?:31\\.(?:(?:0[13578])|(?:1[02]))))" +
"\\.(?:(?!0000)\\d{4}))" +
"|(?:(?:(?:(?:(?:[1-9])|(?:1[0-2]))/(?:(?:[1-9])|(?:1\\d)|(?:2[0-8])))|(?:(?:(?:[13-9])|(?:1[0-2]))/(?:(?:29)|(?:30)))|(?:(?:(?:[13578])|(?:1[02]))/31))" +
"/(?:(?!0000)\\d{4}))" +
"|(?:(?:(?:29\\.02\\.)|(?:2/29/))(?:(?:(?:(?:[13579][26])|(?:[2468][048])|(?:0[48]))00)|" +
"(?:\\d{2}(?:(?:[13579][26])|(?:[2468][048])|(?:0[48]))))))$");
private static Pattern likeLinkPattern = Pattern.compile("^(?:[A-Z]\\d{1,3})$");
private static Pattern linkPattern = Pattern.compile("^(?:[A-Z](?:(?:[1-9])|(?:[1-9]\\d)|(?:1[01]\\d)|(?:12[0-8])))$");
private static Pattern sumPattern = Pattern.compile("^(?:(?:[A-Z]\\d{1,3})|(?:(?:\\d{2}\\.\\d{2}\\.\\d{4})|(?:\\d{1,2}/\\d{1,2}/\\d{4}))|(?:(?:-?[1-9]\\d*)|0))(?:[-+](?:(?:[A-Z]\\d{1,3})|(?:(?:\\d{2}\\.\\d{2}\\.\\d{4})|(?:\\d{1,2}/\\d{1,2}/\\d{4}))|(?:(?:-?[1-9]\\d*)|0)))*$");
private static Pattern parseSumPattern = Pattern.compile("(?:[^-+]+)|(?:[-+])");
private static Pattern minMaxPattern = Pattern.compile("^(?:MIN|MAX)\\((?:(?:(?:[A-Z]\\d{1,3}):(?:[A-Z]\\d{1,3}))|(?:(?:(?:[A-Z]\\d{1,3})|(?:(?:\\d{2}\\.\\d{2}\\.\\d{4})|(?:\\d{1,2}/\\d{1,2}/\\d{4}))|(?:(?:-?[1-9]\\d*)|0));(?:(?:[A-Z]\\d{1,3})|(?:(?:\\d{2}\\.\\d{2}\\.\\d{4})|(?:\\d{1,2}/\\d{1,2}/\\d{4}))|(?:(?:-?[1-9]\\d*)|0))))" +
"(?:;(?:(?:(?:[A-Z]\\d{1,3}):(?:[A-Z]\\d{1,3}))|(?:(?:[A-Z]\\d{1,3})|(?:(?:\\d{2}\\.\\d{2}\\.\\d{4})|(?:\\d{1,2}/\\d{1,2}/\\d{4}))|(?:(?:-?[1-9]\\d*)|0))))*\\)$");
private static Pattern parseMinMaxPattern = Pattern.compile("(?:[^;:]+)|(?:[;:])");
public static boolean intVerify(String text) {
return intPattern.matcher(text).matches();
}
public static boolean smellsLikeDate(String text) {
return likeDatePattern.matcher(text).matches();
}
public static boolean smellsLikeLink(String text) {
return likeLinkPattern.matcher(text).matches();
}
public static boolean dateVerify(String text) {
return datePattern.matcher(text).matches();
}
public static boolean linkVerify(String text) {
return linkPattern.matcher(text).matches();
}
private static boolean sumVerify(String text) {
return sumPattern.matcher(text).matches();
}
private static boolean minMaxVerify(String text) {
return minMaxPattern.matcher(text).matches();
}
private static List<String> parseSum(String text) {
List<String> list = new ArrayList<>();
list.add("SUM");
Matcher matcher = parseSumPattern.matcher(text);
while (matcher.find()) {
list.add(matcher.group());
}
return list;
}
private static List<String> parseMinMax(String text) {
List<String> list = new ArrayList<>();
if (text.charAt(2) == 'X')
list.add("MAX");
else list.add("MIN");
Matcher matcher = parseMinMaxPattern.matcher(text.substring(4, text.length() - 1));
while (matcher.find()) {
list.add(matcher.group());
}
return list;
}
public static List<String> parseFunc(String text) throws FuncFormatException {
List<String> tokens;
if (sumVerify(text)) {
tokens = parseSum(text);
} else if (minMaxVerify(text)) {
tokens = parseMinMax(text);
} else
throw new FuncFormatException("Запись не является формулой");
int size = tokens.size();
for (int i = 0; i < size; i++) {
if ((smellsLikeLink(tokens.get(i))) && (!linkVerify(tokens.get(i))))
throw new FuncFormatException("Ячейка " + tokens.get(i) + " не существует");
else if ((smellsLikeDate(tokens.get(i))) && (!dateVerify(tokens.get(i))))
throw new FuncFormatException("Дата " + tokens.get(i) + " не существует");
}
return tokens;
}
}
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
public class MyRenderer extends DefaultTableCellRenderer {
private Font font;
private JLabel label;
public MyRenderer() {
font = new Font("Verdana", Font.PLAIN, 16);
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
label.setHorizontalAlignment(SwingConstants.LEFT);
label.setFont(font);
if (value != null)
label.setText(value.toString());
//label.setText(parser.parse(value.toString(), table));
return label;
}
}
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class MyTable extends JFrame implements ActionListener {
private MyModel model;
private MyController controller;
private JTable table;
private JMenuBar menuBar;
private JMenu file;
private JMenuItem open;
private JMenuItem imp;
private JMenuItem save;
private JMenuItem saveAs;
private String filename;
public MyTable(MyModel model, MyController controller) {
super("Excel Date Lite");
this.model = model;
this.controller = controller;
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
}
setIconImage(new ImageIcon("src\\excel.png").getImage());
setSize(900, 600);
ListModel<String> listModel = new AbstractListModel<>() {
String[] headers;
{
headers = new String[128];
for (int i = 0; i < 128; i++) {
headers[i] = Integer.toString(i + 1);
}
}
public int getSize() {
return headers.length;
}
public String getElementAt(int index) {
return headers[index];
}
};
table = new JTable(model);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getTableHeader().setReorderingAllowed(false);
table.getTableHeader().setDefaultRenderer(new HeaderRenderer(table));
table.setDefaultRenderer(String.class, new MyRenderer());
JTextField textField = new JTextField();
textField.setFont(new Font("Verdana", Font.PLAIN, 16));
textField.setHorizontalAlignment(SwingConstants.LEFT);
MyCellEditor cellEditor = new MyCellEditor(textField, controller, this, table);
table.setDefaultEditor(String.class, cellEditor);
table.setRowHeight(26);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setColumnSelectionAllowed(true);
table.setRowSelectionAllowed(true);
JList<String> rowHeader = new JList<>(listModel);
rowHeader.setFixedCellWidth(50);
rowHeader.setFixedCellHeight(table.getRowHeight());
rowHeader.setCellRenderer(new RowHeaderRenderer(table));
JScrollPane scroll = new JScrollPane(table);
scroll.setRowHeaderView(rowHeader);
getContentPane().add(scroll, BorderLayout.CENTER);
menuBar = new JMenuBar();
file = new JMenu("Файл");
open = new JMenuItem("Открыть", new ImageIcon("src\\open.png"));
file.add(open);
imp = new JMenuItem("Импортировать", new ImageIcon("src\\import.png"));
file.add(imp);
save = new JMenuItem("Сохранить", new ImageIcon("src\\save.png"));
file.add(save);
saveAs = new JMenuItem("Сохранить как", new ImageIcon("src\\saveAs.png"));
file.add(saveAs);
open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK));
imp.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_DOWN_MASK));
save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK));
saveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK));
menuBar.add(file);
setJMenuBar(menuBar);
open.addActionListener(this);
imp.addActionListener(this);
save.addActionListener(this);
saveAs.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setSize(900, 600);
setLocationRelativeTo(null);
setVisible(true);
}
public void updateUI() {
SwingUtilities.invokeLater(() ->
table.updateUI()
);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == open) {
if (open())
controller.open(filename);
} else if (e.getSource() == imp) {
if (open())
controller.insert(filename);
} else if (e.getSource() == save) {
if (filename != null) {
controller.save(filename);
} else {
saveAs();
}
} else if (e.getSource() == saveAs) {
saveAs();
}
}
private void saveAs() {
JFileChooser fileChooser = new JFileChooser(".");
fileChooser.setAcceptAllFileFilterUsed(false);
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("csv table file", "csv"));
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
filename = fileChooser.getDescription(fileChooser.getSelectedFile());
controller.save(filename);
}
}
private boolean open() {
JFileChooser fileChooser = new JFileChooser(".");
fileChooser.setAcceptAllFileFilterUsed(false);
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("csv table file", "csv"));
if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
filename = fileChooser.getDescription(fileChooser.getSelectedFile());
return true;
}
return false;
}
}
class RowHeaderRenderer extends DefaultListCellRenderer {
private JLabel label;
private JTableHeader header;
RowHeaderRenderer(JTable table) {
header = table.getTableHeader();
}
@Override
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected, boolean cellHasFocus) {
label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
label.setText((value == null) ? "" : value.toString());
label.setOpaque(true);
label.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
label.setHorizontalAlignment(CENTER);
label.setForeground(header.getForeground());
label.setBackground(header.getBackground());
label.setFont(header.getFont());
return label;
}
}
class HeaderRenderer extends DefaultTableCellRenderer {
private JLabel label;
private JTableHeader header;
HeaderRenderer(JTable table) {
header = table.getTableHeader();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
label.setText((value == null) ? "" : value.toString());
label.setOpaque(true);
label.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
label.setHorizontalAlignment(CENTER);
label.setForeground(header.getForeground());
label.setBackground(header.getBackground());
label.setFont(header.getFont());
return label;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment