Witam. Mam napisany wstępny projekt arkusza kalkulacyjnego. Arkusz jak dla mojego doktorka od laborek z inżynierii oprogramowania powiedział ze jest łatwy. Arkusz ma zazdanie dodawać, odejmować, mnożyc i dzielić. Chcialbym prosic czy mozna w jakiś sposób go udoskonalić? Jeśli tak to prosił bym o jakis poprawki w kodzie.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
@SuppressWarnings("serial")
public class SpreadSheet extends JFrame {
// ********************************************************
class RowHeaderRenderer extends JLabel implements TableCellRenderer {
RowHeaderRenderer(JTable table) {
JTableHeader header = table.getTableHeader();
setOpaque(true);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
setHorizontalAlignment(CENTER);
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
this.setText((row + 1) + "");
return this;
}
}
// *********************************************************
class SimpleTableModel extends DefaultTableModel{
final Map<String,Object> vals = new HashMap<String,Object>();
public SimpleTableModel(int rowCount, int columnCount) {
super(rowCount, columnCount);
}
@Override
public Object getValueAt(int row, int column) {
Object obj = super.getValueAt(row, column);
if(obj==null) return "";
String v = obj.toString();
if(v.startsWith("="))
return eval(v);
else
return v;
}
public Object getFormula(int row, int column){
return super.getValueAt(row, column);
}
@Override
public void setValueAt(Object value, int row, int column) {
super.setValueAt(value, row, column);
String k =Character.toString((char) (column+65))+""+(row+1);
try{
double d = Double.parseDouble(value+"");
vals.put(k,d);
}catch(Exception e){
vals.put(k, ""+value);
}
table.repaint();
}
public Map<String,Object> getVals(){
return vals;
}
}
// *********************************************************
final int ROW_COUNT = 50;
final int COLUMN_COUNT=25;
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
JTable table;
JTable rowHead;
SimpleTableModel model;
JTextField evalField;
public SpreadSheet() {
super("Arkusz Kalkulacyjny");
makeGUI();
linkEvents();
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setVisible(true);
}
private void makeGUI() {
table = new JTable();
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
model = new SimpleTableModel(ROW_COUNT, COLUMN_COUNT);
table.setModel(model);
rowHead = new JTable();
rowHead.setModel(new DefaultTableModel(ROW_COUNT, 1));
LookAndFeel.installColorsAndFont(rowHead, "TableHeader.background",
"TableHeader.foreground", "TableHeader.font");
rowHead.setIntercellSpacing(new Dimension(0, 0));
Dimension d = rowHead.getPreferredScrollableViewportSize();
d.width = rowHead.getPreferredSize().width;
rowHead.setPreferredScrollableViewportSize(d);
rowHead.setRowHeight(table.getRowHeight());
rowHead.setDefaultRenderer(Object.class, new RowHeaderRenderer(table));
JScrollPane sp = new JScrollPane(table);
sp.setRowHeaderView(rowHead);
add(sp, BorderLayout.CENTER);
JPanel editPanel = new JPanel();
editPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
editPanel.add(new JLabel("Fromula:"));
evalField = new JTextField();
evalField.setColumns(50);
editPanel.add(evalField);
add(editPanel,BorderLayout.NORTH);
pack();
this.setLocationRelativeTo(null);
}
private void linkEvents(){
ListSelectionListener listener = new ListSelectionListener(){
@Override
public void valueChanged(ListSelectionEvent e) {
int col=table.getSelectedColumn();
int row = table.getSelectedRow();
if(col<0 || row<0) return;
evalField.setText(model.getFormula(row, col)+"");
}
};
table.getColumnModel().getSelectionModel()
.addListSelectionListener(listener);
table.getSelectionModel().addListSelectionListener(listener);
evalField.addKeyListener(new KeyAdapter(){
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key==KeyEvent.VK_ENTER){
int col=table.getSelectedColumn();
int row = table.getSelectedRow();
if(col<0 || row<0) return;
model.setValueAt(evalField.getText(), row, col);
}
}
});
}
private Object eval(final String formula){
String f = formula.substring(1).toUpperCase();
Map<String, Object> vals = model.getVals();
Set<Entry<String, Object>> es = vals.entrySet();
for(Entry<String,Object> e:es){
engine.put(e.getKey(), e.getValue());
}
try {
return engine.eval(f);
} catch (ScriptException e1) {
return "";
}
}
public static void main(String[] args) {
new SpreadSheet();
}
}